feat: sync bot rich messages and inline menus
This commit is contained in:
parent
2965f5d47d
commit
1a2d03f529
24 changed files with 2073 additions and 38 deletions
99
internal/botapi/rich_message.go
Normal file
99
internal/botapi/rich_message.go
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
package botapi
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"telesrv/internal/domain"
|
||||
)
|
||||
|
||||
const maxBotAPIRichSourceBytes = 256 << 10
|
||||
|
||||
func richMessageInputFromAPI(raw string) (domain.BotAPIRichMessageInput, error) {
|
||||
raw = strings.TrimSpace(raw)
|
||||
if raw == "" || len(raw) > maxBotAPIRichSourceBytes {
|
||||
return domain.BotAPIRichMessageInput{}, errors.New("RICH_MESSAGE_INVALID")
|
||||
}
|
||||
var fields map[string]json.RawMessage
|
||||
if err := json.Unmarshal([]byte(raw), &fields); err != nil {
|
||||
return domain.BotAPIRichMessageInput{}, errors.New("RICH_MESSAGE_INVALID")
|
||||
}
|
||||
var out domain.BotAPIRichMessageInput
|
||||
sources := 0
|
||||
if value, ok := fields["html"]; ok && !bytes.Equal(bytes.TrimSpace(value), []byte("null")) {
|
||||
if err := json.Unmarshal(value, &out.HTML); err != nil || out.HTML == "" {
|
||||
return domain.BotAPIRichMessageInput{}, errors.New("RICH_MESSAGE_INVALID")
|
||||
}
|
||||
sources++
|
||||
}
|
||||
if value, ok := fields["markdown"]; ok && !bytes.Equal(bytes.TrimSpace(value), []byte("null")) {
|
||||
if err := json.Unmarshal(value, &out.Markdown); err != nil || out.Markdown == "" {
|
||||
return domain.BotAPIRichMessageInput{}, errors.New("RICH_MESSAGE_INVALID")
|
||||
}
|
||||
sources++
|
||||
}
|
||||
if value, ok := fields["blocks"]; ok && !bytes.Equal(bytes.TrimSpace(value), []byte("null")) {
|
||||
if len(bytes.TrimSpace(value)) == 0 {
|
||||
return domain.BotAPIRichMessageInput{}, errors.New("RICH_MESSAGE_INVALID")
|
||||
}
|
||||
out.BlocksJSON = append([]byte(nil), value...)
|
||||
sources++
|
||||
}
|
||||
if sources != 1 {
|
||||
return domain.BotAPIRichMessageInput{}, errors.New("RICH_MESSAGE_INVALID")
|
||||
}
|
||||
if len(out.BlocksJSON) != 0 {
|
||||
return domain.BotAPIRichMessageInput{}, errors.New("RICH_MESSAGE_BLOCKS_UNSUPPORTED")
|
||||
}
|
||||
if value, ok := fields["media"]; ok && !bytes.Equal(bytes.TrimSpace(value), []byte("null")) && !bytes.Equal(bytes.TrimSpace(value), []byte("[]")) {
|
||||
out.MediaJSON = append([]byte(nil), value...)
|
||||
return domain.BotAPIRichMessageInput{}, errors.New("RICH_MESSAGE_MEDIA_UNSUPPORTED")
|
||||
}
|
||||
if value, ok := fields["is_rtl"]; ok {
|
||||
if err := json.Unmarshal(value, &out.RTL); err != nil {
|
||||
return domain.BotAPIRichMessageInput{}, errors.New("RICH_MESSAGE_INVALID")
|
||||
}
|
||||
}
|
||||
if value, ok := fields["skip_entity_detection"]; ok {
|
||||
if err := json.Unmarshal(value, &out.SkipEntityDetection); err != nil {
|
||||
return domain.BotAPIRichMessageInput{}, errors.New("RICH_MESSAGE_INVALID")
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func richReplyMessageID(values map[string]string) (int, error) {
|
||||
legacy := apiInt(values["reply_to_message_id"], 0)
|
||||
raw := strings.TrimSpace(values["reply_parameters"])
|
||||
if raw == "" {
|
||||
if legacy < 0 {
|
||||
return 0, errors.New("REPLY_MESSAGE_ID_INVALID")
|
||||
}
|
||||
return legacy, nil
|
||||
}
|
||||
if legacy != 0 {
|
||||
return 0, errors.New("REPLY_PARAMETERS_INVALID")
|
||||
}
|
||||
var payload struct {
|
||||
MessageID int `json:"message_id"`
|
||||
}
|
||||
if err := json.Unmarshal([]byte(raw), &payload); err != nil || payload.MessageID <= 0 {
|
||||
return 0, errors.New("REPLY_PARAMETERS_INVALID")
|
||||
}
|
||||
return payload.MessageID, nil
|
||||
}
|
||||
|
||||
func apiInt64(raw string) (int64, error) {
|
||||
raw = strings.TrimSpace(raw)
|
||||
if raw == "" {
|
||||
return 0, nil
|
||||
}
|
||||
value, err := strconv.ParseInt(raw, 10, 64)
|
||||
if err != nil || value < 0 {
|
||||
return 0, errors.New("VALUE_INVALID")
|
||||
}
|
||||
return value, nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue