replace telegram thinking placeholder with typing indicator

This commit is contained in:
Henrique Costa 2026-02-12 18:53:26 -03:00
parent 7dc16235db
commit 3e4c022c81

View file

@ -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)
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(),
})
}
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(),
})
}
}
}
}(chatID, pID)
}
}(chatID)
metadata := map[string]string{
"message_id": fmt.Sprintf("%d", message.MessageID),