Files
transcriber/internal/adapter/telegram/sender.go
T
av b733a84d6a telegram: сервис поднимается без бота и работает одним входом
- Клиент бота собирается один раз и достаётся отправителю и транспорту;
  разрез прошёл по «ответил ли Telegram»: ответ «такого бота нет» роняет
  старт, недоступность даёт подъём без Telegram (ADR-2026-08-13). Ожидание
  при сборке ограничено сроком — иначе молчащий Telegram вешал подъём.
- Недоставленный ответ не роняет шаг: пишется с job_id и считается метрикой,
  уровень по причине — WARN для неподнятого входа, ERROR для неназванного
  адресата. Заведены transcriber_intake_up и transcriber_undelivered_reply_count.
- Закрыта утечка токена в журнал: отказ разбора адреса рождается раньше
  обращения к клиенту, то есть мимо чистки на его границе.
2026-08-13 19:10:08 +03:00

67 lines
1.9 KiB
Go

package telegram
import (
"log/slog"
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
)
const (
TextLengthLimit = 4000
)
type TelegramMessageSender struct {
bot *tgbotapi.BotAPI
logger *slog.Logger
}
// NewTelegramMessageSender принимает готового клиента, а не токен. Клиента
// заводит сборка при старте — одного на отправителя и на транспорт бота: пока
// его строили здесь и там порознь, два пути одного старта разошлись в том,
// терпеть ли негодный токен, и согласовывать их приходилось руками.
func NewTelegramMessageSender(bot *tgbotapi.BotAPI, logger *slog.Logger) *TelegramMessageSender {
return &TelegramMessageSender{
bot: bot,
logger: logger,
}
}
func (s *TelegramMessageSender) Send(text string, chatId int64, replyToMessageId *int) error {
// If message is short enough, send it directly
if len([]rune(text)) <= TextLengthLimit {
return s.sendSingleMessage(text, chatId, replyToMessageId)
}
// Split long message into parts
parts := s.splitMessageByWords(text, TextLengthLimit)
// Send each part
for i, part := range parts {
var replyId *int
// Only use replyToMessageId for the first part
if i == 0 {
replyId = replyToMessageId
}
err := s.sendSingleMessage(part, chatId, replyId)
if err != nil {
return err
}
}
return nil
}
// sendSingleMessage sends a single message
func (s *TelegramMessageSender) sendSingleMessage(text string, chatId int64, replyToMessageId *int) error {
resultMsg := tgbotapi.NewMessage(chatId, text)
if replyToMessageId != nil {
resultMsg.ReplyToMessageID = *replyToMessageId
}
_, err := s.bot.Send(resultMsg)
if err != nil {
s.logger.Error("Failed to send message to tg bot", "error", err)
return err
}
return nil
}