diff --git a/bot.go b/bot.go index 3247f01..c6ca084 100644 --- a/bot.go +++ b/bot.go @@ -548,7 +548,7 @@ func (bot *BotAPI) GetStickerSet(config GetStickerSetConfig) (StickerSet, error) resp, err := bot.MakeRequest(config.method(), params) if err != nil { - return StickerSet{}, nil + return StickerSet{}, err } var stickers StickerSet @@ -556,3 +556,21 @@ func (bot *BotAPI) GetStickerSet(config GetStickerSetConfig) (StickerSet, error) return stickers, err } + +// StopPoll stops a poll and returns the result. +func (bot *BotAPI) StopPoll(config StopPollConfig) (Poll, error) { + params, err := config.params() + if err != nil { + return Poll{}, err + } + + resp, err := bot.MakeRequest(config.method(), params) + if err != nil { + return Poll{}, err + } + + var poll Poll + err = json.Unmarshal(resp.Result, &poll) + + return poll, err +} diff --git a/bot_test.go b/bot_test.go index 137f9b9..fe1fd55 100644 --- a/bot_test.go +++ b/bot_test.go @@ -700,3 +700,36 @@ func TestUnpinChatMessage(t *testing.T) { t.Fail() } } + +func TestPolls(t *testing.T) { + bot, _ := getBot(t) + + poll := NewPoll(SupergroupChatID, "Are polls working?", "Yes", "No") + + msg, err := bot.Send(poll) + if err != nil { + t.Error(err) + t.Fail() + } + + result, err := bot.StopPoll(NewStopPoll(SupergroupChatID, msg.MessageID)) + if err != nil { + t.Error(err) + t.Fail() + } + + if result.Question != "Are polls working?" { + t.Error("Poll question did not match") + t.Fail() + } + + if !result.IsClosed { + t.Error("Poll did not end") + t.Fail() + } + + if result.Options[0].Text != "Yes" || result.Options[0].VoterCount != 0 || result.Options[1].Text != "No" || result.Options[1].VoterCount != 0 { + t.Error("Poll options were incorrect") + t.Fail() + } +} diff --git a/configs.go b/configs.go index 08a2609..0258d74 100644 --- a/configs.go +++ b/configs.go @@ -499,6 +499,29 @@ func (config ContactConfig) method() string { return "sendContact" } +// SendPollConfig allows you to send a poll. +type SendPollConfig struct { + BaseChat + Question string + Options []string +} + +func (config SendPollConfig) params() (Params, error) { + params, err := config.BaseChat.params() + if err != nil { + return params, err + } + + params["question"] = config.Question + err = params.AddInterface("options", config.Options) + + return params, err +} + +func (SendPollConfig) method() string { + return "sendPoll" +} + // GameConfig allows you to send a game. type GameConfig struct { BaseChat @@ -671,6 +694,19 @@ func (config EditMessageReplyMarkupConfig) method() string { return "editMessageReplyMarkup" } +// StopPollConfig allows you to stop a poll sent by the bot. +type StopPollConfig struct { + BaseEdit +} + +func (config StopPollConfig) params() (Params, error) { + return config.BaseEdit.params() +} + +func (StopPollConfig) method() string { + return "stopPoll" +} + // UserProfilePhotosConfig contains information about a // GetUserProfilePhotos request. type UserProfilePhotosConfig struct { diff --git a/helpers.go b/helpers.go index fea373d..b97aa2a 100644 --- a/helpers.go +++ b/helpers.go @@ -814,3 +814,24 @@ func NewDeleteChatPhoto(chatID int64, photo interface{}) DeleteChatPhotoConfig { ChatID: chatID, } } + +// NewPoll allows you to create a new poll. +func NewPoll(chatID int64, question string, options ...string) SendPollConfig { + return SendPollConfig{ + BaseChat: BaseChat{ + ChatID: chatID, + }, + Question: question, + Options: options, + } +} + +// NewStopPoll allows you to stop a poll. +func NewStopPoll(chatID int64, messageID int) StopPollConfig { + return StopPollConfig{ + BaseEdit{ + ChatID: chatID, + MessageID: messageID, + }, + } +} diff --git a/types.go b/types.go index 8a5326a..a301c3b 100644 --- a/types.go +++ b/types.go @@ -37,6 +37,7 @@ type Update struct { CallbackQuery *CallbackQuery `json:"callback_query"` ShippingQuery *ShippingQuery `json:"shipping_query"` PreCheckoutQuery *PreCheckoutQuery `json:"pre_checkout_query"` + Poll *Poll `json:"poll"` } // UpdatesChannel is the channel for getting updates. @@ -141,6 +142,7 @@ type Message struct { ForwardFromChat *Chat `json:"forward_from_chat"` // optional ForwardFromMessageID int `json:"forward_from_message_id"` // optional ForwardSignature string `json:"forward_signature"` // optional + ForwardSenderName string `json:"forward_sender_name"` // optional ForwardDate int `json:"forward_date"` // optional ReplyToMessage *Message `json:"reply_to_message"` // optional EditDate int `json:"edit_date"` // optional @@ -162,6 +164,7 @@ type Message struct { Contact *Contact `json:"contact"` // optional Location *Location `json:"location"` // optional Venue *Venue `json:"venue"` // optional + Poll *Poll `json:"poll"` // optional NewChatMembers []User `json:"new_chat_members"` // optional LeftChatMember *User `json:"left_chat_member"` // optional NewChatTitle string `json:"new_chat_title"` // optional @@ -385,6 +388,20 @@ type Venue struct { FoursquareID string `json:"foursquare_id"` // optional } +// PollOption contains information about one answer option in a poll. +type PollOption struct { + Text string `json:"text"` + VoterCount int `json:"voter_count"` +} + +// Poll contains information about a poll. +type Poll struct { + ID string `json:"id"` + Question string `json:"question"` + Options []PollOption `json:"options"` + IsClosed bool `json:"is_closed"` +} + // UserProfilePhotos contains a set of user profile photos. type UserProfilePhotos struct { TotalCount int `json:"total_count"` @@ -487,6 +504,7 @@ type ChatMember struct { CanRestrictMembers bool `json:"can_restrict_members,omitempty"` // optional CanPinMessages bool `json:"can_pin_messages,omitempty"` // optional CanPromoteMembers bool `json:"can_promote_members,omitempty"` // optional + IsChatMember bool `json:"is_member"` // optional CanSendMessages bool `json:"can_send_messages,omitempty"` // optional CanSendMediaMessages bool `json:"can_send_media_messages,omitempty"` // optional CanSendOtherMessages bool `json:"can_send_other_messages,omitempty"` // optional