изображения projects!

This commit is contained in:
Artem Tsyrulnikov
2026-01-19 21:47:44 +03:00
parent f7ad52f543
commit f4a876836e
11 changed files with 682 additions and 73 deletions

View File

@@ -2,6 +2,9 @@ package bot
import (
"context"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"strings"
"sync"
@@ -28,6 +31,9 @@ type Bot struct {
CurrentState State
Session *Session
LastMessageID int // ID последнего сообщения с inline кнопками
LastMessageIsMedia bool // True if LastMessageID points to media message
LastMessageTextHash string // Hash for last text/caption
LastMessageKBHash string // Hash for last inline keyboard
commandRouter func(cmd string) State // Роутер для команд (например, /start, /help)
globalCallbackRouter func(callbackData string) State // Роутер для глобальных callbacks из уведомлений
Backend *backend.Client
@@ -323,6 +329,10 @@ func (b *Bot) Render(text string, keyboard echotron.InlineKeyboardMarkup, mode R
}
}
func (b *Bot) SetLastMessageIsMedia(isMedia bool) {
b.LastMessageIsMedia = isMedia
}
func (b *Bot) DownloadFileBytes(fileID string) ([]byte, error) {
res, err := b.GetFile(fileID)
if err != nil {
@@ -335,7 +345,6 @@ func (b *Bot) DownloadFileBytes(fileID string) ([]byte, error) {
}
func (b *Bot) SendNew(text string, keyboard echotron.InlineKeyboardMarkup) {
// Удаляем кнопки у предыдущего сообщения перед отправкой нового
if b.LastMessageID != 0 {
log.Info().Int("cleanup_msg_id", b.LastMessageID).Msg("Cleaning up keyboard before SendNew")
b.cleanupKeyboard(b.LastMessageID)
@@ -357,6 +366,9 @@ func (b *Bot) SendNew(text string, keyboard echotron.InlineKeyboardMarkup) {
if res.Result != nil {
b.LastMessageID = res.Result.ID
b.LastMessageIsMedia = false
b.LastMessageTextHash = hashString(text)
b.LastMessageKBHash = keyboardHash(keyboard)
log.Info().Int("new_last_msg_id", b.LastMessageID).Msg("Updated LastMessageID in SendNew")
}
}
@@ -368,22 +380,56 @@ func (b *Bot) Edit(text string, keyboard echotron.InlineKeyboardMarkup) {
Int("keyboard_rows", len(keyboard.InlineKeyboard)).
Int("text_len", len(text)).
Msg("EditMessageText request")
_, err := b.EditMessageText(
text,
echotron.NewMessageID(b.ChatID, b.LastMessageID),
&echotron.MessageTextOptions{
ReplyMarkup: keyboard,
ParseMode: echotron.HTML,
},
)
textHash := hashString(text)
kbHash := keyboardHash(keyboard)
if textHash == b.LastMessageTextHash && kbHash == b.LastMessageKBHash {
log.Info().Msg("EditMessageText skipped: message is not modified")
if b.exec != nil {
b.exec.handled = true
}
return
}
var err error
if b.LastMessageIsMedia {
_, err = b.EditMessageCaption(
echotron.NewMessageID(b.ChatID, b.LastMessageID),
&echotron.MessageCaptionOptions{
Caption: text,
ParseMode: echotron.HTML,
ReplyMarkup: keyboard,
},
)
if err == nil {
b.LastMessageTextHash = textHash
b.LastMessageKBHash = kbHash
}
} else {
_, err = b.EditMessageText(
text,
echotron.NewMessageID(b.ChatID, b.LastMessageID),
&echotron.MessageTextOptions{
ReplyMarkup: keyboard,
ParseMode: echotron.HTML,
},
)
if err == nil {
b.LastMessageTextHash = textHash
b.LastMessageKBHash = kbHash
}
}
if err != nil {
if strings.Contains(err.Error(), "message is not modified") {
log.Info().Msg("EditMessageText ignored: message is not modified")
log.Err(err).Msg("EditMessageText ignored: message is not modified")
if b.exec != nil {
b.exec.handled = true
}
return
}
if strings.Contains(err.Error(), "no text in the message to edit") {
b.LastMessageIsMedia = true
log.Err(err).Msg("EditMessageText ignored: message has no text")
return
}
log.Error().Err(err).Msg("EditMessageText")
}
} else {
@@ -420,9 +466,26 @@ func (b *Bot) SendMessageWithURLButton(text, buttonText, url string) {
if err == nil && res.Result != nil {
b.LastMessageID = res.Result.ID
b.LastMessageIsMedia = false
b.LastMessageTextHash = hashString(text)
b.LastMessageKBHash = keyboardHash(keyboard)
}
}
func keyboardHash(kb echotron.InlineKeyboardMarkup) string {
b, err := json.Marshal(kb)
if err != nil {
return ""
}
sum := sha256.Sum256(b)
return hex.EncodeToString(sum[:])
}
func hashString(v string) string {
sum := sha256.Sum256([]byte(v))
return hex.EncodeToString(sum[:])
}
func (b *Bot) Update(u *echotron.Update) {
b.mu.Lock()
defer b.mu.Unlock()