diff --git a/telegram_bot/adapter/backend/backend_client.go b/telegram_bot/adapter/backend/backend_client.go
index 44c6619..40dffc2 100644
--- a/telegram_bot/adapter/backend/backend_client.go
+++ b/telegram_bot/adapter/backend/backend_client.go
@@ -206,6 +206,30 @@ func (c *Client) GetWorkspaces(
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(
ctx context.Context,
jwt string,
diff --git a/telegram_bot/bot/bot.go b/telegram_bot/bot/bot.go
index 1dfc92a..dab2da6 100644
--- a/telegram_bot/bot/bot.go
+++ b/telegram_bot/bot/bot.go
@@ -3,6 +3,7 @@ package bot
import (
"context"
"fmt"
+ "strings"
"example.com/m/adapter/backend"
"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) {
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(
text,
echotron.NewMessageID(b.ChatID, b.LastMessageID),
@@ -152,6 +158,13 @@ func (b *Bot) Edit(text string, keyboard echotron.InlineKeyboardMarkup) {
},
)
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")
}
} else {
@@ -195,6 +208,9 @@ func (b *Bot) Update(u *echotron.Update) {
log.Info().
Int64("chat_id", b.ChatID).
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")
// Обрабатываем системные события (добавление в канал, подписки и т.д.)
@@ -255,7 +271,21 @@ func (b *Bot) Update(u *echotron.Update) {
}
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)
+ 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 newState := b.GlobalCallbackRouter(u.CallbackQuery.Data); newState != nil {
@@ -272,11 +302,23 @@ func (b *Bot) Update(u *echotron.Update) {
}
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")
b.CurrentState.Handle(b, u)
}
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")
b.SetState(b.DefaultStateFactory(), NewMessage)
}
diff --git a/telegram_bot/screens/add_creative.go b/telegram_bot/screens/add_creative.go
index 61cd6ca..feadc0f 100644
--- a/telegram_bot/screens/add_creative.go
+++ b/telegram_bot/screens/add_creative.go
@@ -85,7 +85,7 @@ https://t.me/+AbCdEfGhIjKlMn`, [][]echotron.InlineKeyboardButton{
// Начинаем процесс добавления медиа
s.WaitingForMedia = true
- s.ShowControlPanel(b, `⧉ Добавить медиа
+ s.ShowControlPanel(b, `+ Добавить медиа
Отправьте фото, видео или GIF
diff --git a/telegram_bot/screens/creative_details.go b/telegram_bot/screens/creative_details.go
index 75c2c49..c111873 100644
--- a/telegram_bot/screens/creative_details.go
+++ b/telegram_bot/screens/creative_details.go
@@ -116,7 +116,7 @@ https://t.me/+AbCdEfGhIjKlMn`, [][]echotron.InlineKeyboardButton{
case data == "add_media":
s.WaitingForMedia = true
- s.ShowControlPanel(b, `⧉ Добавить медиа
+ s.ShowControlPanel(b, `+ Добавить медиа
Отправьте фото, видео или GIF
diff --git a/telegram_bot/screens/creative_editor.go b/telegram_bot/screens/creative_editor.go
index 3a2ff77..dd3e3f8 100644
--- a/telegram_bot/screens/creative_editor.go
+++ b/telegram_bot/screens/creative_editor.go
@@ -283,7 +283,7 @@ func (e *CreativeEditorFields) ShowManagementPanel(b *bot.Bot, confirmButtonText
// Блок редактирования контента
buttons = append(buttons, bot.Row(
bot.Button("✎ Текст", "edit_text"),
- bot.Button("⧉ Медиа", "add_media"),
+ bot.Button("+ Медиа", "add_media"),
))
// Добавление кнопки сразу под основным блоком
buttons = append(buttons, bot.Row(bot.Button("+ Добавить кнопку", "add_button")))
diff --git a/telegram_bot/screens/my_projects.go b/telegram_bot/screens/my_projects.go
index 5b0a1b1..f27c924 100644
--- a/telegram_bot/screens/my_projects.go
+++ b/telegram_bot/screens/my_projects.go
@@ -38,12 +38,34 @@ func (s *MyProjects) Enter(b *bot.Bot, mode bot.RenderMode) {
}
if len(workspaces) == 0 {
- b.SendNew("У вас пока нет workspace'ов", bot.Keyboard())
- return
- }
+ // Автоматически создаем 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
+ }
+ }
+ }
- // Используем первый workspace по умолчанию
- s.WorkspaceID = workspaces[0].ID
+ 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
+ }
+
+ s.WorkspaceID = workspace.ID
+ log.Info().Str("workspace_id", s.WorkspaceID).Str("name", workspace.Name).Msg("Workspace created successfully")
+ } else {
+ // Используем первый workspace по умолчанию
+ s.WorkspaceID = workspaces[0].ID
+ }
}
s.renderProjects(b, mode, jwt)
diff --git a/telegram_bot/screens/purchase_optional_details.go b/telegram_bot/screens/purchase_optional_details.go
index 9b9b28c..51c8438 100644
--- a/telegram_bot/screens/purchase_optional_details.go
+++ b/telegram_bot/screens/purchase_optional_details.go
@@ -570,9 +570,9 @@ func (s *PurchaseOptionalDetails) renderParamChannels(b *bot.Bot, mode bot.Rende
label := fmt.Sprintf("%d", i+1)
rows = append(rows, bot.Row(
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_paste:%s:%d", param, i)),
- bot.Button("✎", fmt.Sprintf("param_edit:%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_edit:%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:"):
param, index, ok := s.parseParamIndex(data, "param_edit:")
if !ok {
- return false
+ s.Enter(b, bot.EditMessage)
+ return true
}
if index >= 0 && index < len(s.Channels) {
s.CurrentParam = param
@@ -638,10 +639,13 @@ func (s *PurchaseOptionalDetails) handleParamCallback(b *bot.Bot, data string) b
s.openChannelEditor(b, param, s.CurrentChannel)
return true
}
+ s.Enter(b, bot.EditMessage)
+ return true
case strings.HasPrefix(data, "param_copy:"):
param, index, ok := s.parseParamIndex(data, "param_copy:")
if !ok {
- return false
+ s.Enter(b, bot.EditMessage)
+ return true
}
if index >= 0 && index < len(s.Channels) {
username := s.Channels[index].Username
@@ -649,10 +653,13 @@ func (s *PurchaseOptionalDetails) handleParamCallback(b *bot.Bot, data string) b
s.Enter(b, bot.EditMessage)
return true
}
+ s.Enter(b, bot.EditMessage)
+ return true
case strings.HasPrefix(data, "param_paste:"):
param, index, ok := s.parseParamIndex(data, "param_paste:")
if !ok {
- return false
+ s.Enter(b, bot.EditMessage)
+ return true
}
if index >= 0 && index < len(s.Channels) {
username := s.Channels[index].Username
@@ -660,10 +667,13 @@ func (s *PurchaseOptionalDetails) handleParamCallback(b *bot.Bot, data string) b
s.Enter(b, bot.EditMessage)
return true
}
+ s.Enter(b, bot.EditMessage)
+ return true
case strings.HasPrefix(data, "param_clear:"):
param, index, ok := s.parseParamIndex(data, "param_clear:")
if !ok {
- return false
+ s.Enter(b, bot.EditMessage)
+ return true
}
if index >= 0 && index < len(s.Channels) {
username := s.Channels[index].Username
@@ -671,6 +681,8 @@ func (s *PurchaseOptionalDetails) handleParamCallback(b *bot.Bot, data string) b
s.Enter(b, bot.EditMessage)
return true
}
+ s.Enter(b, bot.EditMessage)
+ return true
case strings.HasPrefix(data, "param_apply_all:"):
param := strings.TrimPrefix(data, "param_apply_all:")
s.applyParamToAll(param)