99 lines
3.2 KiB
Go
99 lines
3.2 KiB
Go
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
|
|
}
|