diff --git a/pkg/channels/telegram.go b/pkg/channels/telegram.go index a18fd1ed8..021807a3d 100644 --- a/pkg/channels/telegram.go +++ b/pkg/channels/telegram.go @@ -27,7 +27,6 @@ type TelegramChannel struct { config config.TelegramConfig chatIDs map[string]int64 transcriber *voice.GroqTranscriber - placeholders sync.Map // chatID -> messageID stopThinking sync.Map // chatID -> thinkingCancel } @@ -69,7 +68,6 @@ func NewTelegramChannel(cfg config.TelegramConfig, bus *bus.MessageBus) (*Telegr config: cfg, chatIDs: make(map[string]int64), transcriber: nil, - placeholders: sync.Map{}, stopThinking: sync.Map{}, }, nil } @@ -139,18 +137,6 @@ func (c *TelegramChannel) Send(ctx context.Context, msg bus.OutboundMessage) err htmlContent := markdownToTelegramHTML(msg.Content) - // Try to edit placeholder - if pID, ok := c.placeholders.Load(msg.ChatID); ok { - c.placeholders.Delete(msg.ChatID) - editMsg := tu.EditMessageText(tu.ID(chatID), pID.(int), htmlContent) - editMsg.ParseMode = telego.ModeHTML - - if _, err = c.bot.EditMessageText(ctx, editMsg); err == nil { - return nil - } - // Fallback to new message if edit fails - } - tgMsg := tu.Message(tu.ID(chatID), htmlContent) tgMsg.ParseMode = telego.ModeHTML @@ -302,15 +288,7 @@ func (c *TelegramChannel) handleMessage(ctx context.Context, update telego.Updat "preview": utils.Truncate(content, 50), }) - // Thinking indicator - err := c.bot.SendChatAction(ctx, tu.ChatAction(tu.ID(chatID), telego.ChatActionTyping)) - if err != nil { - logger.ErrorCF("telegram", "Failed to send chat action", map[string]interface{}{ - "error": err.Error(), - }) - } - - // Stop any previous thinking animation + // Stop any previous typing indicator chatIDStr := fmt.Sprintf("%d", chatID) if prevStop, ok := c.stopThinking.Load(chatIDStr); ok { if cf, ok := prevStop.(*thinkingCancel); ok && cf != nil { @@ -318,38 +296,26 @@ func (c *TelegramChannel) handleMessage(ctx context.Context, update telego.Updat } } - // Create new context for thinking animation with timeout + // Keep typing status active while processing the request. thinkCtx, thinkCancel := context.WithTimeout(ctx, 5*time.Minute) c.stopThinking.Store(chatIDStr, &thinkingCancel{fn: thinkCancel}) - pMsg, err := c.bot.SendMessage(ctx, tu.Message(tu.ID(chatID), "Thinking... 💭")) - if err == nil { - pID := pMsg.MessageID - c.placeholders.Store(chatIDStr, pID) - - go func(cid int64, mid int) { - dots := []string{".", "..", "..."} - emotes := []string{"💭", "🤔", "☁️"} - i := 0 - ticker := time.NewTicker(2000 * time.Millisecond) - defer ticker.Stop() - for { - select { - case <-thinkCtx.Done(): - return - case <-ticker.C: - i++ - text := fmt.Sprintf("Thinking%s %s", dots[i%len(dots)], emotes[i%len(emotes)]) - _, editErr := c.bot.EditMessageText(thinkCtx, tu.EditMessageText(tu.ID(chatID), mid, text)) - if editErr != nil { - logger.DebugCF("telegram", "Failed to edit thinking message", map[string]interface{}{ - "error": editErr.Error(), - }) - } - } + go func(cid int64) { + ticker := time.NewTicker(4 * time.Second) + defer ticker.Stop() + for { + if err := c.bot.SendChatAction(thinkCtx, tu.ChatAction(tu.ID(cid), telego.ChatActionTyping)); err != nil { + logger.DebugCF("telegram", "Failed to send chat action", map[string]interface{}{ + "error": err.Error(), + }) } - }(chatID, pID) - } + select { + case <-thinkCtx.Done(): + return + case <-ticker.C: + } + } + }(chatID) metadata := map[string]string{ "message_id": fmt.Sprintf("%d", message.MessageID),