diff --git a/go.mod b/go.mod index 7a32efb..627ee2a 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ module github.com/DivideProjects/GoLangTgBot go 1.18 require ( - github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.9 + github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.10 github.com/sirupsen/logrus v1.9.0 go.mongodb.org/mongo-driver v1.10.1 ) diff --git a/go.sum b/go.sum index e774f88..ec6e8f5 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.9 h1:0pEtHIqipAj62qnGjg+sFRNw8+iR9LXP1cmF2YLZ+Ac= -github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.9/go.mod h1:r815fYWTudnU9JhtsJAxUtuV7QrSgKpChJkfTSMFpfg= +github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.10 h1:4P297S3AZ8RsBrMPxJm+jpFCY8kx8KZPNZXp6ThDAbQ= +github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.10/go.mod h1:r815fYWTudnU9JhtsJAxUtuV7QrSgKpChJkfTSMFpfg= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/vendor/github.com/PaulSonOfLars/gotgbot/v2/.golangci.yaml b/vendor/github.com/PaulSonOfLars/gotgbot/v2/.golangci.yaml index 7e4c51a..876e740 100644 --- a/vendor/github.com/PaulSonOfLars/gotgbot/v2/.golangci.yaml +++ b/vendor/github.com/PaulSonOfLars/gotgbot/v2/.golangci.yaml @@ -56,7 +56,7 @@ linters: - gomoddirectives - goprintffuncname - gosec - - ifshort + # - ifshort - importas # - lll - makezero @@ -65,7 +65,7 @@ linters: # - nilassign - nilerr - noctx - - nolintlint + # - nolintlint # - paralleltest - prealloc - promlinter @@ -118,6 +118,5 @@ linters-settings: # use the struct field name to check the name of the struct tag use-field-name: true rules: - # any struct tag type can be used. - # support string case: `camel`, `pascal`, `kebab`, `snake`, `goCamel`, `goPascal`, `goKebab`, `goSnake`, `upper`, `lower` + # JSON must use snake case json: snake diff --git a/vendor/github.com/PaulSonOfLars/gotgbot/v2/bot.go b/vendor/github.com/PaulSonOfLars/gotgbot/v2/bot.go index 31a8da5..0ff3af3 100644 --- a/vendor/github.com/PaulSonOfLars/gotgbot/v2/bot.go +++ b/vendor/github.com/PaulSonOfLars/gotgbot/v2/bot.go @@ -26,6 +26,10 @@ type BotOpts struct { // token can be assumed to be valid (eg lambdas). // Warning: Disabling the token check will mean that the Bot.User struct will no longer be populated. DisableTokenCheck bool + // UseTestEnvironment defines whether this bot was created to run on telegram's test environment. + // Enabling this uses a slightly different API path. + // See https://core.telegram.org/bots/webapps#using-bots-in-the-test-environment for more details. + UseTestEnvironment bool // Request opts to use for checking token validity with Bot.GetMe. Can be slow - a high timeout (eg 10s) is // recommended. RequestOpts *RequestOpts @@ -50,6 +54,7 @@ func NewBot(token string, opts *BotOpts) (*Bot, error) { checkTokenValidity := true if opts != nil { botClient.Client = opts.Client + botClient.UseTestEnvironment = opts.UseTestEnvironment if opts.DefaultRequestOpts != nil { botClient.DefaultRequestOpts = opts.DefaultRequestOpts } @@ -84,7 +89,7 @@ func (bot *Bot) UseMiddleware(mw func(client BotClient) BotClient) *Bot { var ErrNilBotClient = errors.New("nil BotClient") -func (bot *Bot) Post(method string, params map[string]string, data map[string]NamedReader, opts *RequestOpts) (json.RawMessage, error) { +func (bot *Bot) Request(method string, params map[string]string, data map[string]NamedReader, opts *RequestOpts) (json.RawMessage, error) { if bot.BotClient == nil { return nil, ErrNilBotClient } @@ -92,5 +97,5 @@ func (bot *Bot) Post(method string, params map[string]string, data map[string]Na ctx, cancel := bot.BotClient.TimeoutContext(opts) defer cancel() - return bot.BotClient.PostWithContext(ctx, method, params, data, opts) + return bot.BotClient.RequestWithContext(ctx, method, params, data, opts) } diff --git a/vendor/github.com/PaulSonOfLars/gotgbot/v2/ext/handlers/message.go b/vendor/github.com/PaulSonOfLars/gotgbot/v2/ext/handlers/message.go index cada47f..2267d78 100644 --- a/vendor/github.com/PaulSonOfLars/gotgbot/v2/ext/handlers/message.go +++ b/vendor/github.com/PaulSonOfLars/gotgbot/v2/ext/handlers/message.go @@ -25,29 +25,23 @@ func NewMessage(f filters.Message, r Response) Message { } func (m Message) CheckUpdate(b *gotgbot.Bot, u *gotgbot.Update) bool { + // Normal incoming message in a group/private chat. if u.Message != nil { return m.Filter == nil || m.Filter(u.Message) } - // if no edits and message is edited + // If edits are allowed, and message is edited. if m.AllowEdited && u.EditedMessage != nil { - if u.EditedMessage.Text == "" && u.EditedMessage.Caption == "" { - return false - } return m.Filter == nil || m.Filter(u.EditedMessage) } - // if no channel and message is channel message + + // If channels are allowed, and message is a channel post. if m.AllowChannel && u.ChannelPost != nil { - if u.ChannelPost.Text == "" && u.ChannelPost.Caption == "" { - return false - } return m.Filter == nil || m.Filter(u.ChannelPost) } - // if no channel, no edits, and post is edited + + // If edits AND channels are allowed, and message is a channel post. if m.AllowChannel && m.AllowEdited && u.EditedChannelPost != nil { - if u.EditedChannelPost.Text == "" && u.EditedChannelPost.Caption == "" { - return false - } return m.Filter == nil || m.Filter(u.EditedChannelPost) } diff --git a/vendor/github.com/PaulSonOfLars/gotgbot/v2/ext/updater.go b/vendor/github.com/PaulSonOfLars/gotgbot/v2/ext/updater.go index 6035544..7a499bd 100644 --- a/vendor/github.com/PaulSonOfLars/gotgbot/v2/ext/updater.go +++ b/vendor/github.com/PaulSonOfLars/gotgbot/v2/ext/updater.go @@ -10,6 +10,7 @@ import ( "net/http" "os" "strconv" + "strings" "time" "github.com/PaulSonOfLars/gotgbot/v2" @@ -133,7 +134,7 @@ func (u *Updater) pollingLoop(b *gotgbot.Bot, opts *gotgbot.RequestOpts, dropPen // continue as usual } - r, err := b.Post("getUpdates", v, nil, opts) + r, err := b.Request("getUpdates", v, nil, opts) if err != nil { u.ErrorLog.Println("failed to get updates; sleeping 1s: " + err.Error()) time.Sleep(time.Second) @@ -237,13 +238,20 @@ func (u *Updater) StartWebhook(b *gotgbot.Bot, opts WebhookOpts) error { mux := http.NewServeMux() mux.HandleFunc("/"+opts.URLPath, func(w http.ResponseWriter, r *http.Request) { + if opts.SecretToken != "" && opts.SecretToken != r.Header.Get("X-Telegram-Bot-Api-Secret-Token") { + // Drop any updates from invalid secret tokens. + w.WriteHeader(http.StatusUnauthorized) + return + } bytes, _ := ioutil.ReadAll(r.Body) u.UpdateChan <- bytes }) u.server = &http.Server{ - Addr: opts.GetListenAddr(), - Handler: mux, + Addr: opts.GetListenAddr(), + Handler: mux, + ReadTimeout: opts.ReadTimeout, + ReadHeaderTimeout: opts.ReadHeaderTimeout, } go func() { @@ -261,13 +269,30 @@ func (u *Updater) StartWebhook(b *gotgbot.Bot, opts WebhookOpts) error { return nil } +// WebhookOpts represent various fields that are needed for configuring the local webhook server. type WebhookOpts struct { - Listen string - Port int + // Listen is the address to listen on (eg: localhost, 0.0.0.0, etc). + Listen string + // Port is the port listen on (eg 443, 8443, etc). + Port int + // URLPath defines the path to listen at; eg /. + // Using the bot token here is often a good idea, as it is a secret known only by telegram. URLPath string - + // ReadTimeout is passed to the http server to limit the time it takes to read an incoming request. + // See http.Server for more details. + ReadTimeout time.Duration + // ReadHeaderTimeout is passed to the http server to limit the time it takes to read the headers of an incoming + // request. + // See http.Server for more details. + ReadHeaderTimeout time.Duration + + // HTTPS cert and key files for custom signed certificates CertFile string KeyFile string + + // The secret token used in the Bot.SetWebhook call, which can be used to ensure that the request comes from a + // webhook set by you. + SecretToken string } // GetListenAddr returns the local listening address, including port. @@ -284,5 +309,5 @@ func (w *WebhookOpts) GetListenAddr() string { // GetWebhookURL returns the domain in the form domain/path. // eg: example.com/super_secret_token func (w *WebhookOpts) GetWebhookURL(domain string) string { - return fmt.Sprintf("%s/%s", domain, w.URLPath) + return fmt.Sprintf("%s/%s", strings.TrimSuffix(domain, "/"), w.URLPath) } diff --git a/vendor/github.com/PaulSonOfLars/gotgbot/v2/gen_methods.go b/vendor/github.com/PaulSonOfLars/gotgbot/v2/gen_methods.go index a75b916..af212d9 100644 --- a/vendor/github.com/PaulSonOfLars/gotgbot/v2/gen_methods.go +++ b/vendor/github.com/PaulSonOfLars/gotgbot/v2/gen_methods.go @@ -107,7 +107,7 @@ func (bot *Bot) AddStickerToSet(userId int64, name string, emojis string, opts * reqOpts = opts.RequestOpts } - r, err := bot.Post("addStickerToSet", v, data, reqOpts) + r, err := bot.Request("addStickerToSet", v, data, reqOpts) if err != nil { return false, err } @@ -151,7 +151,7 @@ func (bot *Bot) AnswerCallbackQuery(callbackQueryId string, opts *AnswerCallback reqOpts = opts.RequestOpts } - r, err := bot.Post("answerCallbackQuery", v, nil, reqOpts) + r, err := bot.Request("answerCallbackQuery", v, nil, reqOpts) if err != nil { return false, err } @@ -164,7 +164,7 @@ func (bot *Bot) AnswerCallbackQuery(callbackQueryId string, opts *AnswerCallback type AnswerInlineQueryOpts struct { // The maximum amount of time in seconds that the result of the inline query may be cached on the server. Defaults to 300. CacheTime int64 - // Pass True, if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query + // Pass True if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query IsPersonal bool // Pass the offset that a client should send in the next query with the same text to receive more results. Pass an empty string if there are no more results or if you don't support pagination. Offset length can't exceed 64 bytes. NextOffset string @@ -207,7 +207,7 @@ func (bot *Bot) AnswerInlineQuery(inlineQueryId string, results []InlineQueryRes reqOpts = opts.RequestOpts } - r, err := bot.Post("answerInlineQuery", v, nil, reqOpts) + r, err := bot.Request("answerInlineQuery", v, nil, reqOpts) if err != nil { return false, err } @@ -242,7 +242,7 @@ func (bot *Bot) AnswerPreCheckoutQuery(preCheckoutQueryId string, ok bool, opts reqOpts = opts.RequestOpts } - r, err := bot.Post("answerPreCheckoutQuery", v, nil, reqOpts) + r, err := bot.Request("answerPreCheckoutQuery", v, nil, reqOpts) if err != nil { return false, err } @@ -263,7 +263,7 @@ type AnswerShippingQueryOpts struct { // AnswerShippingQuery If you sent an invoice requesting a shipping address and the parameter is_flexible was specified, the Bot API will send an Update with a shipping_query field to the bot. Use this method to reply to shipping queries. On success, True is returned. // - shippingQueryId (type string): Unique identifier for the query to be answered -// - ok (type bool): Specify True if delivery to the specified address is possible and False if there are any problems (for example, if delivery to the specified address is not possible) +// - ok (type bool): Pass True if delivery to the specified address is possible and False if there are any problems (for example, if delivery to the specified address is not possible) // - opts (type AnswerShippingQueryOpts): All optional parameters. // https://core.telegram.org/bots/api#answershippingquery func (bot *Bot) AnswerShippingQuery(shippingQueryId string, ok bool, opts *AnswerShippingQueryOpts) (bool, error) { @@ -286,7 +286,7 @@ func (bot *Bot) AnswerShippingQuery(shippingQueryId string, ok bool, opts *Answe reqOpts = opts.RequestOpts } - r, err := bot.Post("answerShippingQuery", v, nil, reqOpts) + r, err := bot.Request("answerShippingQuery", v, nil, reqOpts) if err != nil { return false, err } @@ -319,7 +319,7 @@ func (bot *Bot) AnswerWebAppQuery(webAppQueryId string, result InlineQueryResult reqOpts = opts.RequestOpts } - r, err := bot.Post("answerWebAppQuery", v, nil, reqOpts) + r, err := bot.Request("answerWebAppQuery", v, nil, reqOpts) if err != nil { return nil, err } @@ -348,7 +348,7 @@ func (bot *Bot) ApproveChatJoinRequest(chatId int64, userId int64, opts *Approve reqOpts = opts.RequestOpts } - r, err := bot.Post("approveChatJoinRequest", v, nil, reqOpts) + r, err := bot.Request("approveChatJoinRequest", v, nil, reqOpts) if err != nil { return false, err } @@ -388,7 +388,7 @@ func (bot *Bot) BanChatMember(chatId int64, userId int64, opts *BanChatMemberOpt reqOpts = opts.RequestOpts } - r, err := bot.Post("banChatMember", v, nil, reqOpts) + r, err := bot.Request("banChatMember", v, nil, reqOpts) if err != nil { return false, err } @@ -417,7 +417,7 @@ func (bot *Bot) BanChatSenderChat(chatId int64, senderChatId int64, opts *BanCha reqOpts = opts.RequestOpts } - r, err := bot.Post("banChatSenderChat", v, nil, reqOpts) + r, err := bot.Request("banChatSenderChat", v, nil, reqOpts) if err != nil { return false, err } @@ -442,7 +442,7 @@ func (bot *Bot) Close(opts *CloseOpts) (bool, error) { reqOpts = opts.RequestOpts } - r, err := bot.Post("close", v, nil, reqOpts) + r, err := bot.Request("close", v, nil, reqOpts) if err != nil { return false, err } @@ -465,7 +465,7 @@ type CopyMessageOpts struct { ProtectContent bool // If the message is a reply, ID of the original message ReplyToMessageId int64 - // Pass True, if the message should be sent even if the specified replied-to message is not found + // Pass True if the message should be sent even if the specified replied-to message is not found AllowSendingWithoutReply bool // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. ReplyMarkup ReplyMarkup @@ -473,7 +473,7 @@ type CopyMessageOpts struct { RequestOpts *RequestOpts } -// CopyMessage Use this method to copy messages of any kind. Service messages and invoice messages can't be copied. The method is analogous to the method forwardMessage, but the copied message doesn't have a link to the original message. Returns the MessageId of the sent message on success. +// CopyMessage Use this method to copy messages of any kind. Service messages and invoice messages can't be copied. A quiz poll can be copied only if the value of the field correct_option_id is known to the bot. The method is analogous to the method forwardMessage, but the copied message doesn't have a link to the original message. Returns the MessageId of the sent message on success. // - chatId (type int64): Unique identifier for the target chat or username of the target channel (in the format @channelusername) // - fromChatId (type int64): Unique identifier for the chat where the original message was sent (or channel username in the format @channelusername) // - messageId (type int64): Message identifier in the chat specified in from_chat_id @@ -514,7 +514,7 @@ func (bot *Bot) CopyMessage(chatId int64, fromChatId int64, messageId int64, opt reqOpts = opts.RequestOpts } - r, err := bot.Post("copyMessage", v, nil, reqOpts) + r, err := bot.Request("copyMessage", v, nil, reqOpts) if err != nil { return nil, err } @@ -560,7 +560,7 @@ func (bot *Bot) CreateChatInviteLink(chatId int64, opts *CreateChatInviteLinkOpt reqOpts = opts.RequestOpts } - r, err := bot.Post("createChatInviteLink", v, nil, reqOpts) + r, err := bot.Request("createChatInviteLink", v, nil, reqOpts) if err != nil { return nil, err } @@ -585,19 +585,19 @@ type CreateInvoiceLinkOpts struct { PhotoWidth int64 // Photo height PhotoHeight int64 - // Pass True, if you require the user's full name to complete the order + // Pass True if you require the user's full name to complete the order NeedName bool - // Pass True, if you require the user's phone number to complete the order + // Pass True if you require the user's phone number to complete the order NeedPhoneNumber bool - // Pass True, if you require the user's email address to complete the order + // Pass True if you require the user's email address to complete the order NeedEmail bool - // Pass True, if you require the user's shipping address to complete the order + // Pass True if you require the user's shipping address to complete the order NeedShippingAddress bool - // Pass True, if the user's phone number should be sent to the provider + // Pass True if the user's phone number should be sent to the provider SendPhoneNumberToProvider bool - // Pass True, if the user's email address should be sent to the provider + // Pass True if the user's email address should be sent to the provider SendEmailToProvider bool - // Pass True, if the final price depends on the shipping method + // Pass True if the final price depends on the shipping method IsFlexible bool // RequestOpts are an additional optional field to configure timeouts for individual requests RequestOpts *RequestOpts @@ -662,7 +662,7 @@ func (bot *Bot) CreateInvoiceLink(title string, description string, payload stri reqOpts = opts.RequestOpts } - r, err := bot.Post("createInvoiceLink", v, nil, reqOpts) + r, err := bot.Request("createInvoiceLink", v, nil, reqOpts) if err != nil { return "", err } @@ -679,8 +679,8 @@ type CreateNewStickerSetOpts struct { TgsSticker InputFile // WEBM video with the sticker, uploaded using multipart/form-data. See https://core.telegram.org/stickers#video-sticker-requirements for technical requirements WebmSticker InputFile - // Pass True, if a set of mask stickers should be created - ContainsMasks bool + // Type of stickers in the set, pass "regular" or "mask". Custom emoji sticker sets can't be created via the Bot API at the moment. By default, a regular sticker set is created. + StickerType string // A JSON-serialized object for position where the mask should be placed on faces MaskPosition MaskPosition // RequestOpts are an additional optional field to configure timeouts for individual requests @@ -759,7 +759,7 @@ func (bot *Bot) CreateNewStickerSet(userId int64, name string, title string, emo return false, fmt.Errorf("unknown type for InputFile: %T", opts.WebmSticker) } } - v["contains_masks"] = strconv.FormatBool(opts.ContainsMasks) + v["sticker_type"] = opts.StickerType bs, err := json.Marshal(opts.MaskPosition) if err != nil { return false, fmt.Errorf("failed to marshal field mask_position: %w", err) @@ -772,7 +772,7 @@ func (bot *Bot) CreateNewStickerSet(userId int64, name string, title string, emo reqOpts = opts.RequestOpts } - r, err := bot.Post("createNewStickerSet", v, data, reqOpts) + r, err := bot.Request("createNewStickerSet", v, data, reqOpts) if err != nil { return false, err } @@ -801,7 +801,7 @@ func (bot *Bot) DeclineChatJoinRequest(chatId int64, userId int64, opts *Decline reqOpts = opts.RequestOpts } - r, err := bot.Post("declineChatJoinRequest", v, nil, reqOpts) + r, err := bot.Request("declineChatJoinRequest", v, nil, reqOpts) if err != nil { return false, err } @@ -828,7 +828,7 @@ func (bot *Bot) DeleteChatPhoto(chatId int64, opts *DeleteChatPhotoOpts) (bool, reqOpts = opts.RequestOpts } - r, err := bot.Post("deleteChatPhoto", v, nil, reqOpts) + r, err := bot.Request("deleteChatPhoto", v, nil, reqOpts) if err != nil { return false, err } @@ -855,7 +855,7 @@ func (bot *Bot) DeleteChatStickerSet(chatId int64, opts *DeleteChatStickerSetOpt reqOpts = opts.RequestOpts } - r, err := bot.Post("deleteChatStickerSet", v, nil, reqOpts) + r, err := bot.Request("deleteChatStickerSet", v, nil, reqOpts) if err != nil { return false, err } @@ -892,7 +892,7 @@ func (bot *Bot) DeleteMessage(chatId int64, messageId int64, opts *DeleteMessage reqOpts = opts.RequestOpts } - r, err := bot.Post("deleteMessage", v, nil, reqOpts) + r, err := bot.Request("deleteMessage", v, nil, reqOpts) if err != nil { return false, err } @@ -930,7 +930,7 @@ func (bot *Bot) DeleteMyCommands(opts *DeleteMyCommandsOpts) (bool, error) { reqOpts = opts.RequestOpts } - r, err := bot.Post("deleteMyCommands", v, nil, reqOpts) + r, err := bot.Request("deleteMyCommands", v, nil, reqOpts) if err != nil { return false, err } @@ -957,7 +957,7 @@ func (bot *Bot) DeleteStickerFromSet(sticker string, opts *DeleteStickerFromSetO reqOpts = opts.RequestOpts } - r, err := bot.Post("deleteStickerFromSet", v, nil, reqOpts) + r, err := bot.Request("deleteStickerFromSet", v, nil, reqOpts) if err != nil { return false, err } @@ -988,7 +988,7 @@ func (bot *Bot) DeleteWebhook(opts *DeleteWebhookOpts) (bool, error) { reqOpts = opts.RequestOpts } - r, err := bot.Post("deleteWebhook", v, nil, reqOpts) + r, err := bot.Request("deleteWebhook", v, nil, reqOpts) if err != nil { return false, err } @@ -1036,7 +1036,7 @@ func (bot *Bot) EditChatInviteLink(chatId int64, inviteLink string, opts *EditCh reqOpts = opts.RequestOpts } - r, err := bot.Post("editChatInviteLink", v, nil, reqOpts) + r, err := bot.Request("editChatInviteLink", v, nil, reqOpts) if err != nil { return nil, err } @@ -1099,7 +1099,7 @@ func (bot *Bot) EditMessageCaption(opts *EditMessageCaptionOpts) (*Message, bool reqOpts = opts.RequestOpts } - r, err := bot.Post("editMessageCaption", v, nil, reqOpts) + r, err := bot.Request("editMessageCaption", v, nil, reqOpts) if err != nil { return nil, false, err } @@ -1174,7 +1174,7 @@ func (bot *Bot) EditMessageLiveLocation(latitude float64, longitude float64, opt reqOpts = opts.RequestOpts } - r, err := bot.Post("editMessageLiveLocation", v, nil, reqOpts) + r, err := bot.Request("editMessageLiveLocation", v, nil, reqOpts) if err != nil { return nil, false, err } @@ -1237,7 +1237,7 @@ func (bot *Bot) EditMessageMedia(media InputMedia, opts *EditMessageMediaOpts) ( reqOpts = opts.RequestOpts } - r, err := bot.Post("editMessageMedia", v, data, reqOpts) + r, err := bot.Request("editMessageMedia", v, data, reqOpts) if err != nil { return nil, false, err } @@ -1293,7 +1293,7 @@ func (bot *Bot) EditMessageReplyMarkup(opts *EditMessageReplyMarkupOpts) (*Messa reqOpts = opts.RequestOpts } - r, err := bot.Post("editMessageReplyMarkup", v, nil, reqOpts) + r, err := bot.Request("editMessageReplyMarkup", v, nil, reqOpts) if err != nil { return nil, false, err } @@ -1366,7 +1366,7 @@ func (bot *Bot) EditMessageText(text string, opts *EditMessageTextOpts) (*Messag reqOpts = opts.RequestOpts } - r, err := bot.Post("editMessageText", v, nil, reqOpts) + r, err := bot.Request("editMessageText", v, nil, reqOpts) if err != nil { return nil, false, err } @@ -1401,7 +1401,7 @@ func (bot *Bot) ExportChatInviteLink(chatId int64, opts *ExportChatInviteLinkOpt reqOpts = opts.RequestOpts } - r, err := bot.Post("exportChatInviteLink", v, nil, reqOpts) + r, err := bot.Request("exportChatInviteLink", v, nil, reqOpts) if err != nil { return "", err } @@ -1441,7 +1441,7 @@ func (bot *Bot) ForwardMessage(chatId int64, fromChatId int64, messageId int64, reqOpts = opts.RequestOpts } - r, err := bot.Post("forwardMessage", v, nil, reqOpts) + r, err := bot.Request("forwardMessage", v, nil, reqOpts) if err != nil { return nil, err } @@ -1468,7 +1468,7 @@ func (bot *Bot) GetChat(chatId int64, opts *GetChatOpts) (*Chat, error) { reqOpts = opts.RequestOpts } - r, err := bot.Post("getChat", v, nil, reqOpts) + r, err := bot.Request("getChat", v, nil, reqOpts) if err != nil { return nil, err } @@ -1483,7 +1483,7 @@ type GetChatAdministratorsOpts struct { RequestOpts *RequestOpts } -// GetChatAdministrators Use this method to get a list of administrators in a chat. On success, returns an Array of ChatMember objects that contains information about all chat administrators except other bots. If the chat is a group or a supergroup and no administrators were appointed, only the creator will be returned. +// GetChatAdministrators Use this method to get a list of administrators in a chat, which aren't bots. Returns an Array of ChatMember objects. // - chatId (type int64): Unique identifier for the target chat or username of the target supergroup or channel (in the format @channelusername) // https://core.telegram.org/bots/api#getchatadministrators func (bot *Bot) GetChatAdministrators(chatId int64, opts *GetChatAdministratorsOpts) ([]ChatMember, error) { @@ -1495,7 +1495,7 @@ func (bot *Bot) GetChatAdministrators(chatId int64, opts *GetChatAdministratorsO reqOpts = opts.RequestOpts } - r, err := bot.Post("getChatAdministrators", v, nil, reqOpts) + r, err := bot.Request("getChatAdministrators", v, nil, reqOpts) if err != nil { return nil, err } @@ -1523,7 +1523,7 @@ func (bot *Bot) GetChatMember(chatId int64, userId int64, opts *GetChatMemberOpt reqOpts = opts.RequestOpts } - r, err := bot.Post("getChatMember", v, nil, reqOpts) + r, err := bot.Request("getChatMember", v, nil, reqOpts) if err != nil { return nil, err } @@ -1549,7 +1549,7 @@ func (bot *Bot) GetChatMemberCount(chatId int64, opts *GetChatMemberCountOpts) ( reqOpts = opts.RequestOpts } - r, err := bot.Post("getChatMemberCount", v, nil, reqOpts) + r, err := bot.Request("getChatMemberCount", v, nil, reqOpts) if err != nil { return 0, err } @@ -1582,7 +1582,7 @@ func (bot *Bot) GetChatMenuButton(opts *GetChatMenuButtonOpts) (MenuButton, erro reqOpts = opts.RequestOpts } - r, err := bot.Post("getChatMenuButton", v, nil, reqOpts) + r, err := bot.Request("getChatMenuButton", v, nil, reqOpts) if err != nil { return nil, err } @@ -1590,6 +1590,39 @@ func (bot *Bot) GetChatMenuButton(opts *GetChatMenuButtonOpts) (MenuButton, erro return unmarshalMenuButton(r) } +// GetCustomEmojiStickersOpts is the set of optional fields for Bot.GetCustomEmojiStickers. +type GetCustomEmojiStickersOpts struct { + // RequestOpts are an additional optional field to configure timeouts for individual requests + RequestOpts *RequestOpts +} + +// GetCustomEmojiStickers Use this method to get information about custom emoji stickers by their identifiers. Returns an Array of Sticker objects. +// - customEmojiIds (type []string): List of custom emoji identifiers. At most 200 custom emoji identifiers can be specified. +// https://core.telegram.org/bots/api#getcustomemojistickers +func (bot *Bot) GetCustomEmojiStickers(customEmojiIds []string, opts *GetCustomEmojiStickersOpts) ([]Sticker, error) { + v := map[string]string{} + if customEmojiIds != nil { + bs, err := json.Marshal(customEmojiIds) + if err != nil { + return nil, fmt.Errorf("failed to marshal field custom_emoji_ids: %w", err) + } + v["custom_emoji_ids"] = string(bs) + } + + var reqOpts *RequestOpts + if opts != nil { + reqOpts = opts.RequestOpts + } + + r, err := bot.Request("getCustomEmojiStickers", v, nil, reqOpts) + if err != nil { + return nil, err + } + + var s []Sticker + return s, json.Unmarshal(r, &s) +} + // GetFileOpts is the set of optional fields for Bot.GetFile. type GetFileOpts struct { // RequestOpts are an additional optional field to configure timeouts for individual requests @@ -1609,7 +1642,7 @@ func (bot *Bot) GetFile(fileId string, opts *GetFileOpts) (*File, error) { reqOpts = opts.RequestOpts } - r, err := bot.Post("getFile", v, nil, reqOpts) + r, err := bot.Request("getFile", v, nil, reqOpts) if err != nil { return nil, err } @@ -1630,7 +1663,7 @@ type GetGameHighScoresOpts struct { RequestOpts *RequestOpts } -// GetGameHighScores Use this method to get data for high score tables. Will return the score of the specified user and several of their neighbors in a game. On success, returns an Array of GameHighScore objects. +// GetGameHighScores Use this method to get data for high score tables. Will return the score of the specified user and several of their neighbors in a game. Returns an Array of GameHighScore objects. // - userId (type int64): Target user id // - opts (type GetGameHighScoresOpts): All optional parameters. // https://core.telegram.org/bots/api#getgamehighscores @@ -1652,7 +1685,7 @@ func (bot *Bot) GetGameHighScores(userId int64, opts *GetGameHighScoresOpts) ([] reqOpts = opts.RequestOpts } - r, err := bot.Post("getGameHighScores", v, nil, reqOpts) + r, err := bot.Request("getGameHighScores", v, nil, reqOpts) if err != nil { return nil, err } @@ -1677,7 +1710,7 @@ func (bot *Bot) GetMe(opts *GetMeOpts) (*User, error) { reqOpts = opts.RequestOpts } - r, err := bot.Post("getMe", v, nil, reqOpts) + r, err := bot.Request("getMe", v, nil, reqOpts) if err != nil { return nil, err } @@ -1696,7 +1729,7 @@ type GetMyCommandsOpts struct { RequestOpts *RequestOpts } -// GetMyCommands Use this method to get the current list of the bot's commands for the given scope and user language. Returns Array of BotCommand on success. If commands aren't set, an empty list is returned. +// GetMyCommands Use this method to get the current list of the bot's commands for the given scope and user language. Returns an Array of BotCommand objects. If commands aren't set, an empty list is returned. // - opts (type GetMyCommandsOpts): All optional parameters. // https://core.telegram.org/bots/api#getmycommands func (bot *Bot) GetMyCommands(opts *GetMyCommandsOpts) ([]BotCommand, error) { @@ -1715,7 +1748,7 @@ func (bot *Bot) GetMyCommands(opts *GetMyCommandsOpts) ([]BotCommand, error) { reqOpts = opts.RequestOpts } - r, err := bot.Post("getMyCommands", v, nil, reqOpts) + r, err := bot.Request("getMyCommands", v, nil, reqOpts) if err != nil { return nil, err } @@ -1746,7 +1779,7 @@ func (bot *Bot) GetMyDefaultAdministratorRights(opts *GetMyDefaultAdministratorR reqOpts = opts.RequestOpts } - r, err := bot.Post("getMyDefaultAdministratorRights", v, nil, reqOpts) + r, err := bot.Request("getMyDefaultAdministratorRights", v, nil, reqOpts) if err != nil { return nil, err } @@ -1773,7 +1806,7 @@ func (bot *Bot) GetStickerSet(name string, opts *GetStickerSetOpts) (*StickerSet reqOpts = opts.RequestOpts } - r, err := bot.Post("getStickerSet", v, nil, reqOpts) + r, err := bot.Request("getStickerSet", v, nil, reqOpts) if err != nil { return nil, err } @@ -1796,7 +1829,7 @@ type GetUpdatesOpts struct { RequestOpts *RequestOpts } -// GetUpdates Use this method to receive incoming updates using long polling (wiki). An Array of Update objects is returned. +// GetUpdates Use this method to receive incoming updates using long polling (wiki). Returns an Array of Update objects. // - opts (type GetUpdatesOpts): All optional parameters. // https://core.telegram.org/bots/api#getupdates func (bot *Bot) GetUpdates(opts *GetUpdatesOpts) ([]Update, error) { @@ -1825,7 +1858,7 @@ func (bot *Bot) GetUpdates(opts *GetUpdatesOpts) ([]Update, error) { reqOpts = opts.RequestOpts } - r, err := bot.Post("getUpdates", v, nil, reqOpts) + r, err := bot.Request("getUpdates", v, nil, reqOpts) if err != nil { return nil, err } @@ -1865,7 +1898,7 @@ func (bot *Bot) GetUserProfilePhotos(userId int64, opts *GetUserProfilePhotosOpt reqOpts = opts.RequestOpts } - r, err := bot.Post("getUserProfilePhotos", v, nil, reqOpts) + r, err := bot.Request("getUserProfilePhotos", v, nil, reqOpts) if err != nil { return nil, err } @@ -1890,7 +1923,7 @@ func (bot *Bot) GetWebhookInfo(opts *GetWebhookInfoOpts) (*WebhookInfo, error) { reqOpts = opts.RequestOpts } - r, err := bot.Post("getWebhookInfo", v, nil, reqOpts) + r, err := bot.Request("getWebhookInfo", v, nil, reqOpts) if err != nil { return nil, err } @@ -1917,7 +1950,7 @@ func (bot *Bot) LeaveChat(chatId int64, opts *LeaveChatOpts) (bool, error) { reqOpts = opts.RequestOpts } - r, err := bot.Post("leaveChat", v, nil, reqOpts) + r, err := bot.Request("leaveChat", v, nil, reqOpts) if err != nil { return false, err } @@ -1942,7 +1975,7 @@ func (bot *Bot) LogOut(opts *LogOutOpts) (bool, error) { reqOpts = opts.RequestOpts } - r, err := bot.Post("logOut", v, nil, reqOpts) + r, err := bot.Request("logOut", v, nil, reqOpts) if err != nil { return false, err } @@ -1953,7 +1986,7 @@ func (bot *Bot) LogOut(opts *LogOutOpts) (bool, error) { // PinChatMessageOpts is the set of optional fields for Bot.PinChatMessage. type PinChatMessageOpts struct { - // Pass True, if it is not necessary to send a notification to all chat members about the new pinned message. Notifications are always disabled in channels and private chats. + // Pass True if it is not necessary to send a notification to all chat members about the new pinned message. Notifications are always disabled in channels and private chats. DisableNotification bool // RequestOpts are an additional optional field to configure timeouts for individual requests RequestOpts *RequestOpts @@ -1977,7 +2010,7 @@ func (bot *Bot) PinChatMessage(chatId int64, messageId int64, opts *PinChatMessa reqOpts = opts.RequestOpts } - r, err := bot.Post("pinChatMessage", v, nil, reqOpts) + r, err := bot.Request("pinChatMessage", v, nil, reqOpts) if err != nil { return false, err } @@ -1988,27 +2021,27 @@ func (bot *Bot) PinChatMessage(chatId int64, messageId int64, opts *PinChatMessa // PromoteChatMemberOpts is the set of optional fields for Bot.PromoteChatMember. type PromoteChatMemberOpts struct { - // Pass True, if the administrator's presence in the chat is hidden + // Pass True if the administrator's presence in the chat is hidden IsAnonymous bool - // Pass True, if the administrator can access the chat event log, chat statistics, message statistics in channels, see channel members, see anonymous administrators in supergroups and ignore slow mode. Implied by any other administrator privilege + // Pass True if the administrator can access the chat event log, chat statistics, message statistics in channels, see channel members, see anonymous administrators in supergroups and ignore slow mode. Implied by any other administrator privilege CanManageChat bool - // Pass True, if the administrator can create channel posts, channels only + // Pass True if the administrator can create channel posts, channels only CanPostMessages bool - // Pass True, if the administrator can edit messages of other users and can pin messages, channels only + // Pass True if the administrator can edit messages of other users and can pin messages, channels only CanEditMessages bool - // Pass True, if the administrator can delete messages of other users + // Pass True if the administrator can delete messages of other users CanDeleteMessages bool - // Pass True, if the administrator can manage video chats + // Pass True if the administrator can manage video chats CanManageVideoChats bool - // Pass True, if the administrator can restrict, ban or unban chat members + // Pass True if the administrator can restrict, ban or unban chat members CanRestrictMembers bool - // Pass True, if the administrator can add new administrators with a subset of their own privileges or demote administrators that he has promoted, directly or indirectly (promoted by administrators that were appointed by him) + // Pass True if the administrator can add new administrators with a subset of their own privileges or demote administrators that he has promoted, directly or indirectly (promoted by administrators that were appointed by him) CanPromoteMembers bool - // Pass True, if the administrator can change chat title, photo and other settings + // Pass True if the administrator can change chat title, photo and other settings CanChangeInfo bool - // Pass True, if the administrator can invite new users to the chat + // Pass True if the administrator can invite new users to the chat CanInviteUsers bool - // Pass True, if the administrator can pin messages, supergroups only + // Pass True if the administrator can pin messages, supergroups only CanPinMessages bool // RequestOpts are an additional optional field to configure timeouts for individual requests RequestOpts *RequestOpts @@ -2042,7 +2075,7 @@ func (bot *Bot) PromoteChatMember(chatId int64, userId int64, opts *PromoteChatM reqOpts = opts.RequestOpts } - r, err := bot.Post("promoteChatMember", v, nil, reqOpts) + r, err := bot.Request("promoteChatMember", v, nil, reqOpts) if err != nil { return false, err } @@ -2085,7 +2118,7 @@ func (bot *Bot) RestrictChatMember(chatId int64, userId int64, permissions ChatP reqOpts = opts.RequestOpts } - r, err := bot.Post("restrictChatMember", v, nil, reqOpts) + r, err := bot.Request("restrictChatMember", v, nil, reqOpts) if err != nil { return false, err } @@ -2114,7 +2147,7 @@ func (bot *Bot) RevokeChatInviteLink(chatId int64, inviteLink string, opts *Revo reqOpts = opts.RequestOpts } - r, err := bot.Post("revokeChatInviteLink", v, nil, reqOpts) + r, err := bot.Request("revokeChatInviteLink", v, nil, reqOpts) if err != nil { return nil, err } @@ -2145,7 +2178,7 @@ type SendAnimationOpts struct { ProtectContent bool // If the message is a reply, ID of the original message ReplyToMessageId int64 - // Pass True, if the message should be sent even if the specified replied-to message is not found + // Pass True if the message should be sent even if the specified replied-to message is not found AllowSendingWithoutReply bool // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. ReplyMarkup ReplyMarkup @@ -2243,7 +2276,7 @@ func (bot *Bot) SendAnimation(chatId int64, animation InputFile, opts *SendAnima reqOpts = opts.RequestOpts } - r, err := bot.Post("sendAnimation", v, data, reqOpts) + r, err := bot.Request("sendAnimation", v, data, reqOpts) if err != nil { return nil, err } @@ -2274,7 +2307,7 @@ type SendAudioOpts struct { ProtectContent bool // If the message is a reply, ID of the original message ReplyToMessageId int64 - // Pass True, if the message should be sent even if the specified replied-to message is not found + // Pass True if the message should be sent even if the specified replied-to message is not found AllowSendingWithoutReply bool // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. ReplyMarkup ReplyMarkup @@ -2369,7 +2402,7 @@ func (bot *Bot) SendAudio(chatId int64, audio InputFile, opts *SendAudioOpts) (* reqOpts = opts.RequestOpts } - r, err := bot.Post("sendAudio", v, data, reqOpts) + r, err := bot.Request("sendAudio", v, data, reqOpts) if err != nil { return nil, err } @@ -2399,7 +2432,7 @@ func (bot *Bot) SendChatAction(chatId int64, action string, opts *SendChatAction reqOpts = opts.RequestOpts } - r, err := bot.Post("sendChatAction", v, nil, reqOpts) + r, err := bot.Request("sendChatAction", v, nil, reqOpts) if err != nil { return false, err } @@ -2420,7 +2453,7 @@ type SendContactOpts struct { ProtectContent bool // If the message is a reply, ID of the original message ReplyToMessageId int64 - // Pass True, if the message should be sent even if the specified replied-to message is not found + // Pass True if the message should be sent even if the specified replied-to message is not found AllowSendingWithoutReply bool // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove keyboard or to force a reply from the user. ReplyMarkup ReplyMarkup @@ -2462,7 +2495,7 @@ func (bot *Bot) SendContact(chatId int64, phoneNumber string, firstName string, reqOpts = opts.RequestOpts } - r, err := bot.Post("sendContact", v, nil, reqOpts) + r, err := bot.Request("sendContact", v, nil, reqOpts) if err != nil { return nil, err } @@ -2481,7 +2514,7 @@ type SendDiceOpts struct { ProtectContent bool // If the message is a reply, ID of the original message ReplyToMessageId int64 - // Pass True, if the message should be sent even if the specified replied-to message is not found + // Pass True if the message should be sent even if the specified replied-to message is not found AllowSendingWithoutReply bool // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. ReplyMarkup ReplyMarkup @@ -2518,7 +2551,7 @@ func (bot *Bot) SendDice(chatId int64, opts *SendDiceOpts) (*Message, error) { reqOpts = opts.RequestOpts } - r, err := bot.Post("sendDice", v, nil, reqOpts) + r, err := bot.Request("sendDice", v, nil, reqOpts) if err != nil { return nil, err } @@ -2545,7 +2578,7 @@ type SendDocumentOpts struct { ProtectContent bool // If the message is a reply, ID of the original message ReplyToMessageId int64 - // Pass True, if the message should be sent even if the specified replied-to message is not found + // Pass True if the message should be sent even if the specified replied-to message is not found AllowSendingWithoutReply bool // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. ReplyMarkup ReplyMarkup @@ -2635,7 +2668,7 @@ func (bot *Bot) SendDocument(chatId int64, document InputFile, opts *SendDocumen reqOpts = opts.RequestOpts } - r, err := bot.Post("sendDocument", v, data, reqOpts) + r, err := bot.Request("sendDocument", v, data, reqOpts) if err != nil { return nil, err } @@ -2652,7 +2685,7 @@ type SendGameOpts struct { ProtectContent bool // If the message is a reply, ID of the original message ReplyToMessageId int64 - // Pass True, if the message should be sent even if the specified replied-to message is not found + // Pass True if the message should be sent even if the specified replied-to message is not found AllowSendingWithoutReply bool // A JSON-serialized object for an inline keyboard. If empty, one 'Play game_title' button will be shown. If not empty, the first button must launch the game. ReplyMarkup InlineKeyboardMarkup @@ -2688,7 +2721,7 @@ func (bot *Bot) SendGame(chatId int64, gameShortName string, opts *SendGameOpts) reqOpts = opts.RequestOpts } - r, err := bot.Post("sendGame", v, nil, reqOpts) + r, err := bot.Request("sendGame", v, nil, reqOpts) if err != nil { return nil, err } @@ -2715,19 +2748,19 @@ type SendInvoiceOpts struct { PhotoWidth int64 // Photo height PhotoHeight int64 - // Pass True, if you require the user's full name to complete the order + // Pass True if you require the user's full name to complete the order NeedName bool - // Pass True, if you require the user's phone number to complete the order + // Pass True if you require the user's phone number to complete the order NeedPhoneNumber bool - // Pass True, if you require the user's email address to complete the order + // Pass True if you require the user's email address to complete the order NeedEmail bool - // Pass True, if you require the user's shipping address to complete the order + // Pass True if you require the user's shipping address to complete the order NeedShippingAddress bool - // Pass True, if the user's phone number should be sent to provider + // Pass True if the user's phone number should be sent to provider SendPhoneNumberToProvider bool - // Pass True, if the user's email address should be sent to provider + // Pass True if the user's email address should be sent to provider SendEmailToProvider bool - // Pass True, if the final price depends on the shipping method + // Pass True if the final price depends on the shipping method IsFlexible bool // Sends the message silently. Users will receive a notification with no sound. DisableNotification bool @@ -2735,7 +2768,7 @@ type SendInvoiceOpts struct { ProtectContent bool // If the message is a reply, ID of the original message ReplyToMessageId int64 - // Pass True, if the message should be sent even if the specified replied-to message is not found + // Pass True if the message should be sent even if the specified replied-to message is not found AllowSendingWithoutReply bool // A JSON-serialized object for an inline keyboard. If empty, one 'Pay total price' button will be shown. If not empty, the first button must be a Pay button. ReplyMarkup InlineKeyboardMarkup @@ -2816,7 +2849,7 @@ func (bot *Bot) SendInvoice(chatId int64, title string, description string, payl reqOpts = opts.RequestOpts } - r, err := bot.Post("sendInvoice", v, nil, reqOpts) + r, err := bot.Request("sendInvoice", v, nil, reqOpts) if err != nil { return nil, err } @@ -2841,7 +2874,7 @@ type SendLocationOpts struct { ProtectContent bool // If the message is a reply, ID of the original message ReplyToMessageId int64 - // Pass True, if the message should be sent even if the specified replied-to message is not found + // Pass True if the message should be sent even if the specified replied-to message is not found AllowSendingWithoutReply bool // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. ReplyMarkup ReplyMarkup @@ -2893,7 +2926,7 @@ func (bot *Bot) SendLocation(chatId int64, latitude float64, longitude float64, reqOpts = opts.RequestOpts } - r, err := bot.Post("sendLocation", v, nil, reqOpts) + r, err := bot.Request("sendLocation", v, nil, reqOpts) if err != nil { return nil, err } @@ -2910,7 +2943,7 @@ type SendMediaGroupOpts struct { ProtectContent bool // If the messages are a reply, ID of the original message ReplyToMessageId int64 - // Pass True, if the message should be sent even if the specified replied-to message is not found + // Pass True if the message should be sent even if the specified replied-to message is not found AllowSendingWithoutReply bool // RequestOpts are an additional optional field to configure timeouts for individual requests RequestOpts *RequestOpts @@ -2954,7 +2987,7 @@ func (bot *Bot) SendMediaGroup(chatId int64, media []InputMedia, opts *SendMedia reqOpts = opts.RequestOpts } - r, err := bot.Post("sendMediaGroup", v, data, reqOpts) + r, err := bot.Request("sendMediaGroup", v, data, reqOpts) if err != nil { return nil, err } @@ -2977,7 +3010,7 @@ type SendMessageOpts struct { ProtectContent bool // If the message is a reply, ID of the original message ReplyToMessageId int64 - // Pass True, if the message should be sent even if the specified replied-to message is not found + // Pass True if the message should be sent even if the specified replied-to message is not found AllowSendingWithoutReply bool // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. ReplyMarkup ReplyMarkup @@ -3024,7 +3057,7 @@ func (bot *Bot) SendMessage(chatId int64, text string, opts *SendMessageOpts) (* reqOpts = opts.RequestOpts } - r, err := bot.Post("sendMessage", v, nil, reqOpts) + r, err := bot.Request("sendMessage", v, nil, reqOpts) if err != nil { return nil, err } @@ -3047,7 +3080,7 @@ type SendPhotoOpts struct { ProtectContent bool // If the message is a reply, ID of the original message ReplyToMessageId int64 - // Pass True, if the message should be sent even if the specified replied-to message is not found + // Pass True if the message should be sent even if the specified replied-to message is not found AllowSendingWithoutReply bool // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. ReplyMarkup ReplyMarkup @@ -3115,7 +3148,7 @@ func (bot *Bot) SendPhoto(chatId int64, photo InputFile, opts *SendPhotoOpts) (* reqOpts = opts.RequestOpts } - r, err := bot.Post("sendPhoto", v, data, reqOpts) + r, err := bot.Request("sendPhoto", v, data, reqOpts) if err != nil { return nil, err } @@ -3144,7 +3177,7 @@ type SendPollOpts struct { OpenPeriod int64 // Point in time (Unix timestamp) when the poll will be automatically closed. Must be at least 5 and no more than 600 seconds in the future. Can't be used together with open_period. CloseDate int64 - // Pass True, if the poll needs to be immediately closed. This can be useful for poll preview. + // Pass True if the poll needs to be immediately closed. This can be useful for poll preview. IsClosed bool // Sends the message silently. Users will receive a notification with no sound. DisableNotification bool @@ -3152,7 +3185,7 @@ type SendPollOpts struct { ProtectContent bool // If the message is a reply, ID of the original message ReplyToMessageId int64 - // Pass True, if the message should be sent even if the specified replied-to message is not found + // Pass True if the message should be sent even if the specified replied-to message is not found AllowSendingWithoutReply bool // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. ReplyMarkup ReplyMarkup @@ -3221,7 +3254,7 @@ func (bot *Bot) SendPoll(chatId int64, question string, options []string, opts * reqOpts = opts.RequestOpts } - r, err := bot.Post("sendPoll", v, nil, reqOpts) + r, err := bot.Request("sendPoll", v, nil, reqOpts) if err != nil { return nil, err } @@ -3238,7 +3271,7 @@ type SendStickerOpts struct { ProtectContent bool // If the message is a reply, ID of the original message ReplyToMessageId int64 - // Pass True, if the message should be sent even if the specified replied-to message is not found + // Pass True if the message should be sent even if the specified replied-to message is not found AllowSendingWithoutReply bool // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. ReplyMarkup ReplyMarkup @@ -3297,7 +3330,7 @@ func (bot *Bot) SendSticker(chatId int64, sticker InputFile, opts *SendStickerOp reqOpts = opts.RequestOpts } - r, err := bot.Post("sendSticker", v, data, reqOpts) + r, err := bot.Request("sendSticker", v, data, reqOpts) if err != nil { return nil, err } @@ -3322,7 +3355,7 @@ type SendVenueOpts struct { ProtectContent bool // If the message is a reply, ID of the original message ReplyToMessageId int64 - // Pass True, if the message should be sent even if the specified replied-to message is not found + // Pass True if the message should be sent even if the specified replied-to message is not found AllowSendingWithoutReply bool // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. ReplyMarkup ReplyMarkup @@ -3370,7 +3403,7 @@ func (bot *Bot) SendVenue(chatId int64, latitude float64, longitude float64, tit reqOpts = opts.RequestOpts } - r, err := bot.Post("sendVenue", v, nil, reqOpts) + r, err := bot.Request("sendVenue", v, nil, reqOpts) if err != nil { return nil, err } @@ -3395,7 +3428,7 @@ type SendVideoOpts struct { ParseMode string // A JSON-serialized list of special entities that appear in the caption, which can be specified instead of parse_mode CaptionEntities []MessageEntity - // Pass True, if the uploaded video is suitable for streaming + // Pass True if the uploaded video is suitable for streaming SupportsStreaming bool // Sends the message silently. Users will receive a notification with no sound. DisableNotification bool @@ -3403,7 +3436,7 @@ type SendVideoOpts struct { ProtectContent bool // If the message is a reply, ID of the original message ReplyToMessageId int64 - // Pass True, if the message should be sent even if the specified replied-to message is not found + // Pass True if the message should be sent even if the specified replied-to message is not found AllowSendingWithoutReply bool // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. ReplyMarkup ReplyMarkup @@ -3502,7 +3535,7 @@ func (bot *Bot) SendVideo(chatId int64, video InputFile, opts *SendVideoOpts) (* reqOpts = opts.RequestOpts } - r, err := bot.Post("sendVideo", v, data, reqOpts) + r, err := bot.Request("sendVideo", v, data, reqOpts) if err != nil { return nil, err } @@ -3525,7 +3558,7 @@ type SendVideoNoteOpts struct { ProtectContent bool // If the message is a reply, ID of the original message ReplyToMessageId int64 - // Pass True, if the message should be sent even if the specified replied-to message is not found + // Pass True if the message should be sent even if the specified replied-to message is not found AllowSendingWithoutReply bool // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. ReplyMarkup ReplyMarkup @@ -3611,7 +3644,7 @@ func (bot *Bot) SendVideoNote(chatId int64, videoNote InputFile, opts *SendVideo reqOpts = opts.RequestOpts } - r, err := bot.Post("sendVideoNote", v, data, reqOpts) + r, err := bot.Request("sendVideoNote", v, data, reqOpts) if err != nil { return nil, err } @@ -3636,7 +3669,7 @@ type SendVoiceOpts struct { ProtectContent bool // If the message is a reply, ID of the original message ReplyToMessageId int64 - // Pass True, if the message should be sent even if the specified replied-to message is not found + // Pass True if the message should be sent even if the specified replied-to message is not found AllowSendingWithoutReply bool // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. ReplyMarkup ReplyMarkup @@ -3707,7 +3740,7 @@ func (bot *Bot) SendVoice(chatId int64, voice InputFile, opts *SendVoiceOpts) (* reqOpts = opts.RequestOpts } - r, err := bot.Post("sendVoice", v, data, reqOpts) + r, err := bot.Request("sendVoice", v, data, reqOpts) if err != nil { return nil, err } @@ -3738,7 +3771,7 @@ func (bot *Bot) SetChatAdministratorCustomTitle(chatId int64, userId int64, cust reqOpts = opts.RequestOpts } - r, err := bot.Post("setChatAdministratorCustomTitle", v, nil, reqOpts) + r, err := bot.Request("setChatAdministratorCustomTitle", v, nil, reqOpts) if err != nil { return false, err } @@ -3771,7 +3804,7 @@ func (bot *Bot) SetChatDescription(chatId int64, opts *SetChatDescriptionOpts) ( reqOpts = opts.RequestOpts } - r, err := bot.Post("setChatDescription", v, nil, reqOpts) + r, err := bot.Request("setChatDescription", v, nil, reqOpts) if err != nil { return false, err } @@ -3811,7 +3844,7 @@ func (bot *Bot) SetChatMenuButton(opts *SetChatMenuButtonOpts) (bool, error) { reqOpts = opts.RequestOpts } - r, err := bot.Post("setChatMenuButton", v, nil, reqOpts) + r, err := bot.Request("setChatMenuButton", v, nil, reqOpts) if err != nil { return false, err } @@ -3844,7 +3877,7 @@ func (bot *Bot) SetChatPermissions(chatId int64, permissions ChatPermissions, op reqOpts = opts.RequestOpts } - r, err := bot.Post("setChatPermissions", v, nil, reqOpts) + r, err := bot.Request("setChatPermissions", v, nil, reqOpts) if err != nil { return false, err } @@ -3891,7 +3924,7 @@ func (bot *Bot) SetChatPhoto(chatId int64, photo InputFile, opts *SetChatPhotoOp reqOpts = opts.RequestOpts } - r, err := bot.Post("setChatPhoto", v, data, reqOpts) + r, err := bot.Request("setChatPhoto", v, data, reqOpts) if err != nil { return false, err } @@ -3920,7 +3953,7 @@ func (bot *Bot) SetChatStickerSet(chatId int64, stickerSetName string, opts *Set reqOpts = opts.RequestOpts } - r, err := bot.Post("setChatStickerSet", v, nil, reqOpts) + r, err := bot.Request("setChatStickerSet", v, nil, reqOpts) if err != nil { return false, err } @@ -3949,7 +3982,7 @@ func (bot *Bot) SetChatTitle(chatId int64, title string, opts *SetChatTitleOpts) reqOpts = opts.RequestOpts } - r, err := bot.Post("setChatTitle", v, nil, reqOpts) + r, err := bot.Request("setChatTitle", v, nil, reqOpts) if err != nil { return false, err } @@ -3960,9 +3993,9 @@ func (bot *Bot) SetChatTitle(chatId int64, title string, opts *SetChatTitleOpts) // SetGameScoreOpts is the set of optional fields for Bot.SetGameScore. type SetGameScoreOpts struct { - // Pass True, if the high score is allowed to decrease. This can be useful when fixing mistakes or banning cheaters + // Pass True if the high score is allowed to decrease. This can be useful when fixing mistakes or banning cheaters Force bool - // Pass True, if the game message should not be automatically edited to include the current scoreboard + // Pass True if the game message should not be automatically edited to include the current scoreboard DisableEditMessage bool // Required if inline_message_id is not specified. Unique identifier for the target chat ChatId int64 @@ -4000,7 +4033,7 @@ func (bot *Bot) SetGameScore(userId int64, score int64, opts *SetGameScoreOpts) reqOpts = opts.RequestOpts } - r, err := bot.Post("setGameScore", v, nil, reqOpts) + r, err := bot.Request("setGameScore", v, nil, reqOpts) if err != nil { return nil, false, err } @@ -4054,7 +4087,7 @@ func (bot *Bot) SetMyCommands(commands []BotCommand, opts *SetMyCommandsOpts) (b reqOpts = opts.RequestOpts } - r, err := bot.Post("setMyCommands", v, nil, reqOpts) + r, err := bot.Request("setMyCommands", v, nil, reqOpts) if err != nil { return false, err } @@ -4092,7 +4125,7 @@ func (bot *Bot) SetMyDefaultAdministratorRights(opts *SetMyDefaultAdministratorR reqOpts = opts.RequestOpts } - r, err := bot.Post("setMyDefaultAdministratorRights", v, nil, reqOpts) + r, err := bot.Request("setMyDefaultAdministratorRights", v, nil, reqOpts) if err != nil { return false, err } @@ -4128,7 +4161,7 @@ func (bot *Bot) SetPassportDataErrors(userId int64, errors []PassportElementErro reqOpts = opts.RequestOpts } - r, err := bot.Post("setPassportDataErrors", v, nil, reqOpts) + r, err := bot.Request("setPassportDataErrors", v, nil, reqOpts) if err != nil { return false, err } @@ -4157,7 +4190,7 @@ func (bot *Bot) SetStickerPositionInSet(sticker string, position int64, opts *Se reqOpts = opts.RequestOpts } - r, err := bot.Post("setStickerPositionInSet", v, nil, reqOpts) + r, err := bot.Request("setStickerPositionInSet", v, nil, reqOpts) if err != nil { return false, err } @@ -4213,7 +4246,7 @@ func (bot *Bot) SetStickerSetThumb(name string, userId int64, opts *SetStickerSe reqOpts = opts.RequestOpts } - r, err := bot.Post("setStickerSetThumb", v, data, reqOpts) + r, err := bot.Request("setStickerSetThumb", v, data, reqOpts) if err != nil { return false, err } @@ -4288,7 +4321,7 @@ func (bot *Bot) SetWebhook(url string, opts *SetWebhookOpts) (bool, error) { reqOpts = opts.RequestOpts } - r, err := bot.Post("setWebhook", v, data, reqOpts) + r, err := bot.Request("setWebhook", v, data, reqOpts) if err != nil { return false, err } @@ -4336,7 +4369,7 @@ func (bot *Bot) StopMessageLiveLocation(opts *StopMessageLiveLocationOpts) (*Mes reqOpts = opts.RequestOpts } - r, err := bot.Post("stopMessageLiveLocation", v, nil, reqOpts) + r, err := bot.Request("stopMessageLiveLocation", v, nil, reqOpts) if err != nil { return nil, false, err } @@ -4383,7 +4416,7 @@ func (bot *Bot) StopPoll(chatId int64, messageId int64, opts *StopPollOpts) (*Po reqOpts = opts.RequestOpts } - r, err := bot.Post("stopPoll", v, nil, reqOpts) + r, err := bot.Request("stopPoll", v, nil, reqOpts) if err != nil { return nil, err } @@ -4418,7 +4451,7 @@ func (bot *Bot) UnbanChatMember(chatId int64, userId int64, opts *UnbanChatMembe reqOpts = opts.RequestOpts } - r, err := bot.Post("unbanChatMember", v, nil, reqOpts) + r, err := bot.Request("unbanChatMember", v, nil, reqOpts) if err != nil { return false, err } @@ -4447,7 +4480,7 @@ func (bot *Bot) UnbanChatSenderChat(chatId int64, senderChatId int64, opts *Unba reqOpts = opts.RequestOpts } - r, err := bot.Post("unbanChatSenderChat", v, nil, reqOpts) + r, err := bot.Request("unbanChatSenderChat", v, nil, reqOpts) if err != nil { return false, err } @@ -4474,7 +4507,7 @@ func (bot *Bot) UnpinAllChatMessages(chatId int64, opts *UnpinAllChatMessagesOpt reqOpts = opts.RequestOpts } - r, err := bot.Post("unpinAllChatMessages", v, nil, reqOpts) + r, err := bot.Request("unpinAllChatMessages", v, nil, reqOpts) if err != nil { return false, err } @@ -4509,7 +4542,7 @@ func (bot *Bot) UnpinChatMessage(chatId int64, opts *UnpinChatMessageOpts) (bool reqOpts = opts.RequestOpts } - r, err := bot.Post("unpinChatMessage", v, nil, reqOpts) + r, err := bot.Request("unpinChatMessage", v, nil, reqOpts) if err != nil { return false, err } @@ -4556,7 +4589,7 @@ func (bot *Bot) UploadStickerFile(userId int64, pngSticker InputFile, opts *Uplo reqOpts = opts.RequestOpts } - r, err := bot.Post("uploadStickerFile", v, data, reqOpts) + r, err := bot.Request("uploadStickerFile", v, data, reqOpts) if err != nil { return nil, err } diff --git a/vendor/github.com/PaulSonOfLars/gotgbot/v2/gen_types.go b/vendor/github.com/PaulSonOfLars/gotgbot/v2/gen_types.go index 08109c9..71a2cdc 100644 --- a/vendor/github.com/PaulSonOfLars/gotgbot/v2/gen_types.go +++ b/vendor/github.com/PaulSonOfLars/gotgbot/v2/gen_types.go @@ -390,6 +390,8 @@ type Chat struct { Bio string `json:"bio,omitempty"` // Optional. True, if privacy settings of the other party in the private chat allows to use tg://user?id= links only in chats with the user. Returned only in getChat. HasPrivateForwards bool `json:"has_private_forwards,omitempty"` + // Optional. True, if the privacy settings of the other party restrict sending voice and video note messages in the private chat. Returned only in getChat. + HasRestrictedVoiceAndVideoMessages bool `json:"has_restricted_voice_and_video_messages,omitempty"` // Optional. True, if users need to join the supergroup before they can send messages. Returned only in getChat. JoinToSendMessages bool `json:"join_to_send_messages,omitempty"` // Optional. True, if all users directly joining the supergroup need to be approved by supergroup administrators. Returned only in getChat. @@ -1339,7 +1341,7 @@ type MergedInlineQueryResult struct { VoiceFileId string `json:"voice_file_id,omitempty"` // Optional. URL of the result (Only for article) Url string `json:"url,omitempty"` - // Optional. Pass True, if you don't want the URL to be shown in the message (Only for article) + // Optional. Pass True if you don't want the URL to be shown in the message (Only for article) HideUrl bool `json:"hide_url,omitempty"` // Optional. Url of the thumbnail for the result (Only for article, contact, document, gif, location, mpeg4_gif, photo, venue, video) ThumbUrl string `json:"thumb_url,omitempty"` @@ -1458,7 +1460,7 @@ type InlineQueryResultArticle struct { ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"` // Optional. URL of the result Url string `json:"url,omitempty"` - // Optional. Pass True, if you don't want the URL to be shown in the message + // Optional. Pass True if you don't want the URL to be shown in the message HideUrl bool `json:"hide_url,omitempty"` // Optional. Short description of the result Description string `json:"description,omitempty"` @@ -2853,19 +2855,19 @@ type InputInvoiceMessageContent struct { PhotoWidth int64 `json:"photo_width,omitempty"` // Optional. Photo height PhotoHeight int64 `json:"photo_height,omitempty"` - // Optional. Pass True, if you require the user's full name to complete the order + // Optional. Pass True if you require the user's full name to complete the order NeedName bool `json:"need_name,omitempty"` - // Optional. Pass True, if you require the user's phone number to complete the order + // Optional. Pass True if you require the user's phone number to complete the order NeedPhoneNumber bool `json:"need_phone_number,omitempty"` - // Optional. Pass True, if you require the user's email address to complete the order + // Optional. Pass True if you require the user's email address to complete the order NeedEmail bool `json:"need_email,omitempty"` - // Optional. Pass True, if you require the user's shipping address to complete the order + // Optional. Pass True if you require the user's shipping address to complete the order NeedShippingAddress bool `json:"need_shipping_address,omitempty"` - // Optional. Pass True, if the user's phone number should be sent to provider + // Optional. Pass True if the user's phone number should be sent to provider SendPhoneNumberToProvider bool `json:"send_phone_number_to_provider,omitempty"` - // Optional. Pass True, if the user's email address should be sent to provider + // Optional. Pass True if the user's email address should be sent to provider SendEmailToProvider bool `json:"send_email_to_provider,omitempty"` - // Optional. Pass True, if the final price depends on the shipping method + // Optional. Pass True if the final price depends on the shipping method IsFlexible bool `json:"is_flexible,omitempty"` } @@ -2935,7 +2937,7 @@ type MergedInputMedia struct { Performer string `json:"performer,omitempty"` // Optional. Title of the audio (Only for audio) Title string `json:"title,omitempty"` - // Optional. Pass True, if the uploaded video is suitable for streaming (Only for video) + // Optional. Pass True if the uploaded video is suitable for streaming (Only for video) SupportsStreaming bool `json:"supports_streaming,omitempty"` } @@ -3294,7 +3296,7 @@ type InputMediaVideo struct { Height int64 `json:"height,omitempty"` // Optional. Video duration in seconds Duration int64 `json:"duration,omitempty"` - // Optional. Pass True, if the uploaded video is suitable for streaming + // Optional. Pass True if the uploaded video is suitable for streaming SupportsStreaming bool `json:"supports_streaming,omitempty"` } @@ -3483,7 +3485,7 @@ type Location struct { // Telegram apps support these buttons as of version 5.7. // https://core.telegram.org/bots/api#loginurl type LoginUrl struct { - // An HTTP URL to be opened with user authorization data added to the query string when the button is pressed. If the user refuses to provide authorization data, the original URL without information about the user will be opened. The data added is the same as described in Receiving authorization data. NOTE: You must always check the hash of the received data to verify the authentication and the integrity of the data as described in Checking authorization. + // An HTTPS URL to be opened with user authorization data added to the query string when the button is pressed. If the user refuses to provide authorization data, the original URL without information about the user will be opened. The data added is the same as described in Receiving authorization data. NOTE: You must always check the hash of the received data to verify the authentication and the integrity of the data as described in Checking authorization. Url string `json:"url"` // Optional. New text of the button in forwarded messages. ForwardText string `json:"forward_text,omitempty"` @@ -3843,7 +3845,7 @@ type MessageAutoDeleteTimerChanged struct { // MessageEntity This object represents one special entity in a text message. For example, hashtags, usernames, URLs, etc. // https://core.telegram.org/bots/api#messageentity type MessageEntity struct { - // Type of the entity. Currently, can be "mention" (@username), "hashtag" (#hashtag), "cashtag" ($USD), "bot_command" (/start@jobs_bot), "url" (https://telegram.org), "email" (do-not-reply@telegram.org), "phone_number" (+1-212-555-0123), "bold" (bold text), "italic" (italic text), "underline" (underlined text), "strikethrough" (strikethrough text), "spoiler" (spoiler message), "code" (monowidth string), "pre" (monowidth block), "text_link" (for clickable text URLs), "text_mention" (for users without usernames) + // Type of the entity. Currently, can be "mention" (@username), "hashtag" (#hashtag), "cashtag" ($USD), "bot_command" (/start@jobs_bot), "url" (https://telegram.org), "email" (do-not-reply@telegram.org), "phone_number" (+1-212-555-0123), "bold" (bold text), "italic" (italic text), "underline" (underlined text), "strikethrough" (strikethrough text), "spoiler" (spoiler message), "code" (monowidth string), "pre" (monowidth block), "text_link" (for clickable text URLs), "text_mention" (for users without usernames), "custom_emoji" (for inline custom emoji stickers) Type string `json:"type"` // Offset in UTF-16 code units to the start of the entity Offset int64 `json:"offset"` @@ -3855,6 +3857,8 @@ type MessageEntity struct { User *User `json:"user,omitempty"` // Optional. For "pre" only, the programming language of the entity text Language string `json:"language,omitempty"` + // Optional. For "custom_emoji" only, unique identifier of the custom emoji. Use getCustomEmojiStickers to get full information about the sticker + CustomEmojiId string `json:"custom_emoji_id,omitempty"` } // MessageId This object represents a unique message identifier. @@ -4623,6 +4627,8 @@ type Sticker struct { FileId string `json:"file_id"` // Unique identifier for this file, which is supposed to be the same over time and for different bots. Can't be used to download or reuse the file. FileUniqueId string `json:"file_unique_id"` + // Type of the sticker, currently one of "regular", "mask", "custom_emoji". The type of the sticker is independent from its format, which is determined by the fields is_animated and is_video. + Type string `json:"type"` // Sticker width Width int64 `json:"width"` // Sticker height @@ -4637,10 +4643,12 @@ type Sticker struct { Emoji string `json:"emoji,omitempty"` // Optional. Name of the sticker set to which the sticker belongs SetName string `json:"set_name,omitempty"` - // Optional. Premium animation for the sticker, if the sticker is premium + // Optional. For premium regular stickers, premium animation for the sticker PremiumAnimation *File `json:"premium_animation,omitempty"` // Optional. For mask stickers, the position where the mask should be placed MaskPosition *MaskPosition `json:"mask_position,omitempty"` + // Optional. For custom emoji stickers, unique identifier of the custom emoji + CustomEmojiId string `json:"custom_emoji_id,omitempty"` // Optional. File size in bytes FileSize int64 `json:"file_size,omitempty"` } @@ -4652,12 +4660,12 @@ type StickerSet struct { Name string `json:"name"` // Sticker set title Title string `json:"title"` + // Type of stickers in the set, currently one of "regular", "mask", "custom_emoji" + StickerType string `json:"sticker_type"` // True, if the sticker set contains animated stickers IsAnimated bool `json:"is_animated"` // True, if the sticker set contains video stickers IsVideo bool `json:"is_video"` - // True, if the sticker set contains masks - ContainsMasks bool `json:"contains_masks"` // List of all set stickers Stickers []Sticker `json:"stickers,omitempty"` // Optional. Sticker set thumbnail in the .WEBP, .TGS, or .WEBM format diff --git a/vendor/github.com/PaulSonOfLars/gotgbot/v2/request.go b/vendor/github.com/PaulSonOfLars/gotgbot/v2/request.go index 025ee3c..a002db9 100644 --- a/vendor/github.com/PaulSonOfLars/gotgbot/v2/request.go +++ b/vendor/github.com/PaulSonOfLars/gotgbot/v2/request.go @@ -20,8 +20,8 @@ const ( ) type BotClient interface { - // PostWithContext submits a POST HTTP request a bot API instance. - PostWithContext(ctx context.Context, method string, params map[string]string, data map[string]NamedReader, opts *RequestOpts) (json.RawMessage, error) + // RequestWithContext submits a POST HTTP request a bot API instance. + RequestWithContext(ctx context.Context, method string, params map[string]string, data map[string]NamedReader, opts *RequestOpts) (json.RawMessage, error) // TimeoutContext calculates the required timeout contect required given the passed RequestOpts, and any default opts defined by the BotClient. TimeoutContext(opts *RequestOpts) (context.Context, context.CancelFunc) // GetAPIURL gets the URL of the API the bot is interacting with. @@ -35,6 +35,10 @@ type BaseBotClient struct { Token string // Client is the HTTP Client used for all HTTP requests made for this bot. Client http.Client + // UseTestEnvironment defines whether this bot was created to run on telegram's test environment. + // Enabling this uses a slightly different API path. + // See https://core.telegram.org/bots/webapps#using-bots-in-the-test-environment for more details. + UseTestEnvironment bool // The default request opts for this bot instance. DefaultRequestOpts *RequestOpts } @@ -128,13 +132,13 @@ func timeoutFromOpts(opts *RequestOpts) (context.Context, context.CancelFunc) { } // PostWithContext allows sending a POST request to the telegram bot API with an existing context. -// - ctx: the timeout contexts to be used. -// - method: the telegram API method to call. -// - params: map of parameters to be sending to the telegram API. eg: chat_id, user_id, etc. -// - data: map of any files to be sending to the telegram API. -// - opts: request opts to use. Note: Timeout opts are ignored when used in PostWithContext. Timeout handling is the -// responsibility of the caller/context owner. -func (bot *BaseBotClient) PostWithContext(ctx context.Context, method string, params map[string]string, data map[string]NamedReader, opts *RequestOpts) (json.RawMessage, error) { +// - ctx: the timeout contexts to be used. +// - method: the telegram API method to call. +// - params: map of parameters to be sending to the telegram API. eg: chat_id, user_id, etc. +// - data: map of any files to be sending to the telegram API. +// - opts: request opts to use. Note: Timeout opts are ignored when used in PostWithContext. Timeout handling is the +// responsibility of the caller/context owner. +func (bot *BaseBotClient) RequestWithContext(ctx context.Context, method string, params map[string]string, data map[string]NamedReader, opts *RequestOpts) (json.RawMessage, error) { b := &bytes.Buffer{} var contentType string @@ -247,5 +251,8 @@ func (bot *BaseBotClient) getAPIURL(opts *RequestOpts) string { } func (bot *BaseBotClient) methodEnpoint(method string, opts *RequestOpts) string { + if bot.UseTestEnvironment { + return fmt.Sprintf("%s/bot%s/test/%s", bot.getAPIURL(opts), bot.Token, method) + } return fmt.Sprintf("%s/bot%s/%s", bot.getAPIURL(opts), bot.Token, method) } diff --git a/vendor/github.com/PaulSonOfLars/gotgbot/v2/spec_commit b/vendor/github.com/PaulSonOfLars/gotgbot/v2/spec_commit index 22c415f..4232ff7 100644 --- a/vendor/github.com/PaulSonOfLars/gotgbot/v2/spec_commit +++ b/vendor/github.com/PaulSonOfLars/gotgbot/v2/spec_commit @@ -1 +1 @@ -fd71275bd19cbbd1260beacd984563293525b4e0 \ No newline at end of file +e75794e2ca7c0bc923433d1a3e4e861cc028e2c0 \ No newline at end of file diff --git a/vendor/modules.txt b/vendor/modules.txt index db9d596..37a7684 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,4 +1,4 @@ -# github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.9 +# github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.10 ## explicit; go 1.15 github.com/PaulSonOfLars/gotgbot/v2 github.com/PaulSonOfLars/gotgbot/v2/ext