(new): rich messages, tgfmt DSL, Bot API 10.1
Golang lint / lint (push) Successful in 29s
Golang lint / lint (pull_request) Successful in 1m47s

(fix): editMessageText rich_message type
(tests): rich and API 10.1 coverage
(doc): rich godoc, CHANGELOG v1.1.0

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-08 12:45:47 +03:00
co-authored by Claude Fable 5
parent b563e695df
commit 48ddf66540
22 changed files with 2232 additions and 1027 deletions
+42
View File
@@ -11,6 +11,7 @@ import (
"time"
"git.scuroneko.dev/scuroneko/laniakea/tgapi"
"git.scuroneko.dev/scuroneko/laniakea/tgfmt"
"git.scuroneko.dev/scuroneko/sneklog/v2"
)
@@ -821,3 +822,44 @@ func (ctx *MessageContext) UpsertKeyboard(text string, keyboard *InlineKeyboard)
func (ctx *MessageContext) UpsertKeyboardMarkdown(text string, keyboard *InlineKeyboard) *AnswerMessage {
return ctx.upsertKeyboard(text, keyboard, tgapi.ParseMarkdownV2)
}
func (ctx *MessageContext) richAnswer(rich tgapi.InputRichMessage, keyboard *InlineKeyboard) *AnswerMessage {
if ctx.Msg == nil {
ctx.Logger.Errorln(ErrMessageContextNil)
return nil
}
params := tgapi.SendRichMessage{
ChatID: ctx.Msg.Chat.ID,
RichMessage: rich,
}
if keyboard != nil {
params.ReplyMarkup = keyboard.Get()
}
if ctx.Msg.MessageThreadID > 0 {
params.MessageThreadID = int64(ctx.Msg.MessageThreadID)
}
if ctx.Msg.DirectMessageTopic != nil {
params.DirectMessagesTopicID = ctx.Msg.DirectMessageTopic.TopicID
}
msg, err := ctx.API.SendRichMessageWithContext(ctx.Context(), params)
if err != nil {
ctx.Logger.Errorln(err)
return nil
}
return &AnswerMessage{
MessageID: msg.MessageID, ctx: ctx, Text: rich.HTML, IsMedia: false,
}
}
// RichAnswer sends a rich message (Bot API 10.1) built from tgfmt fragments.
// Both inline (tgfmt.Rich) and block (tgfmt.RichBlock) fragments are accepted
// at the top level: Telegram merges adjacent inline content into paragraphs.
func (ctx *MessageContext) RichAnswer(items ...tgfmt.RichItem) *AnswerMessage {
return ctx.richAnswer(tgfmt.RichMessage(items...), nil)
}
// RichAnswerKeyboard sends a rich message with an inline keyboard.
func (ctx *MessageContext) RichAnswerKeyboard(keyboard *InlineKeyboard, items ...tgfmt.RichItem) *AnswerMessage {
return ctx.richAnswer(tgfmt.RichMessage(items...), keyboard)
}