From 72e84f5ab56cbe52ea331a68bada80e7c67ee5b9 Mon Sep 17 00:00:00 2001 From: Steven Berlanga Date: Thu, 21 Apr 2016 16:31:30 -0400 Subject: [PATCH 1/2] Adding support for inline keyboard buttons --- api.go | 3 ++- bot.go | 26 +++++++++++++++++--------- options.go | 3 +++ types.go | 25 ++++++++++++++++++++++--- 4 files changed, 44 insertions(+), 13 deletions(-) diff --git a/api.go b/api.go index 5a69098..52ad0c9 100644 --- a/api.go +++ b/api.go @@ -111,8 +111,9 @@ func embedSendOptions(params *url.Values, options *SendOptions) { { forceReply := options.ReplyMarkup.ForceReply customKeyboard := (options.ReplyMarkup.CustomKeyboard != nil) + inlineKeyboard := options.ReplyMarkup.InlineKeyboard != nil hiddenKeyboard := options.ReplyMarkup.HideCustomKeyboard - if forceReply || customKeyboard || hiddenKeyboard { + if forceReply || customKeyboard || hiddenKeyboard || inlineKeyboard { replyMarkup, _ := json.Marshal(options.ReplyMarkup) params.Set("reply_markup", string(replyMarkup)) } diff --git a/bot.go b/bot.go index 6c056a0..5475fac 100644 --- a/bot.go +++ b/bot.go @@ -11,10 +11,11 @@ import ( // Bot represents a separate Telegram bot instance. type Bot struct { - Token string - Identity User - Messages chan Message - Queries chan Query + Token string + Identity User + Messages chan Message + Queries chan Query + Callbacks chan Callback } // NewBot does try to build a Bot with token `token`, which @@ -34,18 +35,19 @@ func NewBot(token string) (*Bot, error) { // Listen periodically looks for updates and delivers new messages // to the subscription channel. func (b *Bot) Listen(subscription chan Message, timeout time.Duration) { - go b.poll(subscription, nil, timeout) + go b.poll(subscription, nil, nil, timeout) } // Start periodically polls messages and/or updates to corresponding channels // from the bot object. func (b *Bot) Start(timeout time.Duration) { - b.poll(b.Messages, b.Queries, timeout) + b.poll(b.Messages, b.Queries, b.Callbacks, timeout) } func (b *Bot) poll( messages chan Message, queries chan Query, + callbacks chan Callback, timeout time.Duration, ) { latestUpdate := 0 @@ -62,18 +64,24 @@ func (b *Bot) poll( } for _, update := range updates { - if update.Query == nil /* if message */ { + if update.Payload != nil /* if message */ { if messages == nil { continue } - messages <- update.Payload - } else /* if query */ { + messages <- *update.Payload + } else if update.Query != nil /* if query */ { if queries == nil { continue } queries <- *update.Query + } else if update.Callback != nil { + if callbacks == nil { + continue + } + + callbacks <- *update.Callback } latestUpdate = update.ID diff --git a/options.go b/options.go index 2aca9a6..cae87ea 100644 --- a/options.go +++ b/options.go @@ -40,6 +40,9 @@ type ReplyMarkup struct { // // Note: you don't need to set HideCustomKeyboard field to show custom keyboard. CustomKeyboard [][]string `json:"keyboard,omitempty"` + + InlineKeyboard [][]KeyboardButton `json:"inline_keyboard,omitempty"` + // Requests clients to resize the keyboard vertically for optimal fit // (e.g., make the keyboard smaller if there are just two rows of buttons). // Defaults to false, in which case the custom keyboard is always of the diff --git a/types.go b/types.go index 45ae9f5..7a99348 100644 --- a/types.go +++ b/types.go @@ -54,11 +54,12 @@ func (c Chat) IsGroupChat() bool { // Update object represents an incoming update. type Update struct { - ID int `json:"update_id"` - Payload Message `json:"message"` + ID int `json:"update_id"` + Payload *Message `json:"message"` // optional - Query *Query `json:"inline_query"` + Callback *Callback `json:"callback_query"` + Query *Query `json:"inline_query"` } // Thumbnail object represents an image/sticker of a particular size. @@ -129,6 +130,14 @@ type Video struct { Preview Thumbnail `json:"thumb"` } +// KeyboardButton represents a button displayed on in a message. +type KeyboardButton struct { + Text string `json:"text"` + URL string `json:"url,omitempty"` + Data string `json:"callback_data,omitempty"` + InlineQuery string `json:"switch_inline_query,omitempty"` +} + // Contact object represents a contact to Telegram user type Contact struct { UserID int `json:"user_id"` @@ -142,3 +151,13 @@ type Location struct { Longitude float32 `json:"longitude"` Latitude float32 `json:"latitude"` } + +type Callback struct { + ID string `json:"id"` + // For message sent to channels, Sender may be empty + Sender User `json:"from"` + + Message Message `json:"message"` + + Data string `json:"data"` +} From 4b2c1f976c5a1d63139687695d67d711ba9b2bd9 Mon Sep 17 00:00:00 2001 From: Steven Berlanga Date: Wed, 25 May 2016 09:53:01 -0400 Subject: [PATCH 2/2] adding documentation to callback struct --- types.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/types.go b/types.go index 7a99348..a9744db 100644 --- a/types.go +++ b/types.go @@ -152,12 +152,20 @@ type Location struct { Latitude float32 `json:"latitude"` } +// Callback object represents a query from a callback button in an +// inline keyboard. type Callback struct { ID string `json:"id"` + // For message sent to channels, Sender may be empty Sender User `json:"from"` + // Message will be set if the button that originated the query + // was attached to a message sent by a bot. Message Message `json:"message"` - Data string `json:"data"` + // MessageID will be set if the button was attached to a message + // sent via the bot in inline mode. + MessageID string `json:"inline_message_id"` + Data string `json:"data"` }