закуп много каналов
This commit is contained in:
@@ -206,6 +206,30 @@ func (c *Client) GetWorkspaces(
|
|||||||
return resp.Items, err
|
return resp.Items, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Client) CreateWorkspace(
|
||||||
|
ctx context.Context,
|
||||||
|
jwt string,
|
||||||
|
name string,
|
||||||
|
) (*Workspace, error) {
|
||||||
|
req := struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
}{
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
|
||||||
|
var workspace Workspace
|
||||||
|
err := c.do(
|
||||||
|
ctx,
|
||||||
|
http.MethodPost,
|
||||||
|
"api/v1/workspaces",
|
||||||
|
req,
|
||||||
|
&workspace,
|
||||||
|
withBearer(jwt),
|
||||||
|
)
|
||||||
|
|
||||||
|
return &workspace, err
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Client) GetProjects(
|
func (c *Client) GetProjects(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
jwt string,
|
jwt string,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package bot
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"example.com/m/adapter/backend"
|
"example.com/m/adapter/backend"
|
||||||
"github.com/NicoNex/echotron/v3"
|
"github.com/NicoNex/echotron/v3"
|
||||||
@@ -143,6 +144,11 @@ func (b *Bot) SendNew(text string, keyboard echotron.InlineKeyboardMarkup) {
|
|||||||
|
|
||||||
func (b *Bot) Edit(text string, keyboard echotron.InlineKeyboardMarkup) {
|
func (b *Bot) Edit(text string, keyboard echotron.InlineKeyboardMarkup) {
|
||||||
if b.LastMessageID != 0 {
|
if b.LastMessageID != 0 {
|
||||||
|
log.Info().
|
||||||
|
Int("last_msg_id", b.LastMessageID).
|
||||||
|
Int("keyboard_rows", len(keyboard.InlineKeyboard)).
|
||||||
|
Int("text_len", len(text)).
|
||||||
|
Msg("EditMessageText request")
|
||||||
_, err := b.EditMessageText(
|
_, err := b.EditMessageText(
|
||||||
text,
|
text,
|
||||||
echotron.NewMessageID(b.ChatID, b.LastMessageID),
|
echotron.NewMessageID(b.ChatID, b.LastMessageID),
|
||||||
@@ -152,6 +158,13 @@ func (b *Bot) Edit(text string, keyboard echotron.InlineKeyboardMarkup) {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if strings.Contains(err.Error(), "message is not modified") {
|
||||||
|
log.Info().Msg("EditMessageText ignored: message is not modified")
|
||||||
|
if b.exec != nil {
|
||||||
|
b.exec.handled = true
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
log.Error().Err(err).Msg("EditMessageText")
|
log.Error().Err(err).Msg("EditMessageText")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -195,6 +208,9 @@ func (b *Bot) Update(u *echotron.Update) {
|
|||||||
log.Info().
|
log.Info().
|
||||||
Int64("chat_id", b.ChatID).
|
Int64("chat_id", b.ChatID).
|
||||||
Str("current_state", fmt.Sprintf("%T", b.CurrentState)).
|
Str("current_state", fmt.Sprintf("%T", b.CurrentState)).
|
||||||
|
Bool("has_callback", u.CallbackQuery != nil).
|
||||||
|
Bool("has_message", u.Message != nil).
|
||||||
|
Bool("has_edited_message", u.EditedMessage != nil).
|
||||||
Msg("Update received")
|
Msg("Update received")
|
||||||
|
|
||||||
// Обрабатываем системные события (добавление в канал, подписки и т.д.)
|
// Обрабатываем системные события (добавление в канал, подписки и т.д.)
|
||||||
@@ -255,7 +271,21 @@ func (b *Bot) Update(u *echotron.Update) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if u.CallbackQuery != nil {
|
if u.CallbackQuery != nil {
|
||||||
|
log.Info().
|
||||||
|
Str("callback_data", u.CallbackQuery.Data).
|
||||||
|
Int("callback_msg_id", func() int {
|
||||||
|
if u.CallbackQuery.Message != nil {
|
||||||
|
return u.CallbackQuery.Message.ID
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}()).
|
||||||
|
Int("last_msg_id", b.LastMessageID).
|
||||||
|
Msg("Callback received")
|
||||||
b.cleanupCallbackUI(u)
|
b.cleanupCallbackUI(u)
|
||||||
|
if u.CallbackQuery.Data == "empty" || u.CallbackQuery.Data == "page_info" || u.CallbackQuery.Data == "noop" {
|
||||||
|
exec.handled = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if b.GlobalCallbackRouter != nil && u.CallbackQuery.Data != "" {
|
if b.GlobalCallbackRouter != nil && u.CallbackQuery.Data != "" {
|
||||||
if newState := b.GlobalCallbackRouter(u.CallbackQuery.Data); newState != nil {
|
if newState := b.GlobalCallbackRouter(u.CallbackQuery.Data); newState != nil {
|
||||||
@@ -272,11 +302,23 @@ func (b *Bot) Update(u *echotron.Update) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !exec.handled && !exec.transitioned {
|
if !exec.handled && !exec.transitioned {
|
||||||
|
log.Info().
|
||||||
|
Bool("has_callback", u.CallbackQuery != nil).
|
||||||
|
Bool("has_message", u.Message != nil).
|
||||||
|
Bool("handled", exec.handled).
|
||||||
|
Bool("transitioned", exec.transitioned).
|
||||||
|
Msg("No handler handled update, calling common handler")
|
||||||
log.Info().Msg("Common handler")
|
log.Info().Msg("Common handler")
|
||||||
b.CurrentState.Handle(b, u)
|
b.CurrentState.Handle(b, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !exec.handled && !exec.transitioned {
|
if !exec.handled && !exec.transitioned {
|
||||||
|
log.Info().
|
||||||
|
Bool("has_callback", u.CallbackQuery != nil).
|
||||||
|
Bool("has_message", u.Message != nil).
|
||||||
|
Bool("handled", exec.handled).
|
||||||
|
Bool("transitioned", exec.transitioned).
|
||||||
|
Msg("Default feedback triggered")
|
||||||
log.Info().Msg("Default feedback")
|
log.Info().Msg("Default feedback")
|
||||||
b.SetState(b.DefaultStateFactory(), NewMessage)
|
b.SetState(b.DefaultStateFactory(), NewMessage)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ https://t.me/+AbCdEfGhIjKlMn</i>`, [][]echotron.InlineKeyboardButton{
|
|||||||
// Начинаем процесс добавления медиа
|
// Начинаем процесс добавления медиа
|
||||||
s.WaitingForMedia = true
|
s.WaitingForMedia = true
|
||||||
|
|
||||||
s.ShowControlPanel(b, `<b>⧉ Добавить медиа</b>
|
s.ShowControlPanel(b, `<b>+ Добавить медиа</b>
|
||||||
|
|
||||||
Отправьте <b>фото, видео или GIF</b>
|
Отправьте <b>фото, видео или GIF</b>
|
||||||
|
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ https://t.me/+AbCdEfGhIjKlMn</i>`, [][]echotron.InlineKeyboardButton{
|
|||||||
|
|
||||||
case data == "add_media":
|
case data == "add_media":
|
||||||
s.WaitingForMedia = true
|
s.WaitingForMedia = true
|
||||||
s.ShowControlPanel(b, `<b>⧉ Добавить медиа</b>
|
s.ShowControlPanel(b, `<b>+ Добавить медиа</b>
|
||||||
|
|
||||||
Отправьте <b>фото, видео или GIF</b>
|
Отправьте <b>фото, видео или GIF</b>
|
||||||
|
|
||||||
|
|||||||
@@ -283,7 +283,7 @@ func (e *CreativeEditorFields) ShowManagementPanel(b *bot.Bot, confirmButtonText
|
|||||||
// Блок редактирования контента
|
// Блок редактирования контента
|
||||||
buttons = append(buttons, bot.Row(
|
buttons = append(buttons, bot.Row(
|
||||||
bot.Button("✎ Текст", "edit_text"),
|
bot.Button("✎ Текст", "edit_text"),
|
||||||
bot.Button("⧉ Медиа", "add_media"),
|
bot.Button("+ Медиа", "add_media"),
|
||||||
))
|
))
|
||||||
// Добавление кнопки сразу под основным блоком
|
// Добавление кнопки сразу под основным блоком
|
||||||
buttons = append(buttons, bot.Row(bot.Button("+ Добавить кнопку", "add_button")))
|
buttons = append(buttons, bot.Row(bot.Button("+ Добавить кнопку", "add_button")))
|
||||||
|
|||||||
@@ -38,13 +38,35 @@ func (s *MyProjects) Enter(b *bot.Bot, mode bot.RenderMode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(workspaces) == 0 {
|
if len(workspaces) == 0 {
|
||||||
b.SendNew("У вас пока нет workspace'ов", bot.Keyboard())
|
// Автоматически создаем workspace с именем пользователя
|
||||||
|
username := "My Workspace"
|
||||||
|
chatInfo, err := b.GetChat(b.ChatID)
|
||||||
|
if err == nil && chatInfo.Result != nil {
|
||||||
|
if chatInfo.Result.Username != "" {
|
||||||
|
username = chatInfo.Result.Username
|
||||||
|
} else if chatInfo.Result.FirstName != "" {
|
||||||
|
username = chatInfo.Result.FirstName
|
||||||
|
if chatInfo.Result.LastName != "" {
|
||||||
|
username += " " + chatInfo.Result.LastName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info().Str("username", username).Msg("Creating default workspace")
|
||||||
|
workspace, err := b.Backend.CreateWorkspace(context.Background(), jwt, username)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("Failed to create workspace")
|
||||||
|
b.SendNew("❌ Не удалось создать workspace", bot.Keyboard())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.WorkspaceID = workspace.ID
|
||||||
|
log.Info().Str("workspace_id", s.WorkspaceID).Str("name", workspace.Name).Msg("Workspace created successfully")
|
||||||
|
} else {
|
||||||
// Используем первый workspace по умолчанию
|
// Используем первый workspace по умолчанию
|
||||||
s.WorkspaceID = workspaces[0].ID
|
s.WorkspaceID = workspaces[0].ID
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
s.renderProjects(b, mode, jwt)
|
s.renderProjects(b, mode, jwt)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -570,9 +570,9 @@ func (s *PurchaseOptionalDetails) renderParamChannels(b *bot.Bot, mode bot.Rende
|
|||||||
label := fmt.Sprintf("%d", i+1)
|
label := fmt.Sprintf("%d", i+1)
|
||||||
rows = append(rows, bot.Row(
|
rows = append(rows, bot.Row(
|
||||||
bot.Button(label, fmt.Sprintf("param_edit:%s:%d", param, i)),
|
bot.Button(label, fmt.Sprintf("param_edit:%s:%d", param, i)),
|
||||||
bot.Button("⎘", fmt.Sprintf("param_copy:%s:%d", param, i)),
|
bot.Button("⧉", fmt.Sprintf("param_copy:%s:%d", param, i)),
|
||||||
bot.Button("⤵", fmt.Sprintf("param_paste:%s:%d", param, i)),
|
bot.Button("⇲", fmt.Sprintf("param_paste:%s:%d", param, i)),
|
||||||
bot.Button("✎", fmt.Sprintf("param_edit:%s:%d", param, i)),
|
bot.Button("Изменить", fmt.Sprintf("param_edit:%s:%d", param, i)),
|
||||||
bot.Button("⌫", fmt.Sprintf("param_clear:%s:%d", param, i)),
|
bot.Button("⌫", fmt.Sprintf("param_clear:%s:%d", param, i)),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -630,7 +630,8 @@ func (s *PurchaseOptionalDetails) handleParamCallback(b *bot.Bot, data string) b
|
|||||||
case strings.HasPrefix(data, "param_edit:"):
|
case strings.HasPrefix(data, "param_edit:"):
|
||||||
param, index, ok := s.parseParamIndex(data, "param_edit:")
|
param, index, ok := s.parseParamIndex(data, "param_edit:")
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
s.Enter(b, bot.EditMessage)
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
if index >= 0 && index < len(s.Channels) {
|
if index >= 0 && index < len(s.Channels) {
|
||||||
s.CurrentParam = param
|
s.CurrentParam = param
|
||||||
@@ -638,10 +639,13 @@ func (s *PurchaseOptionalDetails) handleParamCallback(b *bot.Bot, data string) b
|
|||||||
s.openChannelEditor(b, param, s.CurrentChannel)
|
s.openChannelEditor(b, param, s.CurrentChannel)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
s.Enter(b, bot.EditMessage)
|
||||||
|
return true
|
||||||
case strings.HasPrefix(data, "param_copy:"):
|
case strings.HasPrefix(data, "param_copy:"):
|
||||||
param, index, ok := s.parseParamIndex(data, "param_copy:")
|
param, index, ok := s.parseParamIndex(data, "param_copy:")
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
s.Enter(b, bot.EditMessage)
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
if index >= 0 && index < len(s.Channels) {
|
if index >= 0 && index < len(s.Channels) {
|
||||||
username := s.Channels[index].Username
|
username := s.Channels[index].Username
|
||||||
@@ -649,10 +653,13 @@ func (s *PurchaseOptionalDetails) handleParamCallback(b *bot.Bot, data string) b
|
|||||||
s.Enter(b, bot.EditMessage)
|
s.Enter(b, bot.EditMessage)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
s.Enter(b, bot.EditMessage)
|
||||||
|
return true
|
||||||
case strings.HasPrefix(data, "param_paste:"):
|
case strings.HasPrefix(data, "param_paste:"):
|
||||||
param, index, ok := s.parseParamIndex(data, "param_paste:")
|
param, index, ok := s.parseParamIndex(data, "param_paste:")
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
s.Enter(b, bot.EditMessage)
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
if index >= 0 && index < len(s.Channels) {
|
if index >= 0 && index < len(s.Channels) {
|
||||||
username := s.Channels[index].Username
|
username := s.Channels[index].Username
|
||||||
@@ -660,10 +667,13 @@ func (s *PurchaseOptionalDetails) handleParamCallback(b *bot.Bot, data string) b
|
|||||||
s.Enter(b, bot.EditMessage)
|
s.Enter(b, bot.EditMessage)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
s.Enter(b, bot.EditMessage)
|
||||||
|
return true
|
||||||
case strings.HasPrefix(data, "param_clear:"):
|
case strings.HasPrefix(data, "param_clear:"):
|
||||||
param, index, ok := s.parseParamIndex(data, "param_clear:")
|
param, index, ok := s.parseParamIndex(data, "param_clear:")
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
s.Enter(b, bot.EditMessage)
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
if index >= 0 && index < len(s.Channels) {
|
if index >= 0 && index < len(s.Channels) {
|
||||||
username := s.Channels[index].Username
|
username := s.Channels[index].Username
|
||||||
@@ -671,6 +681,8 @@ func (s *PurchaseOptionalDetails) handleParamCallback(b *bot.Bot, data string) b
|
|||||||
s.Enter(b, bot.EditMessage)
|
s.Enter(b, bot.EditMessage)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
s.Enter(b, bot.EditMessage)
|
||||||
|
return true
|
||||||
case strings.HasPrefix(data, "param_apply_all:"):
|
case strings.HasPrefix(data, "param_apply_all:"):
|
||||||
param := strings.TrimPrefix(data, "param_apply_all:")
|
param := strings.TrimPrefix(data, "param_apply_all:")
|
||||||
s.applyParamToAll(param)
|
s.applyParamToAll(param)
|
||||||
|
|||||||
Reference in New Issue
Block a user