From 66dc9e824616b3bb3c6531d9411e622417bd4f03 Mon Sep 17 00:00:00 2001 From: Syfaro Date: Sun, 27 Jun 2021 15:15:09 -0400 Subject: [PATCH 1/2] Updates for Bot API 5.3. --- bot.go | 4 +-- bot_test.go | 26 ++++++++++++-- configs.go | 40 ++++++++++++++++++--- helpers.go | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++- types.go | 20 +++++++++++ types_test.go | 1 + 6 files changed, 179 insertions(+), 10 deletions(-) diff --git a/bot.go b/bot.go index 2f257e1a..ad098af5 100644 --- a/bot.go +++ b/bot.go @@ -667,9 +667,7 @@ func (bot *BotAPI) StopPoll(config StopPollConfig) (Poll, error) { } // GetMyCommands gets the currently registered commands. -func (bot *BotAPI) GetMyCommands() ([]BotCommand, error) { - config := GetMyCommandsConfig{} - +func (bot *BotAPI) GetMyCommands(config GetMyCommandsConfig) ([]BotCommand, error) { resp, err := bot.Request(config) if err != nil { return nil, err diff --git a/bot_test.go b/bot_test.go index 82bf6d47..3a9e438a 100644 --- a/bot_test.go +++ b/bot_test.go @@ -953,7 +953,7 @@ func TestSendDice(t *testing.T) { } } -func TestSetCommands(t *testing.T) { +func TestCommands(t *testing.T) { bot, _ := getBot(t) setCommands := NewSetMyCommands(BotCommand{ @@ -965,7 +965,7 @@ func TestSetCommands(t *testing.T) { t.Error("Unable to set commands") } - commands, err := bot.GetMyCommands() + commands, err := bot.GetMyCommands(NewGetMyCommands()) if err != nil { t.Error("Unable to get commands") } @@ -977,6 +977,28 @@ func TestSetCommands(t *testing.T) { if commands[0].Command != "test" || commands[0].Description != "a test command" { t.Error("Commands were incorrectly set") } + + setCommands = NewSetMyCommandsWithScope(NewBotCommandScopeAllPrivateChats(), BotCommand{ + Command: "private", + Description: "a private command", + }) + + if _, err := bot.Request(setCommands); err != nil { + t.Error("Unable to set commands") + } + + commands, err = bot.GetMyCommands(NewGetMyCommandsWithScope(NewBotCommandScopeAllPrivateChats())) + if err != nil { + t.Error("Unable to get commands") + } + + if len(commands) != 1 { + t.Error("Incorrect number of commands returned") + } + + if commands[0].Command != "private" || commands[0].Description != "a private command" { + t.Error("Commands were incorrectly set") + } } func TestEditMessageMedia(t *testing.T) { diff --git a/configs.go b/configs.go index c08b68b6..ac096794 100644 --- a/configs.go +++ b/configs.go @@ -2062,19 +2062,29 @@ func (config DiceConfig) params() (Params, error) { } // GetMyCommandsConfig gets a list of the currently registered commands. -type GetMyCommandsConfig struct{} +type GetMyCommandsConfig struct { + Scope *BotCommandScope + LanguageCode string +} func (config GetMyCommandsConfig) method() string { return "getMyCommands" } func (config GetMyCommandsConfig) params() (Params, error) { - return nil, nil + params := make(Params) + + err := params.AddInterface("scope", config.Scope) + params.AddNonEmpty("language_code", config.LanguageCode) + + return params, err } // SetMyCommandsConfig sets a list of commands the bot understands. type SetMyCommandsConfig struct { - commands []BotCommand + Commands []BotCommand + Scope *BotCommandScope + LanguageCode string } func (config SetMyCommandsConfig) method() string { @@ -2084,7 +2094,29 @@ func (config SetMyCommandsConfig) method() string { func (config SetMyCommandsConfig) params() (Params, error) { params := make(Params) - err := params.AddInterface("commands", config.commands) + if err := params.AddInterface("commands", config.Commands); err != nil { + return params, err + } + err := params.AddInterface("scope", config.Scope) + params.AddNonEmpty("language_code", config.LanguageCode) + + return params, err +} + +type DeleteMyCommandsConfig struct { + Scope *BotCommandScope + LanguageCode string +} + +func (config DeleteMyCommandsConfig) method() string { + return "deleteMyCommands" +} + +func (config DeleteMyCommandsConfig) params() (Params, error) { + params := make(Params) + + err := params.AddInterface("scope", config.Scope) + params.AddNonEmpty("language_code", config.LanguageCode) return params, err } diff --git a/helpers.go b/helpers.go index 7e22b676..f9ad3993 100644 --- a/helpers.go +++ b/helpers.go @@ -837,7 +837,103 @@ func NewDiceWithEmoji(chatID int64, emoji string) DiceConfig { } } +// NewBotCommandScopeDefault represents the default scope of bot commands. +func NewBotCommandScopeDefault() BotCommandScope { + return BotCommandScope{Type: "default"} +} + +// NewBotCommandScopeAllPrivateChats represents the scope of bot commands, +// covering all private chats. +func NewBotCommandScopeAllPrivateChats() BotCommandScope { + return BotCommandScope{Type: "all_private_chats"} +} + +// NewBotCommandScopeAllGroupChats represents the scope of bot commands, +// covering all group and supergroup chats. +func NewBotCommandScopeAllGroupChats() BotCommandScope { + return BotCommandScope{Type: "all_group_chats"} +} + +// NewBotCommandScopeAllChatAdministrators represents the scope of bot commands, +// covering all group and supergroup chat administrators. +func NewBotCommandScopeAllChatAdministrators() BotCommandScope { + return BotCommandScope{Type: "all_chat_administrators"} +} + +// NewBotCommandScopeChat represents the scope of bot commands, covering a +// specific chat. +func NewBotCommandScopeChat(chatID int64) BotCommandScope { + return BotCommandScope{ + Type: "chat", + ChatID: chatID, + } +} + +// NewBotCommandScopeChatAdministrators represents the scope of bot commands, +// covering all administrators of a specific group or supergroup chat. +func NewBotCommandScopeChatAdministrators(chatID int64) BotCommandScope { + return BotCommandScope{ + Type: "chat_administrators", + ChatID: chatID, + } +} + +// NewBotCommandScopeChatMember represents the scope of bot commands, covering a +// specific member of a group or supergroup chat. +func NewBotCommandScopeChatMember(chatID, userID int64) BotCommandScope { + return BotCommandScope{ + Type: "chat_member", + ChatID: chatID, + UserID: userID, + } +} + +// NewGetMyCommands allows you to set the registered commands. +func NewGetMyCommands() GetMyCommandsConfig { + return GetMyCommandsConfig{} +} + +// NewGetMyCommandsWithScope allows you to set the registered commands for a +// given scope. +func NewGetMyCommandsWithScope(scope BotCommandScope) GetMyCommandsConfig { + return GetMyCommandsConfig{Scope: &scope} +} + +// NewGetMyCommandsWithScopeAndLanguage allows you to set the registered +// commands for a given scope and language code. +func NewGetMyCommandsWithScopeAndLanguage(scope BotCommandScope, languageCode string) GetMyCommandsConfig { + return GetMyCommandsConfig{Scope: &scope, LanguageCode: languageCode} +} + // NewSetMyCommands allows you to set the registered commands. func NewSetMyCommands(commands ...BotCommand) SetMyCommandsConfig { - return SetMyCommandsConfig{commands: commands} + return SetMyCommandsConfig{Commands: commands} +} + +// NewSetMyCommands allows you to set the registered commands for a given scope. +func NewSetMyCommandsWithScope(scope BotCommandScope, commands ...BotCommand) SetMyCommandsConfig { + return SetMyCommandsConfig{Commands: commands, Scope: &scope} +} + +// NewSetMyCommands allows you to set the registered commands for a given scope +// and language code. +func NewSetMyCommandsWithScopeAndLanguage(scope BotCommandScope, languageCode string, commands ...BotCommand) SetMyCommandsConfig { + return SetMyCommandsConfig{Commands: commands, Scope: &scope, LanguageCode: languageCode} +} + +// NewDeleteMyCommands allows you to delete the registered commands. +func NewDeleteMyCommands() DeleteMyCommandsConfig { + return DeleteMyCommandsConfig{} +} + +// NewDeleteMyCommands allows you to delete the registered commands for a given +// scope. +func NewDeleteMyCommandsWithScope(scope BotCommandScope) DeleteMyCommandsConfig { + return DeleteMyCommandsConfig{Scope: &scope} +} + +// NewDeleteMyCommands allows you to delete the registered commands for a given +// scope and language code. +func NewDeleteMyCommandsWithScopeAndLanguage(scope BotCommandScope, languageCode string) DeleteMyCommandsConfig { + return DeleteMyCommandsConfig{Scope: &scope, LanguageCode: languageCode} } diff --git a/types.go b/types.go index 918eac08..b269315c 100644 --- a/types.go +++ b/types.go @@ -1158,6 +1158,11 @@ type ReplyKeyboardMarkup struct { // // optional OneTimeKeyboard bool `json:"one_time_keyboard,omitempty"` + // InputFieldPlaceholder is the placeholder to be shown in the input field when + // the keyboard is active; 1-64 characters. + // + // optional + InputFieldPlaceholder string `json:"input_field_placeholder,omitempty"` // Selective use this parameter if you want to show the keyboard to specific users only. // Targets: // 1) users that are @mentioned in the text of the Message object; @@ -1375,6 +1380,11 @@ type ForceReply struct { // ForceReply shows reply interface to the user, // as if they manually selected the bot's message and tapped 'Reply'. ForceReply bool `json:"force_reply"` + // InputFieldPlaceholder is the placeholder to be shown in the input field when + // the reply is active; 1-64 characters. + // + // optional + InputFieldPlaceholder string `json:"input_field_placeholder,omitempty"` // Selective use this parameter if you want to force reply from specific users only. // Targets: // 1) users that are @mentioned in the text of the Message object; @@ -1643,6 +1653,16 @@ type BotCommand struct { Description string `json:"description"` } +// BotCommandScope represents the scope to which bot commands are applied. +// +// It contains the fields for all types of scopes, different types only support +// specific (or no) fields. +type BotCommandScope struct { + Type string `json:"type"` + ChatID int64 `json:"chat_id,omitempty"` + UserID int64 `json:"user_id,omitempty"` +} + // ResponseParameters are various errors that can be returned in APIResponse. type ResponseParameters struct { // The group has been migrated to a supergroup with the specified identifier. diff --git a/types_test.go b/types_test.go index 7a4b196b..b8a52a2a 100644 --- a/types_test.go +++ b/types_test.go @@ -293,6 +293,7 @@ var ( _ Chattable = DeleteChatPhotoConfig{} _ Chattable = DeleteChatStickerSetConfig{} _ Chattable = DeleteMessageConfig{} + _ Chattable = DeleteMyCommandsConfig{} _ Chattable = DeleteWebhookConfig{} _ Chattable = DocumentConfig{} _ Chattable = EditChatInviteLinkConfig{} From 1198abda6d662e8d8fe90e53f6c0e1cc9e56dcb7 Mon Sep 17 00:00:00 2001 From: Syfaro Date: Fri, 20 Aug 2021 01:27:42 -0400 Subject: [PATCH 2/2] Avoid breaking change with GetMyCommands. --- bot.go | 7 ++++++- bot_test.go | 4 ++-- helpers.go | 5 ----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bot.go b/bot.go index ad098af5..0d051dd1 100644 --- a/bot.go +++ b/bot.go @@ -667,7 +667,12 @@ func (bot *BotAPI) StopPoll(config StopPollConfig) (Poll, error) { } // GetMyCommands gets the currently registered commands. -func (bot *BotAPI) GetMyCommands(config GetMyCommandsConfig) ([]BotCommand, error) { +func (bot *BotAPI) GetMyCommands() ([]BotCommand, error) { + return bot.GetMyCommandsWithConfig(GetMyCommandsConfig{}) +} + +// GetMyCommandsWithConfig gets the currently registered commands with a config. +func (bot *BotAPI) GetMyCommandsWithConfig(config GetMyCommandsConfig) ([]BotCommand, error) { resp, err := bot.Request(config) if err != nil { return nil, err diff --git a/bot_test.go b/bot_test.go index 3a9e438a..b1ba8aa6 100644 --- a/bot_test.go +++ b/bot_test.go @@ -965,7 +965,7 @@ func TestCommands(t *testing.T) { t.Error("Unable to set commands") } - commands, err := bot.GetMyCommands(NewGetMyCommands()) + commands, err := bot.GetMyCommands() if err != nil { t.Error("Unable to get commands") } @@ -987,7 +987,7 @@ func TestCommands(t *testing.T) { t.Error("Unable to set commands") } - commands, err = bot.GetMyCommands(NewGetMyCommandsWithScope(NewBotCommandScopeAllPrivateChats())) + commands, err = bot.GetMyCommandsWithConfig(NewGetMyCommandsWithScope(NewBotCommandScopeAllPrivateChats())) if err != nil { t.Error("Unable to get commands") } diff --git a/helpers.go b/helpers.go index f9ad3993..fc2a89d9 100644 --- a/helpers.go +++ b/helpers.go @@ -888,11 +888,6 @@ func NewBotCommandScopeChatMember(chatID, userID int64) BotCommandScope { } } -// NewGetMyCommands allows you to set the registered commands. -func NewGetMyCommands() GetMyCommandsConfig { - return GetMyCommandsConfig{} -} - // NewGetMyCommandsWithScope allows you to set the registered commands for a // given scope. func NewGetMyCommandsWithScope(scope BotCommandScope) GetMyCommandsConfig {