telebot/options.go
2022-10-06 00:45:27 +03:00

214 lines
4.9 KiB
Go

package telebot
import (
"encoding/json"
"strconv"
)
// Option is a shortcut flag type for certain message features
// (so-called options). It means that instead of passing
// fully-fledged SendOptions* to Send(), you can use these
// flags instead.
//
// Supported options are defined as iota-constants.
//
type Option int
const (
// NoPreview = SendOptions.DisableWebPagePreview
NoPreview Option = iota
// Silent = SendOptions.DisableNotification
Silent
// AllowWithoutReply = SendOptions.AllowWithoutReply
AllowWithoutReply
// Protected = SendOptions.Protected
Protected
// ForceReply = ReplyMarkup.ForceReply
ForceReply
// OneTimeKeyboard = ReplyMarkup.OneTimeKeyboard
OneTimeKeyboard
// RemoveKeyboard = ReplyMarkup.RemoveKeyboard
RemoveKeyboard
)
// Placeholder is used to set input field placeholder as a send option.
func Placeholder(text string) *SendOptions {
return &SendOptions{
ReplyMarkup: &ReplyMarkup{
ForceReply: true,
Placeholder: text,
},
}
}
// SendOptions has most complete control over in what way the message
// must be sent, providing an API-complete set of custom properties
// and options.
//
// Despite its power, SendOptions is rather inconvenient to use all
// the way through bot logic, so you might want to consider storing
// and re-using it somewhere or be using Option flags instead.
//
type SendOptions struct {
// If the message is a reply, original message.
ReplyTo *Message
// See ReplyMarkup struct definition.
ReplyMarkup *ReplyMarkup
// For text messages, disables previews for links in this message.
DisableWebPagePreview bool
// Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.
DisableNotification bool
// ParseMode controls how client apps render your message.
ParseMode ParseMode
// Entities is a list of special entities that appear in message text, which can be specified instead of parse_mode.
Entities Entities
// AllowWithoutReply allows sending messages not a as reply if the replied-to message has already been deleted.
AllowWithoutReply bool
// Protected protects the contents of the sent message from forwarding and saving
Protected bool
}
func (og *SendOptions) copy() *SendOptions {
cp := *og
if cp.ReplyMarkup != nil {
cp.ReplyMarkup = cp.ReplyMarkup.copy()
}
return &cp
}
func extractOptions(how []interface{}) *SendOptions {
opts := &SendOptions{}
for _, prop := range how {
switch opt := prop.(type) {
case *SendOptions:
opts = opt.copy()
case *ReplyMarkup:
if opt != nil {
opts.ReplyMarkup = opt.copy()
}
case Option:
switch opt {
case NoPreview:
opts.DisableWebPagePreview = true
case Silent:
opts.DisableNotification = true
case AllowWithoutReply:
opts.AllowWithoutReply = true
case ForceReply:
if opts.ReplyMarkup == nil {
opts.ReplyMarkup = &ReplyMarkup{}
}
opts.ReplyMarkup.ForceReply = true
case OneTimeKeyboard:
if opts.ReplyMarkup == nil {
opts.ReplyMarkup = &ReplyMarkup{}
}
opts.ReplyMarkup.OneTimeKeyboard = true
case RemoveKeyboard:
if opts.ReplyMarkup == nil {
opts.ReplyMarkup = &ReplyMarkup{}
}
opts.ReplyMarkup.RemoveKeyboard = true
case Protected:
opts.Protected = true
default:
panic("telebot: unsupported flag-option")
}
case ParseMode:
opts.ParseMode = opt
case Entities:
opts.Entities = opt
default:
panic("telebot: unsupported send-option")
}
}
return opts
}
func (b *Bot) embedSendOptions(params map[string]string, opt *SendOptions) {
if b.parseMode != ModeDefault {
params["parse_mode"] = b.parseMode
}
if opt == nil {
return
}
if opt.ReplyTo != nil && opt.ReplyTo.ID != 0 {
params["reply_to_message_id"] = strconv.Itoa(opt.ReplyTo.ID)
}
if opt.DisableWebPagePreview {
params["disable_web_page_preview"] = "true"
}
if opt.DisableNotification {
params["disable_notification"] = "true"
}
if opt.ParseMode != ModeDefault {
params["parse_mode"] = opt.ParseMode
}
if len(opt.Entities) > 0 {
delete(params, "parse_mode")
entities, _ := json.Marshal(opt.Entities)
if params["caption"] != "" {
params["caption_entities"] = string(entities)
} else {
params["entities"] = string(entities)
}
}
if opt.AllowWithoutReply {
params["allow_sending_without_reply"] = "true"
}
if opt.ReplyMarkup != nil {
processButtons(opt.ReplyMarkup.InlineKeyboard)
replyMarkup, _ := json.Marshal(opt.ReplyMarkup)
params["reply_markup"] = string(replyMarkup)
}
if opt.Protected {
params["protect_content"] = "true"
}
}
func processButtons(keys [][]InlineButton) {
if keys == nil || len(keys) < 1 || len(keys[0]) < 1 {
return
}
for i := range keys {
for j := range keys[i] {
key := &keys[i][j]
if key.Unique != "" {
// Format: "\f<callback_name>|<data>"
data := key.Data
if data == "" {
key.Data = "\f" + key.Unique
} else {
key.Data = "\f" + key.Unique + "|" + data
}
}
}
}
}