feat: sync bot keyboards and callbacks

Sync telesrv b96f2dd (feat(bot): complete keyboards callbacks and durable delivery).

Skipped private docs and preserved public README files per sync rules; normalized the appearance seed log label for public naming.
This commit is contained in:
A 2026-07-19 20:38:48 +08:00
parent 0c99ae0a9d
commit bf965f610c
80 changed files with 7212 additions and 349 deletions

View file

@ -2,6 +2,7 @@ package postgres
import (
"encoding/json"
"fmt"
"reflect"
"telesrv/internal/domain"
@ -44,9 +45,12 @@ func decodeMessageMedia(s string) (*domain.MessageMedia, error) {
return &m, nil
}
// encodeReplyMarkup 把 inline keyboard 快照序列化为 JSONB;空 markup 序列化为 "{}"。
// encodeReplyMarkup 把 reply/inline keyboard 快照序列化为 JSONB;空 markup 序列化为 "{}"。
// callback data 是 []byte,json.Marshal 自动 base64(保证经 JSONB 字节级 round-trip)。
func encodeReplyMarkup(m *domain.MessageReplyMarkup) ([]byte, error) {
if err := domain.ValidateReplyMarkup(m); err != nil {
return nil, fmt.Errorf("encode reply markup: %w", err)
}
if m.IsZero() {
return []byte("{}"), nil
}
@ -63,6 +67,9 @@ func decodeReplyMarkup(s string) (*domain.MessageReplyMarkup, error) {
if err := json.Unmarshal([]byte(s), &m); err != nil {
return nil, err
}
if err := domain.ValidateReplyMarkup(&m); err != nil {
return nil, fmt.Errorf("decode reply markup: %w", err)
}
if m.IsZero() {
return nil, nil
}