diff --git a/src/dto/user.py b/src/dto/user.py index f327e9e..ac29953 100644 --- a/src/dto/user.py +++ b/src/dto/user.py @@ -7,3 +7,5 @@ class UserOutput(pydantic.BaseModel): id: uuid.UUID telegram_id: int username: str | None + first_name: str | None + last_name: str | None diff --git a/src/usecase/auth/get_me.py b/src/usecase/auth/get_me.py index cb66bc8..5688e5d 100644 --- a/src/usecase/auth/get_me.py +++ b/src/usecase/auth/get_me.py @@ -17,4 +17,6 @@ async def get_me(self: 'Usecase', user_id: uuid.UUID) -> dto.UserOutput: id=user.id, telegram_id=user.telegram_id, username=user.username, + first_name=user.first_name, + last_name=user.last_name, ) diff --git a/telegram_bot/bot/bot.go b/telegram_bot/bot/bot.go index 0c49632..f414c6f 100644 --- a/telegram_bot/bot/bot.go +++ b/telegram_bot/bot/bot.go @@ -68,6 +68,49 @@ func NewBot( return bot } +// GetOrCreateJWT получает JWT токен, передавая актуальные данные пользователя из update +func (b *Bot) GetOrCreateJWT(u *echotron.Update) error { + // Извлекаем данные пользователя из update + var user *echotron.User + if u.Message != nil && u.Message.From != nil { + user = u.Message.From + } else if u.CallbackQuery != nil && u.CallbackQuery.From != nil { + user = u.CallbackQuery.From + } + + var username, firstName, lastName *string + if user != nil { + if user.Username != "" { + username = &user.Username + } + if user.FirstName != "" { + firstName = &user.FirstName + } + if user.LastName != "" { + lastName = &user.LastName + } + } + + // Запрашиваем JWT с актуальными данными пользователя (или создаем нового если не существует) + jwt, err := b.Backend.GetJWTByTelegramUser( + context.Background(), + b.ChatID, + username, + firstName, + lastName, + ) + if err != nil { + return err + } + + // Сохраняем в сессию + b.Session.JWT = jwt + if username != nil { + b.Session.UserName = *username + } + return nil +} + func (b *Bot) SetState(s State, mode RenderMode) { log.Info(). Int64("chat_id", b.ChatID). @@ -265,6 +308,12 @@ func (b *Bot) Update(u *echotron.Update) { return } + // Получаем или создаем JWT, обновляя данные пользователя (username, first_name, last_name) + if err := b.GetOrCreateJWT(u); err != nil { + log.Error().Err(err).Msg("Failed to get or create JWT") + // Не блокируем работу бота если JWT не удалось получить - это не критично для всех действий + } + exec := &Exec{} b.exec = exec diff --git a/telegram_bot/main.go b/telegram_bot/main.go index 7778957..efa5143 100644 --- a/telegram_bot/main.go +++ b/telegram_bot/main.go @@ -38,8 +38,18 @@ func main() { log.Info().Msg("bot starting...") + updateOpts := echotron.UpdateOptions{ + AllowedUpdates: []echotron.UpdateType{ + echotron.MessageUpdate, + echotron.CallbackQueryUpdate, + echotron.MyChatMemberUpdate, + echotron.ChatMemberUpdate, + echotron.UpdateType("chat_join_request"), + }, + } + for { - if err := dsp.Poll(); err != nil { + if err := dsp.PollOptions(false, updateOpts); err != nil { log.Error().Err(err).Msg("dsp.Poll failed, retrying in 5 seconds...") time.Sleep(5 * time.Second) continue diff --git a/telegram_bot/screens/add_creative.go b/telegram_bot/screens/add_creative.go index c21fafb..8f03b72 100644 --- a/telegram_bot/screens/add_creative.go +++ b/telegram_bot/screens/add_creative.go @@ -579,14 +579,15 @@ func (s *AddCreative) sendCreativeAndPanel(b *bot.Bot) { } func (s *AddCreative) createCreative(b *bot.Bot) { - // Получаем JWT - jwt, err := s.ensureJWT(b) - if err != nil { - log.Error().Err(err).Msg("Failed to get JWT") + // JWT уже создан в Bot.Update(), просто берем из сессии + jwt := b.Session.JWT + if jwt == "" { + log.Error().Msg("JWT is empty in session") b.SendNew("❌ Ошибка авторизации\n\nПопробуйте /start login", bot.Keyboard()) return } + var err error var mediaData []byte if s.MediaFileID != "" { mediaData, err = b.DownloadFileBytes(s.MediaFileID) @@ -685,20 +686,3 @@ https://t.me/+AbCdEfGhIjKlMn` b.SetState(s.BackState, bot.NewMessage) } } - -func (s *AddCreative) ensureJWT(b *bot.Bot) (string, error) { - // Проверяем, есть ли JWT в сессии - if b.Session.JWT != "" { - return b.Session.JWT, nil - } - - // Если нет, запрашиваем новый - jwt, err := b.Backend.GetJWTByTelegramID(context.Background(), b.ChatID) - if err != nil { - return "", err - } - - // Сохраняем в сессию - b.Session.JWT = jwt - return jwt, nil -} diff --git a/telegram_bot/screens/add_purchase.go b/telegram_bot/screens/add_purchase.go index 0354594..4b4ad97 100644 --- a/telegram_bot/screens/add_purchase.go +++ b/telegram_bot/screens/add_purchase.go @@ -28,9 +28,10 @@ type AddPurchase struct { } func (s *AddPurchase) Enter(b *bot.Bot, mode bot.RenderMode) { - jwt, err := s.ensureJWT(b) - if err != nil { - log.Error().Err(err).Msg("Failed to get JWT") + // JWT уже создан в Bot.Update(), просто берем из сессии + jwt := b.Session.JWT + if jwt == "" { + log.Error().Msg("JWT is empty in session") b.SendNew("❌ Ошибка авторизации. Попробуйте /start", bot.Keyboard()) return } @@ -203,20 +204,6 @@ func (s *AddPurchase) renderSelection(b *bot.Bot, mode bot.RenderMode, jwt strin b.Render(text, keyboard, mode) } -func (s *AddPurchase) ensureJWT(b *bot.Bot) (string, error) { - if b.Session.JWT != "" { - return b.Session.JWT, nil - } - - jwt, err := b.Backend.GetJWTByTelegramID(context.Background(), b.ChatID) - if err != nil { - return "", err - } - - b.Session.JWT = jwt - return jwt, nil -} - func (s *AddPurchase) HandleCallback(b *bot.Bot, u *echotron.Update) { if u.CallbackQuery == nil || u.CallbackQuery.Data == "" { return diff --git a/telegram_bot/screens/creative_details.go b/telegram_bot/screens/creative_details.go index 8682ee5..64c9dfa 100644 --- a/telegram_bot/screens/creative_details.go +++ b/telegram_bot/screens/creative_details.go @@ -24,10 +24,10 @@ type CreativeDetails struct { } func (s *CreativeDetails) Enter(b *bot.Bot, mode bot.RenderMode) { - // Получаем JWT - jwt, err := s.ensureJWT(b) - if err != nil { - log.Error().Err(err).Msg("Failed to get JWT") + // JWT уже создан в Bot.Update(), просто берем из сессии + jwt := b.Session.JWT + if jwt == "" { + log.Error().Msg("JWT is empty in session") b.SendNew("❌ Ошибка авторизации\n\nПопробуйте /start", bot.Keyboard()) return } @@ -400,14 +400,16 @@ func (s *CreativeDetails) showManagementPanelWithDelete(b *bot.Bot) { } func (s *CreativeDetails) updateCreative(b *bot.Bot) { - // Получаем JWT - jwt, err := s.ensureJWT(b) - if err != nil { - log.Error().Err(err).Msg("Failed to get JWT") + // JWT уже создан в Bot.Update(), просто берем из сессии + jwt := b.Session.JWT + if jwt == "" { + log.Error().Msg("JWT is empty in session") b.SendNew("❌ Ошибка авторизации\n\nПопробуйте /start", bot.Keyboard()) return } + var err error + // Подготавливаем данные для обновления input := backend.UpdateCreativeInput{ Name: s.Name, @@ -471,16 +473,16 @@ func (s *CreativeDetails) updateCreative(b *bot.Bot) { } func (s *CreativeDetails) deleteCreative(b *bot.Bot) { - // Получаем JWT - jwt, err := s.ensureJWT(b) - if err != nil { - log.Error().Err(err).Msg("Failed to get JWT") + // JWT уже создан в Bot.Update(), просто берем из сессии + jwt := b.Session.JWT + if jwt == "" { + log.Error().Msg("JWT is empty in session") b.SendNew("❌ Ошибка авторизации\n\nПопробуйте /start", bot.Keyboard()) return } // Отправляем запрос на удаление - err = b.Backend.DeleteCreative( + err := b.Backend.DeleteCreative( context.Background(), jwt, s.WorkspaceID, @@ -503,20 +505,3 @@ func (s *CreativeDetails) deleteCreative(b *bot.Bot) { b.SetState(s.BackState, bot.NewMessage) } } - -func (s *CreativeDetails) ensureJWT(b *bot.Bot) (string, error) { - // Проверяем есть ли JWT в сессии - if b.Session.JWT != "" { - return b.Session.JWT, nil - } - - // Если нет, запрашиваем новый - jwt, err := b.Backend.GetJWTByTelegramID(context.Background(), b.ChatID) - if err != nil { - return "", err - } - - // Сохраняем в сессию - b.Session.JWT = jwt - return jwt, nil -} diff --git a/telegram_bot/screens/creative_editor.go b/telegram_bot/screens/creative_editor.go index a5bcd73..622a2a6 100644 --- a/telegram_bot/screens/creative_editor.go +++ b/telegram_bot/screens/creative_editor.go @@ -45,20 +45,18 @@ type CreativeEditorFields struct { } const inviteLinkPlaceholder = "{{invite_link}}" -const inviteLinkPreviewURL = "https://t.me/placeholder" +const inviteLinkPreviewURL = "https://t.me/J7_channel" // GetCreativeText возвращает текст для превью креатива func (e *CreativeEditorFields) GetCreativeText() string { var result string if e.Text != nil && *e.Text != "" { - // Проверяем что текст не является "визуально пустым" HTML - // Например: "" - пустая ссылка text := strings.TrimSpace(*e.Text) - // Убираем пустые HTML-теги (простая проверка) - if text == "" || text == "" { - log.Info().Str("text", *e.Text).Msg("GetCreativeText: text is visually empty, using default") + // Проверяем что текст не пустой + if text == "" { + log.Info().Str("text", *e.Text).Msg("GetCreativeText: text is empty, using default") return result + `💭 Я твой креатив У меня пока нет текста, добавь его ниже. @@ -66,8 +64,14 @@ func (e *CreativeEditorFields) GetCreativeText() string { ` } + // Заменяем пустую ссылку на валидную preview-ссылку + text = strings.ReplaceAll(text, ``, `👉 Подписаться`) + + // Также заменяем плейсхолдер {{invite_link}} на preview URL (как в кнопках) + text = strings.ReplaceAll(text, inviteLinkPlaceholder, inviteLinkPreviewURL) + log.Info().Str("text", *e.Text).Msg("GetCreativeText: returning creative text") - return result + *e.Text + return result + text } log.Info().Bool("text_is_nil", e.Text == nil).Msg("GetCreativeText: returning default text") return result + `💭 Я твой креатив @@ -156,6 +160,9 @@ func (e *CreativeEditorFields) SendCreativePreview(b *bot.Bot) { res, err := b.SendMessage(creativeText, b.ChatID, &echotron.MessageOptions{ ReplyMarkup: keyboard, ParseMode: echotron.HTML, + LinkPreviewOptions: echotron.LinkPreviewOptions{ + IsDisabled: true, + }, }) if err == nil && res.Result != nil { msgID = res.Result.ID @@ -169,6 +176,9 @@ func (e *CreativeEditorFields) SendCreativePreview(b *bot.Bot) { res, err := b.SendMessage(creativeText, b.ChatID, &echotron.MessageOptions{ ReplyMarkup: keyboard, ParseMode: echotron.HTML, + LinkPreviewOptions: echotron.LinkPreviewOptions{ + IsDisabled: true, + }, }) if err != nil { log.Error().Err(err).Msg("Failed to send creative preview") @@ -258,6 +268,9 @@ func (e *CreativeEditorFields) UpdateCreativePreview(b *bot.Bot) { &echotron.MessageTextOptions{ ParseMode: echotron.HTML, ReplyMarkup: keyboard, + LinkPreviewOptions: echotron.LinkPreviewOptions{ + IsDisabled: true, + }, }, ) if err != nil { diff --git a/telegram_bot/screens/creatives.go b/telegram_bot/screens/creatives.go index fa8b009..6767b4f 100644 --- a/telegram_bot/screens/creatives.go +++ b/telegram_bot/screens/creatives.go @@ -22,9 +22,10 @@ type Creatives struct { } func (s *Creatives) Enter(b *bot.Bot, mode bot.RenderMode) { - jwt, err := s.ensureJWT(b) - if err != nil { - log.Error().Err(err).Msg("Failed to get JWT") + // JWT уже создан в Bot.Update(), просто берем из сессии + jwt := b.Session.JWT + if jwt == "" { + log.Error().Msg("JWT is empty in session") b.SendNew("❌ Ошибка авторизации. Попробуйте /start login", bot.Keyboard()) return } @@ -131,23 +132,6 @@ func (s *Creatives) renderCreatives(b *bot.Bot, mode bot.RenderMode, jwt string) b.Render(text, keyboard, mode) } -func (s *Creatives) ensureJWT(b *bot.Bot) (string, error) { - // Проверяем, есть ли JWT в сессии - if b.Session.JWT != "" { - return b.Session.JWT, nil - } - - // Если нет, запрашиваем новый - jwt, err := b.Backend.GetJWTByTelegramID(context.Background(), b.ChatID) - if err != nil { - return "", err - } - - // Сохраняем в сессию - b.Session.JWT = jwt - return jwt, nil -} - func (s *Creatives) HandleCallback(b *bot.Bot, u *echotron.Update) { if u.CallbackQuery == nil || u.CallbackQuery.Data == "" { return diff --git a/telegram_bot/screens/login.go b/telegram_bot/screens/login.go index 0a86d12..5af93a5 100644 --- a/telegram_bot/screens/login.go +++ b/telegram_bot/screens/login.go @@ -12,15 +12,15 @@ import ( type Login struct{} func (s *Login) Enter(b *bot.Bot, mode bot.RenderMode) { - telegramID := b.ChatID + // JWT уже создан в Bot.Update() с актуальными данными пользователя + // Теперь создаем login token (это разовый токен для авторизации на сайте) var username *string - - chatInfo, err := b.GetChat(telegramID) - if err == nil && chatInfo.Result != nil && chatInfo.Result.Username != "" { - username = &chatInfo.Result.Username + // Получаем username из сессии если он там сохранен + if b.Session.UserName != "" { + username = &b.Session.UserName } - token, err := b.Backend.CreateLoginToken(context.Background(), telegramID, username) + token, err := b.Backend.CreateLoginToken(context.Background(), b.ChatID, username) if err != nil { log.Error().Err(err).Msg("Failed to create login token") b.SendMessage("❌ Произошла ошибка при создании токена входа. Попробуйте позже.", b.ChatID, nil) diff --git a/telegram_bot/screens/my_placements.go b/telegram_bot/screens/my_placements.go index 03343fd..689d7e4 100644 --- a/telegram_bot/screens/my_placements.go +++ b/telegram_bot/screens/my_placements.go @@ -20,10 +20,10 @@ type MyPlacements struct { } func (s *MyPlacements) Enter(b *bot.Bot, mode bot.RenderMode) { - // Получаем или запрашиваем JWT - jwt, err := s.ensureJWT(b) - if err != nil { - log.Error().Err(err).Msg("Failed to get JWT") + // JWT уже создан в Bot.Update(), просто берем из сессии + jwt := b.Session.JWT + if jwt == "" { + log.Error().Msg("JWT is empty in session") b.SendNew("❌ Ошибка авторизации. Попробуйте /start login", bot.Keyboard()) return } @@ -124,23 +124,6 @@ func (s *MyPlacements) renderPlacements(b *bot.Bot, mode bot.RenderMode, jwt str b.Render(text, keyboard, mode) } -func (s *MyPlacements) ensureJWT(b *bot.Bot) (string, error) { - // Проверяем, есть ли JWT в сессии - if b.Session.JWT != "" { - return b.Session.JWT, nil - } - - // Если нет, запрашиваем новый - jwt, err := b.Backend.GetJWTByTelegramID(context.Background(), b.ChatID) - if err != nil { - return "", err - } - - // Сохраняем в сессию - b.Session.JWT = jwt - return jwt, nil -} - func (s *MyPlacements) HandleCallback(b *bot.Bot, u *echotron.Update) { if u.CallbackQuery == nil || u.CallbackQuery.Data == "" { return diff --git a/telegram_bot/screens/my_projects.go b/telegram_bot/screens/my_projects.go index 6047e1a..067f339 100644 --- a/telegram_bot/screens/my_projects.go +++ b/telegram_bot/screens/my_projects.go @@ -21,10 +21,10 @@ type MyProjects struct { } func (s *MyProjects) Enter(b *bot.Bot, mode bot.RenderMode) { - // Получаем или запрашиваем JWT - jwt, err := s.ensureJWT(b) - if err != nil { - log.Error().Err(err).Msg("Failed to get JWT") + // JWT уже создан в Bot.Update(), просто берем из сессии + jwt := b.Session.JWT + if jwt == "" { + log.Error().Msg("JWT is empty in session") b.SendNew("❌ Ошибка авторизации. Попробуйте /start login", bot.Keyboard()) return } @@ -167,23 +167,6 @@ func (s *MyProjects) renderProjects(b *bot.Bot, mode bot.RenderMode, jwt string) b.Render(text, keyboard, mode) } -func (s *MyProjects) ensureJWT(b *bot.Bot) (string, error) { - // Проверяем, есть ли JWT в сессии - if b.Session.JWT != "" { - return b.Session.JWT, nil - } - - // Если нет, запрашиваем новый - jwt, err := b.Backend.GetJWTByTelegramID(context.Background(), b.ChatID) - if err != nil { - return "", err - } - - // Сохраняем в сессию - b.Session.JWT = jwt - return jwt, nil -} - func (s *MyProjects) HandleCallback(b *bot.Bot, u *echotron.Update) { if u.CallbackQuery == nil || u.CallbackQuery.Data == "" { return diff --git a/telegram_bot/screens/purchase_details.go b/telegram_bot/screens/purchase_details.go index fcb6034..8565709 100644 --- a/telegram_bot/screens/purchase_details.go +++ b/telegram_bot/screens/purchase_details.go @@ -18,9 +18,9 @@ type PurchaseDetails struct { } func (s *PurchaseDetails) Enter(b *bot.Bot, mode bot.RenderMode) { - jwt, err := s.ensureJWT(b) - if err != nil { - log.Error().Err(err).Msg("Failed to get JWT") + jwt := b.Session.JWT + if jwt == "" { + log.Error().Msg("JWT is empty in session") b.SendNew("❌ Ошибка авторизации. Попробуйте /start", bot.Keyboard()) return } @@ -136,20 +136,6 @@ func (s *PurchaseDetails) renderDetails(b *bot.Bot, mode bot.RenderMode, jwt str b.Render(text, keyboard, mode) } -func (s *PurchaseDetails) ensureJWT(b *bot.Bot) (string, error) { - if b.Session.JWT != "" { - return b.Session.JWT, nil - } - - jwt, err := b.Backend.GetJWTByTelegramID(context.Background(), b.ChatID) - if err != nil { - return "", err - } - - b.Session.JWT = jwt - return jwt, nil -} - func (s *PurchaseDetails) HandleCallback(b *bot.Bot, u *echotron.Update) { if u.CallbackQuery == nil || u.CallbackQuery.Data == "" { return diff --git a/telegram_bot/screens/purchase_optional_details.go b/telegram_bot/screens/purchase_optional_details.go index 236c125..6d3fff7 100644 --- a/telegram_bot/screens/purchase_optional_details.go +++ b/telegram_bot/screens/purchase_optional_details.go @@ -207,9 +207,9 @@ func (s *PurchaseOptionalDetails) HandleCallback(b *bot.Bot, u *echotron.Update) BackState: s.BackState, }, bot.EditMessage) case "next": - jwt, err := s.ensureJWT(b) - if err != nil { - log.Error().Err(err).Msg("Failed to get JWT") + jwt := b.Session.JWT + if jwt == "" { + log.Error().Msg("JWT is empty in session") b.SendNew("❌ Ошибка авторизации. Попробуйте /start", bot.Keyboard()) return } @@ -285,20 +285,6 @@ func (s *PurchaseOptionalDetails) HandleMessage(b *bot.Bot, u *echotron.Update) func (s *PurchaseOptionalDetails) Handle(_ *bot.Bot, _ *echotron.Update) { return } -func (s *PurchaseOptionalDetails) ensureJWT(b *bot.Bot) (string, error) { - if b.Session.JWT != "" { - return b.Session.JWT, nil - } - - jwt, err := b.Backend.GetJWTByTelegramID(context.Background(), b.ChatID) - if err != nil { - return "", err - } - - b.Session.JWT = jwt - return jwt, nil -} - func (s *PurchaseOptionalDetails) SetDateTimeSelection(key string, value time.Time) { switch key { case "placement_datetime": diff --git a/telegram_bot/screens/purchases.go b/telegram_bot/screens/purchases.go index a516417..3b05031 100644 --- a/telegram_bot/screens/purchases.go +++ b/telegram_bot/screens/purchases.go @@ -17,9 +17,9 @@ type Purchases struct { } func (s *Purchases) Enter(b *bot.Bot, mode bot.RenderMode) { - jwt, err := s.ensureJWT(b) - if err != nil { - log.Error().Err(err).Msg("Failed to get JWT") + jwt := b.Session.JWT + if jwt == "" { + log.Error().Msg("JWT is empty in session") b.SendNew("❌ Ошибка авторизации. Попробуйте /start", bot.Keyboard()) return } @@ -109,20 +109,6 @@ func (s *Purchases) renderPurchases(b *bot.Bot, mode bot.RenderMode, jwt string) b.Render(text, keyboard, mode) } -func (s *Purchases) ensureJWT(b *bot.Bot) (string, error) { - if b.Session.JWT != "" { - return b.Session.JWT, nil - } - - jwt, err := b.Backend.GetJWTByTelegramID(context.Background(), b.ChatID) - if err != nil { - return "", err - } - - b.Session.JWT = jwt - return jwt, nil -} - func (s *Purchases) HandleCallback(b *bot.Bot, u *echotron.Update) { if u.CallbackQuery == nil || u.CallbackQuery.Data == "" { return diff --git a/telegram_bot/screens/select_channels_for_purchase.go b/telegram_bot/screens/select_channels_for_purchase.go index a0cb39e..c50df6a 100644 --- a/telegram_bot/screens/select_channels_for_purchase.go +++ b/telegram_bot/screens/select_channels_for_purchase.go @@ -130,20 +130,6 @@ func (s *SelectChannelsForPurchase) renderChannelSelection(b *bot.Bot, mode bot. b.Render(text, keyboard, mode) } -func (s *SelectChannelsForPurchase) ensureJWT(b *bot.Bot) (string, error) { - if b.Session.JWT != "" { - return b.Session.JWT, nil - } - - jwt, err := b.Backend.GetJWTByTelegramID(context.Background(), b.ChatID) - if err != nil { - return "", err - } - - b.Session.JWT = jwt - return jwt, nil -} - func (s *SelectChannelsForPurchase) HandleCallback(b *bot.Bot, u *echotron.Update) { if u.CallbackQuery == nil || u.CallbackQuery.Data == "" { return diff --git a/telegram_bot/screens/select_workspace.go b/telegram_bot/screens/select_workspace.go index 1b811eb..f6fcd2c 100644 --- a/telegram_bot/screens/select_workspace.go +++ b/telegram_bot/screens/select_workspace.go @@ -16,9 +16,10 @@ type SelectWorkspace struct { } func (s *SelectWorkspace) Enter(b *bot.Bot, mode bot.RenderMode) { - jwt, err := s.ensureJWT(b) - if err != nil { - log.Error().Err(err).Msg("Failed to get JWT") + // JWT уже создан в Bot.Update(), просто берем из сессии + jwt := b.Session.JWT + if jwt == "" { + log.Error().Msg("JWT is empty in session") b.SendNew("❌ Ошибка авторизации. Попробуйте /start", bot.Keyboard()) return } @@ -56,23 +57,6 @@ func (s *SelectWorkspace) Enter(b *bot.Bot, mode bot.RenderMode) { b.Render(text, keyboard, mode) } -func (s *SelectWorkspace) ensureJWT(b *bot.Bot) (string, error) { - // Проверяем, есть ли JWT в сессии - if b.Session.JWT != "" { - return b.Session.JWT, nil - } - - // Если нет, запрашиваем новый - jwt, err := b.Backend.GetJWTByTelegramID(context.Background(), b.ChatID) - if err != nil { - return "", err - } - - // Сохраняем в сессию - b.Session.JWT = jwt - return jwt, nil -} - func (s *SelectWorkspace) HandleCallback(b *bot.Bot, u *echotron.Update) { if u.CallbackQuery == nil || u.CallbackQuery.Data == "" { return