217 lines
5.0 KiB
Go
217 lines
5.0 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
|
||
|
|
||
|
MessageThreadId *int
|
||
|
|
||
|
// 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.MessageThreadId != nil {
|
||
|
params["message_thread_id"] = strconv.Itoa(*opt.MessageThreadId)
|
||
|
}
|
||
|
|
||
|
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
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|