fix: keep keyboard update message alive instead of send-delete pattern

Previous approach (send \u200C then immediately delete it) lost the
reply keyboard because Telegram may not persist the keyboard from a
deleted message. Now we delete the OLD keyboard message and keep the
new one, ensuring the reply keyboard is always present and correct.
This commit is contained in:
2026-06-24 09:52:28 +03:30
parent b6c7cf81c8
commit 9c83ed98c6

View File

@@ -21,6 +21,7 @@ type Handler struct {
DB *db.Store DB *db.Store
AllowedUsers map[int64]bool AllowedUsers map[int64]bool
lastMsgTime map[int64]time.Time lastMsgTime map[int64]time.Time
keyboardMsg map[int64]int
mu sync.Mutex mu sync.Mutex
} }
@@ -30,6 +31,7 @@ func NewHandler(bot *tgbotapi.BotAPI, store *db.Store, allowed map[int64]bool) *
DB: store, DB: store,
AllowedUsers: allowed, AllowedUsers: allowed,
lastMsgTime: make(map[int64]time.Time), lastMsgTime: make(map[int64]time.Time),
keyboardMsg: make(map[int64]int),
} }
} }
@@ -359,11 +361,19 @@ func (h *Handler) handleStart(msg *tgbotapi.Message) {
} }
func (h *Handler) updateReplyKeyboard(chatID int64) { func (h *Handler) updateReplyKeyboard(chatID int64) {
h.mu.Lock()
oldID := h.keyboardMsg[chatID]
h.mu.Unlock()
if oldID != 0 {
h.Bot.Request(tgbotapi.NewDeleteMessage(chatID, oldID))
}
msg := tgbotapi.NewMessage(chatID, "\u200C") msg := tgbotapi.NewMessage(chatID, "\u200C")
msg.ReplyMarkup = h.smartKeyboard(chatID) msg.ReplyMarkup = h.smartKeyboard(chatID)
sent, err := h.Bot.Send(msg) sent, err := h.Bot.Send(msg)
if err == nil { if err == nil {
h.Bot.Request(tgbotapi.NewDeleteMessage(chatID, sent.MessageID)) h.mu.Lock()
h.keyboardMsg[chatID] = sent.MessageID
h.mu.Unlock()
} }
} }