diff --git a/bot.go b/bot.go index 02affb7..f2dccb2 100644 --- a/bot.go +++ b/bot.go @@ -62,8 +62,9 @@ func NewBotAPIWithClient(token string, client *http.Client) (*BotAPI, error) { return bot, nil } -func (b *BotAPI) SetAPIEndpoint(apiEndpoint string) { - b.apiEndpoint = apiEndpoint +// SetAPIEndpoint changes the Telegram Bot API endpoint used by the instance. +func (bot *BotAPI) SetAPIEndpoint(apiEndpoint string) { + bot.apiEndpoint = apiEndpoint } func buildParams(in Params) (out url.Values) { @@ -473,7 +474,7 @@ func WriteToHTTPResponse(w http.ResponseWriter, c Chattable) error { if t, ok := c.(Fileable); ok { if !t.useExistingFile() { - return errors.New("Can't use HTTP Response to upload files.") + return errors.New("unable to use http response to upload files") } } @@ -610,3 +611,23 @@ func (bot *BotAPI) StopPoll(config StopPollConfig) (Poll, error) { return poll, err } + +// GetMyCommands gets the currently registered commands. +func (bot *BotAPI) GetMyCommands() ([]BotCommand, error) { + config := GetMyCommandsConfig{} + + params, err := config.params() + if err != nil { + return nil, err + } + + resp, err := bot.MakeRequest(config.method(), params) + if err != nil { + return nil, err + } + + var commands []BotCommand + err = json.Unmarshal(resp.Result, &commands) + + return commands, err +} diff --git a/bot_test.go b/bot_test.go index fe1fd55..b5ab2bd 100644 --- a/bot_test.go +++ b/bot_test.go @@ -733,3 +733,44 @@ func TestPolls(t *testing.T) { t.Fail() } } + +func TestSendDice(t *testing.T) { + bot, _ := getBot(t) + + dice := NewSendDice(ChatID) + + msg, err := bot.Send(dice) + if err != nil { + t.Error("Unable to send dice roll") + } + + if msg.Dice == nil { + t.Error("Dice roll was not received") + } +} + +func TestSetCommands(t *testing.T) { + bot, _ := getBot(t) + + setCommands := NewSetMyCommands(BotCommand{ + Command: "test", + Description: "a test command", + }) + + if _, err := bot.Request(setCommands); err != nil { + t.Error("Unable to set commands") + } + + commands, err := bot.GetMyCommands() + if err != nil { + t.Error("Unable to get commands") + } + + if len(commands) != 1 { + t.Error("Incorrect number of commands returned") + } + + if commands[0].Command != "test" || commands[0].Description != "a test command" { + t.Error("Commands were incorrectly set") + } +} diff --git a/configs.go b/configs.go index 716ed5d..217ffc1 100644 --- a/configs.go +++ b/configs.go @@ -1417,11 +1417,14 @@ func (config UploadStickerConfig) useExistingFile() bool { } // NewStickerSetConfig allows creating a new sticker set. +// +// You must set either PNGSticker or TGSSticker. type NewStickerSetConfig struct { UserID int64 Name string Title string PNGSticker interface{} + TGSSticker interface{} Emojis string ContainsMasks bool MaskPosition *MaskPosition @@ -1440,6 +1443,8 @@ func (config NewStickerSetConfig) params() (Params, error) { if sticker, ok := config.PNGSticker.(string); ok { params[config.name()] = sticker + } else if sticker, ok := config.TGSSticker.(string); ok { + params[config.name()] = sticker } params["emojis"] = config.Emojis @@ -1460,9 +1465,17 @@ func (config NewStickerSetConfig) name() string { } func (config NewStickerSetConfig) useExistingFile() bool { - _, ok := config.PNGSticker.(string) + if config.PNGSticker != nil { + _, ok := config.PNGSticker.(string) + return ok + } - return ok + if config.TGSSticker != nil { + _, ok := config.TGSSticker.(string) + return ok + } + + panic("NewStickerSetConfig had nil PNGSticker and TGSSticker") } // AddStickerConfig allows you to add a sticker to a set. @@ -1470,6 +1483,7 @@ type AddStickerConfig struct { UserID int64 Name string PNGSticker interface{} + TGSSticker interface{} Emojis string MaskPosition *MaskPosition } @@ -1487,6 +1501,8 @@ func (config AddStickerConfig) params() (Params, error) { if sticker, ok := config.PNGSticker.(string); ok { params[config.name()] = sticker + } else if sticker, ok := config.TGSSticker.(string); ok { + params[config.name()] = sticker } err := params.AddInterface("mask_position", config.MaskPosition) @@ -1542,6 +1558,43 @@ func (config DeleteStickerConfig) params() (Params, error) { return params, nil } +// SetStickerSetThumbConfig allows you to set the thumbnail for a sticker set. +type SetStickerSetThumbConfig struct { + Name string + UserID int + Thumb interface{} +} + +func (config SetStickerSetThumbConfig) method() string { + return "setStickerSetThumb" +} + +func (config SetStickerSetThumbConfig) params() (Params, error) { + params := make(Params) + + params["name"] = config.Name + params.AddNonZero("user_id", config.UserID) + + if thumb, ok := config.Thumb.(string); ok { + params["thumb"] = thumb + } + + return params, nil +} + +func (config SetStickerSetThumbConfig) name() string { + return "thumb" +} + +func (config SetStickerSetThumbConfig) getFile() interface{} { + return config.Thumb +} + +func (config SetStickerSetThumbConfig) useExistingFile() bool { + _, ok := config.Thumb.(string) + return ok +} + // SetChatStickerSetConfig allows you to set the sticker set for a supergroup. type SetChatStickerSetConfig struct { ChatID int64 @@ -1609,3 +1662,44 @@ func (config MediaGroupConfig) params() (Params, error) { return params, nil } + +// DiceConfig allows you to send a random dice roll to Telegram. +type DiceConfig struct { + BaseChat +} + +func (config DiceConfig) method() string { + return "sendDice" +} + +func (config DiceConfig) params() (Params, error) { + return config.BaseChat.params() +} + +// GetMyCommandsConfig gets a list of the currently registered commands. +type GetMyCommandsConfig struct{} + +func (config GetMyCommandsConfig) method() string { + return "getMyCommands" +} + +func (config GetMyCommandsConfig) params() (Params, error) { + return make(Params), nil +} + +// SetMyCommandsConfig sets a list of commands the bot understands. +type SetMyCommandsConfig struct { + commands []BotCommand +} + +func (config SetMyCommandsConfig) method() string { + return "setMyCommands" +} + +func (config SetMyCommandsConfig) params() (Params, error) { + params := make(Params) + + err := params.AddInterface("commands", config.commands) + + return params, err +} diff --git a/helpers.go b/helpers.go index 434f87b..c6c4e61 100644 --- a/helpers.go +++ b/helpers.go @@ -509,7 +509,7 @@ func NewInlineQueryResultMPEG4GIF(id, url string) InlineQueryResultMPEG4GIF { } } -// NewInlineQueryResultCachedPhoto create a new inline query with cached photo. +// NewInlineQueryResultCachedMPEG4GIF create a new inline query with cached photo. func NewInlineQueryResultCachedMPEG4GIF(id, MPEG4GifID string) InlineQueryResultCachedMpeg4Gif { return InlineQueryResultCachedMpeg4Gif{ Type: "mpeg4_gif", @@ -914,3 +914,17 @@ func NewStopPoll(chatID int64, messageID int) StopPollConfig { }, } } + +// NewSendDice allows you to send a random dice roll. +func NewSendDice(chatID int64) DiceConfig { + return DiceConfig{ + BaseChat{ + ChatID: chatID, + }, + } +} + +// NewSetMyCommands allows you to set the registered commands. +func NewSetMyCommands(commands ...BotCommand) SetMyCommandsConfig { + return SetMyCommandsConfig{commands: commands} +} diff --git a/types.go b/types.go index adc15eb..0d35270 100644 --- a/types.go +++ b/types.go @@ -186,6 +186,7 @@ type Message struct { Location *Location `json:"location"` // optional Venue *Venue `json:"venue"` // optional Poll *Poll `json:"poll"` // optional + Dice *Dice `json:"dice"` // optional NewChatMembers []User `json:"new_chat_members"` // optional LeftChatMember *User `json:"left_chat_member"` // optional NewChatTitle string `json:"new_chat_title"` // optional @@ -495,6 +496,11 @@ type Poll struct { CorrectOptionID int `json:"correct_option_id"` // optional } +// Dice represents a single dice value. +type Dice struct { + Value int `json:"value"` +} + // UserProfilePhotos contains a set of user profile photos. type UserProfilePhotos struct { TotalCount int `json:"total_count"` @@ -1067,11 +1073,18 @@ type PreCheckoutQuery struct { // StickerSet is a collection of stickers. type StickerSet struct { - Name string `json:"name"` - Title string `json:"title"` - IsAnimated bool `json:"is_animated"` - ContainsMasks bool `json:"contains_masks"` - Stickers []Sticker `json:"stickers"` + Name string `json:"name"` + Title string `json:"title"` + IsAnimated bool `json:"is_animated"` + ContainsMasks bool `json:"contains_masks"` + Stickers []Sticker `json:"stickers"` + Thumb *PhotoSize `json:"thumb"` +} + +// BotCommand represents Telegram's understanding of a command. +type BotCommand struct { + Command string `json:"command"` + Description string `json:"description"` } // BaseInputMedia is a base type for the InputMedia types.