all repos — telegram-bot-api @ 6a6de7e674c96edf22bf9d4fbe45b959b7fb3685

Golang bindings for the Telegram Bot API

Merge master into develop.
Syfaro syfaro@huefox.com
Mon, 26 Mar 2018 12:22:16 -0500
commit

6a6de7e674c96edf22bf9d4fbe45b959b7fb3685

parent

9653a4aad4bed727a828034c0ed5c371aada90af

6 files changed, 169 insertions(+), 43 deletions(-)

jump to
M README.mdREADME.md

@@ -91,6 +91,16 @@ if err != nil {

log.Fatal(err) } + info, err := bot.GetWebhookInfo() + + if err != nil { + log.Fatal(err) + } + + if info.LastErrorDate != 0 { + log.Printf("failed to set webhook: %s", info.LastErrorMessage) + } + updates := bot.ListenForWebhook("/" + bot.Token) go http.ListenAndServeTLS("0.0.0.0:8443", "cert.pem", "key.pem", nil)
M bot.gobot.go

@@ -7,6 +7,7 @@ "bytes"

"encoding/json" "errors" "fmt" + "io" "io/ioutil" "log" "net/http"

@@ -71,26 +72,54 @@ return APIResponse{}, err

} defer resp.Body.Close() - bytes, err := ioutil.ReadAll(resp.Body) + var apiResp APIResponse + bytes, err := bot.decodeAPIResponse(resp.Body, &apiResp) if err != nil { - return APIResponse{}, err + return apiResp, err } if bot.Debug { log.Printf("Endpoint: %s, response: %s\n", endpoint, string(bytes)) } - var apiResp APIResponse - err = json.Unmarshal(bytes, &apiResp) + if !apiResp.Ok { + var parameters ResponseParameters + + if apiResp.Parameters != nil { + parameters = *apiResp.Parameters + } + + return apiResp, Error{ + Message: apiResp.Description, + ResponseParameters: parameters, + } + } + + return apiResp, nil +} + +// decodeAPIResponse decode response and return slice of bytes if debug enabled. +// If debug disabled, just decode http.Response.Body stream to APIResponse struct +// for efficient memory usage +func (bot *BotAPI) decodeAPIResponse(responseBody io.Reader, resp *APIResponse) (_ []byte, err error) { + if !bot.Debug { + dec := json.NewDecoder(responseBody) + err = dec.Decode(resp) + return + } + + // if debug, read reponse body + data, err := ioutil.ReadAll(responseBody) if err != nil { - return APIResponse{}, err + return } - if !apiResp.Ok { - return apiResp, errors.New(apiResp.Description) + err = json.Unmarshal(data, resp) + if err != nil { + return } - return apiResp, nil + return data, nil } // UploadFile makes a request to the API with a file.

@@ -543,3 +572,45 @@ err = json.Unmarshal(resp.Result, &stickers)

return stickers, err } + +// SetChatTitle change title of chat. +func (bot *BotAPI) SetChatTitle(config SetChatTitleConfig) (APIResponse, error) { + v, err := config.values() + if err != nil { + return APIResponse{}, err + } + + return bot.MakeRequest(config.method(), v) +} + +// SetChatDescription change description of chat. +func (bot *BotAPI) SetChatDescription(config SetChatDescriptionConfig) (APIResponse, error) { + v, err := config.values() + if err != nil { + return APIResponse{}, err + } + + return bot.MakeRequest(config.method(), v) +} + +// SetChatPhoto change photo of chat. +func (bot *BotAPI) SetChatPhoto(config SetChatPhotoConfig) (APIResponse, error) { + params, err := config.params() + if err != nil { + return APIResponse{}, err + } + + file := config.getFile() + + return bot.UploadFile(config.method(), params, config.name(), file) +} + +// DeleteChatPhoto delete photo of chat. +func (bot *BotAPI) DeleteChatPhoto(config DeleteChatPhotoConfig) (APIResponse, error) { + v, err := config.values() + if err != nil { + return APIResponse{}, err + } + + return bot.MakeRequest(config.method(), v) +}
M bot_test.gobot_test.go

@@ -476,6 +476,16 @@ t.Error(err)

t.Fail() } + info, err := bot.GetWebhookInfo() + + if err != nil { + t.Error(err) + } + + if info.LastErrorDate != 0 { + t.Errorf("failed to set webhook: %s", info.LastErrorMessage) + } + bot.Request(tgbotapi.RemoveWebhookConfig{}) }

@@ -491,6 +501,16 @@ _, err := bot.Request(wh)

if err != nil { t.Error(err) t.Fail() + } + + info, err := bot.GetWebhookInfo() + + if err != nil { + t.Error(err) + } + + if info.LastErrorDate != 0 { + t.Errorf("failed to set webhook: %s", info.LastErrorMessage) } bot.Request(tgbotapi.RemoveWebhookConfig{})

@@ -558,6 +578,16 @@ if err != nil {

log.Fatal(err) } + info, err := bot.GetWebhookInfo() + + if err != nil { + log.Fatal(err) + } + + if info.LastErrorDate != 0 { + log.Printf("failed to set webhook: %s", info.LastErrorMessage) + } + updates := bot.ListenForWebhook("/" + bot.Token) go http.ListenAndServeTLS("0.0.0.0:8443", "cert.pem", "key.pem", nil)

@@ -566,7 +596,7 @@ log.Printf("%+v\n", update)

} } -func ExampleAnswerInlineQuery() { +func ExampleInlineConfig() { bot, err := tgbotapi.NewBotAPI("MyAwesomeBotToken") // create new bot if err != nil { log.Panic(err)
M configs.goconfigs.go

@@ -720,7 +720,7 @@ UserID int

Score int Force bool DisableEditMessage bool - ChatID int + ChatID int64 ChannelUsername string MessageID int InlineMessageID string

@@ -733,7 +733,7 @@ v.Add("user_id", strconv.Itoa(config.UserID))

v.Add("score", strconv.Itoa(config.Score)) if config.InlineMessageID == "" { if config.ChannelUsername == "" { - v.Add("chat_id", strconv.Itoa(config.ChatID)) + v.Add("chat_id", strconv.FormatInt(config.ChatID, 10)) } else { v.Add("chat_id", config.ChannelUsername) }

@@ -1376,10 +1376,7 @@ }

// SetChatPhotoConfig allows you to set a group, supergroup, or channel's photo. type SetChatPhotoConfig struct { - ChatID int64 - ChannelUsername string - - Photo interface{} + BaseFile } func (config SetChatPhotoConfig) method() string {

@@ -1390,36 +1387,12 @@ func (config SetChatPhotoConfig) name() string {

return "photo" } -func (config SetChatPhotoConfig) values() (url.Values, error) { - v := url.Values{} - - if config.ChannelUsername == "" { - v.Add("chat_id", strconv.FormatInt(config.ChatID, 10)) - } else { - v.Add("chat_id", config.ChannelUsername) - } - - return v, nil -} - -func (config SetChatPhotoConfig) params() map[string]string { - params := make(map[string]string) - - if config.ChannelUsername == "" { - params["chat_id"] = strconv.FormatInt(config.ChatID, 10) - } else { - params["chat_id"] = config.ChannelUsername - } - - return params -} - func (config SetChatPhotoConfig) getFile() interface{} { - return config.Photo + return config.File } func (config SetChatPhotoConfig) useExistingFile() bool { - return false + return config.UseExisting } // DeleteChatPhotoConfig allows you to delete a group, supergroup, or channel's photo.
M helpers.gohelpers.go

@@ -641,7 +641,7 @@ ShowAlert: true,

} } -// NewInvoice created a new Invoice request to the user. +// NewInvoice creates a new Invoice request to the user. func NewInvoice(chatID int64, title, description, payload, providerToken, startParameter, currency string, prices *[]LabeledPrice) InvoiceConfig { return InvoiceConfig{ BaseChat: BaseChat{ChatID: chatID},

@@ -653,3 +653,34 @@ StartParameter: startParameter,

Currency: currency, Prices: prices} } + +// NewSetChatPhotoUpload creates a new chat photo uploader. +// +// chatID is where to send it, file is a string path to the file, +// FileReader, or FileBytes. +// +// Note that you must send animated GIFs as a document. +func NewSetChatPhotoUpload(chatID int64, file interface{}) SetChatPhotoConfig { + return SetChatPhotoConfig{ + BaseFile: BaseFile{ + BaseChat: BaseChat{ChatID: chatID}, + File: file, + UseExisting: false, + }, + } +} + +// NewSetChatPhotoShare shares an existing photo. +// You may use this to reshare an existing photo without reuploading it. +// +// chatID is where to send it, fileID is the ID of the file +// already uploaded. +func NewSetChatPhotoShare(chatID int64, fileID string) SetChatPhotoConfig { + return SetChatPhotoConfig{ + BaseFile: BaseFile{ + BaseChat: BaseChat{ChatID: chatID}, + FileID: fileID, + UseExisting: true, + }, + } +}
M types.gotypes.go

@@ -676,7 +676,7 @@ type InlineQueryResultGame struct {

Type string `json:"type"` ID string `json:"id"` GameShortName string `json:"game_short_name"` - ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup"` + ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"` } // ChosenInlineResult is an inline query result chosen by a User

@@ -819,3 +819,14 @@ Width int `json:"width,omitempty"`

Height int `json:"height,omitempty"` Duration int `json:"duration,omitempty"` } + +// Error is an error containing extra information returned by the Telegram API. +type Error struct { + Message string + ResponseParameters +} + +// Error message string. +func (e Error) Error() string { + return e.Message +}