fix all golint errors, add info about audio uploads
@@ -1,23 +1,24 @@
-// Methods for interacting with the Telegram Bot API. +// Package tgbotapi has bindings for interacting with the Telegram Bot API. package tgbotapi -type BotApi struct { +// BotAPI has methods for interacting with all of Telegram's Bot API endpoints. +type BotAPI struct { Token string `json:"token"` Debug bool `json:"debug"` Self User `json:"-"` Updates chan Update `json:"-"` } -// Creates a new BotApi instance. +// NewBotAPI creates a new BotAPI instance. // Requires a token, provided by @BotFather on Telegram -func NewBotApi(token string) (*BotApi, error) { - bot := &BotApi{ +func NewBotAPI(token string) (*BotAPI, error) { + bot := &BotAPI{ Token: token, } self, err := bot.GetMe() if err != nil { - return &BotApi{}, err + return &BotAPI{}, err } bot.Self = self
@@ -4,195 +4,195 @@ import (
"net/url" ) -// Creates a new Message. -// Perhaps set a ChatAction of CHAT_TYPING while processing. +// NewMessage creates a new Message. +// Perhaps set a ChatAction of ChatTyping while processing. // -// chatId is where to send it, text is the message text. -func NewMessage(chatId int, text string) MessageConfig { +// chatID is where to send it, text is the message text. +func NewMessage(chatID int, text string) MessageConfig { return MessageConfig{ - ChatId: chatId, + ChatID: chatID, Text: text, DisableWebPagePreview: false, - ReplyToMessageId: 0, + ReplyToMessageID: 0, } } -// Creates a new forward. +// NewForward creates a new forward. // -// chatId is where to send it, fromChatId is the source chat, -// and messageId is the Id of the original message. -func NewForward(chatId int, fromChatId int, messageId int) ForwardConfig { +// chatID is where to send it, fromChatID is the source chat, +// and messageID is the ID of the original message. +func NewForward(chatID int, fromChatID int, messageID int) ForwardConfig { return ForwardConfig{ - ChatId: chatId, - FromChatId: fromChatId, - MessageId: messageId, + ChatID: chatID, + FromChatID: fromChatID, + MessageID: messageID, } } -// Creates a new photo uploader. +// NewPhotoUpload creates a new photo uploader. // This requires a file on the local filesystem to upload to Telegram. -// Perhaps set a ChatAction of CHAT_UPLOAD_PHOTO while processing. +// Perhaps set a ChatAction of ChatUploadPhoto while processing. // -// chatId is where to send it, filename is the path to the file. -func NewPhotoUpload(chatId int, filename string) PhotoConfig { +// chatID is where to send it, filename is the path to the file. +func NewPhotoUpload(chatID int, filename string) PhotoConfig { return PhotoConfig{ - ChatId: chatId, + ChatID: chatID, UseExistingPhoto: false, FilePath: filename, } } -// Shares an existing photo. +// NewPhotoShare 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 NewPhotoShare(chatId int, fileId string) PhotoConfig { +// chatID is where to send it, fileID is the ID of the file already uploaded. +func NewPhotoShare(chatID int, fileID string) PhotoConfig { return PhotoConfig{ - ChatId: chatId, + ChatID: chatID, UseExistingPhoto: true, - FileId: fileId, + FileID: fileID, } } -// Creates a new audio uploader. +// NewAudioUpload creates a new audio uploader. // This requires a file on the local filesystem to upload to Telegram. -// Perhaps set a ChatAction of CHAT_RECORD_AUDIO or CHAT_UPLOAD_AUDIO while processing. +// Perhaps set a ChatAction of ChatRecordAudio or ChatUploadAudio while processing. // -// chatId is where to send it, filename is the path to the file. -func NewAudioUpload(chatId int, filename string) AudioConfig { +// chatID is where to send it, filename is the path to the file. +func NewAudioUpload(chatID int, filename string) AudioConfig { return AudioConfig{ - ChatId: chatId, + ChatID: chatID, UseExistingAudio: false, FilePath: filename, } } -// Shares an existing audio file. +// NewAudioShare shares an existing audio file. // You may use this to reshare an existing audio file without reuploading it. // -// chatId is where to send it, fileId is the Id of the audio already uploaded. -func NewAudioShare(chatId int, fileId string) AudioConfig { +// chatID is where to send it, fileID is the ID of the audio already uploaded. +func NewAudioShare(chatID int, fileID string) AudioConfig { return AudioConfig{ - ChatId: chatId, + ChatID: chatID, UseExistingAudio: true, - FileId: fileId, + FileID: fileID, } } -// Creates a new document uploader. +// NewDocumentUpload creates a new document uploader. // This requires a file on the local filesystem to upload to Telegram. -// Perhaps set a ChatAction of CHAT_UPLOAD_DOCUMENT while processing. +// Perhaps set a ChatAction of ChatUploadDocument while processing. // -// chatId is where to send it, filename is the path to the file. -func NewDocumentUpload(chatId int, filename string) DocumentConfig { +// chatID is where to send it, filename is the path to the file. +func NewDocumentUpload(chatID int, filename string) DocumentConfig { return DocumentConfig{ - ChatId: chatId, + ChatID: chatID, UseExistingDocument: false, FilePath: filename, } } -// Shares an existing document. +// NewDocumentShare shares an existing document. // You may use this to reshare an existing document without reuploading it. // -// chatId is where to send it, fileId is the Id of the document already uploaded. -func NewDocumentShare(chatId int, fileId string) DocumentConfig { +// chatID is where to send it, fileID is the ID of the document already uploaded. +func NewDocumentShare(chatID int, fileID string) DocumentConfig { return DocumentConfig{ - ChatId: chatId, + ChatID: chatID, UseExistingDocument: true, - FileId: fileId, + FileID: fileID, } } -// Creates a new sticker uploader. +// NewStickerUpload creates a new sticker uploader. // This requires a file on the local filesystem to upload to Telegram. // -// chatId is where to send it, filename is the path to the file. -func NewStickerUpload(chatId int, filename string) StickerConfig { +// chatID is where to send it, filename is the path to the file. +func NewStickerUpload(chatID int, filename string) StickerConfig { return StickerConfig{ - ChatId: chatId, + ChatID: chatID, UseExistingSticker: false, FilePath: filename, } } -// Shares an existing sticker. +// NewStickerShare shares an existing sticker. // You may use this to reshare an existing sticker without reuploading it. // -// chatId is where to send it, fileId is the Id of the sticker already uploaded. -func NewStickerShare(chatId int, fileId string) StickerConfig { +// chatID is where to send it, fileID is the ID of the sticker already uploaded. +func NewStickerShare(chatID int, fileID string) StickerConfig { return StickerConfig{ - ChatId: chatId, + ChatID: chatID, UseExistingSticker: true, - FileId: fileId, + FileID: fileID, } } -// Creates a new video uploader. +// NewVideoUpload creates a new video uploader. // This requires a file on the local filesystem to upload to Telegram. -// Perhaps set a ChatAction of CHAT_RECORD_VIDEO or CHAT_UPLOAD_VIDEO while processing. +// Perhaps set a ChatAction of ChatRecordVideo or ChatUploadVideo while processing. // -// chatId is where to send it, filename is the path to the file. -func NewVideoUpload(chatId int, filename string) VideoConfig { +// chatID is where to send it, filename is the path to the file. +func NewVideoUpload(chatID int, filename string) VideoConfig { return VideoConfig{ - ChatId: chatId, + ChatID: chatID, UseExistingVideo: false, FilePath: filename, } } -// Shares an existing video. +// NewVideoShare shares an existing video. // You may use this to reshare an existing video without reuploading it. // -// chatId is where to send it, fileId is the Id of the video already uploaded. -func NewVideoShare(chatId int, fileId string) VideoConfig { +// chatID is where to send it, fileID is the ID of the video already uploaded. +func NewVideoShare(chatID int, fileID string) VideoConfig { return VideoConfig{ - ChatId: chatId, + ChatID: chatID, UseExistingVideo: true, - FileId: fileId, + FileID: fileID, } } -// Shares your location. -// Perhaps set a ChatAction of CHAT_FIND_LOCATION while processing. +// NewLocation shares your location. +// Perhaps set a ChatAction of ChatFindLocation while processing. // -// chatId is where to send it, latitude and longitude are coordinates. -func NewLocation(chatId int, latitude float64, longitude float64) LocationConfig { +// chatID is where to send it, latitude and longitude are coordinates. +func NewLocation(chatID int, latitude float64, longitude float64) LocationConfig { return LocationConfig{ - ChatId: chatId, + ChatID: chatID, Latitude: latitude, Longitude: longitude, - ReplyToMessageId: 0, + ReplyToMessageID: 0, ReplyMarkup: nil, } } -// Sets a chat action. +// NewChatAction sets a chat action. // Actions last for 5 seconds, or until your next action. // -// chatId is where to send it, action should be set via CHAT constants. -func NewChatAction(chatId int, action string) ChatActionConfig { +// chatID is where to send it, action should be set via CHAT constants. +func NewChatAction(chatID int, action string) ChatActionConfig { return ChatActionConfig{ - ChatId: chatId, + ChatID: chatID, Action: action, } } -// Gets user profile photos. +// NewUserProfilePhotos gets user profile photos. // -// userId is the Id of the user you wish to get profile photos from. -func NewUserProfilePhotos(userId int) UserProfilePhotosConfig { +// userID is the ID of the user you wish to get profile photos from. +func NewUserProfilePhotos(userID int) UserProfilePhotosConfig { return UserProfilePhotosConfig{ - UserId: userId, + UserID: userID, Offset: 0, Limit: 0, } } -// Gets updates since the last Offset. +// NewUpdate gets updates since the last Offset. // -// offset is the last Update Id to include. -// You likely want to set this to the last Update Id plus 1. +// offset is the last Update ID to include. +// You likely want to set this to the last Update ID plus 1. func NewUpdate(offset int) UpdateConfig { return UpdateConfig{ Offset: offset,@@ -201,14 +201,14 @@ Timeout: 0,
} } -// Creates a new webhook. +// NewWebhook creates a new webhook. // // link is the url parsable link you wish to get the updates. func NewWebhook(link string) WebhookConfig { u, _ := url.Parse(link) return WebhookConfig{ - Url: u, + URL: u, Clear: false, } }
@@ -14,163 +14,176 @@ "os"
"strconv" ) +// Constant values for ChatActions const ( - CHAT_TYPING = "typing" - CHAT_UPLOAD_PHOTO = "upload_photo" - CHAT_RECORD_VIDEO = "record_video" - CHAT_UPLOAD_VIDEO = "upload_video" - CHAT_RECORD_AUDIO = "record_audio" - CHAT_UPLOAD_AUDIO = "upload_audio" - CHAT_UPLOAD_DOCUMENT = "upload_document" - CHAT_FIND_LOCATION = "find_location" + ChatTyping = "typing" + ChatUploadPhoto = "upload_photo" + ChatRecordVideo = "record_video" + ChatUploadVideo = "upload_video" + ChatRecordAudio = "record_audio" + ChatUploadAudio = "upload_audio" + ChatUploadDocument = "upload_document" + ChatFindLocation = "find_location" ) +// MessageConfig contains information about a SendMessage request. type MessageConfig struct { - ChatId int + ChatID int Text string DisableWebPagePreview bool - ReplyToMessageId int + ReplyToMessageID int ReplyMarkup interface{} } +// ForwardConfig contains infomation about a ForwardMessage request. type ForwardConfig struct { - ChatId int - FromChatId int - MessageId int + ChatID int + FromChatID int + MessageID int } +// PhotoConfig contains information about a SendPhoto request. type PhotoConfig struct { - ChatId int + ChatID int Caption string - ReplyToMessageId int + ReplyToMessageID int ReplyMarkup interface{} UseExistingPhoto bool FilePath string - FileId string + FileID string } +// AudioConfig contains information about a SendAudio request. type AudioConfig struct { - ChatId int - ReplyToMessageId int + ChatID int + ReplyToMessageID int ReplyMarkup interface{} UseExistingAudio bool FilePath string - FileId string + FileID string } +// DocumentConfig contains information about a SendDocument request. type DocumentConfig struct { - ChatId int - ReplyToMessageId int + ChatID int + ReplyToMessageID int ReplyMarkup interface{} UseExistingDocument bool FilePath string - FileId string + FileID string } +// StickerConfig contains information about a SendSticker request. type StickerConfig struct { - ChatId int - ReplyToMessageId int + ChatID int + ReplyToMessageID int ReplyMarkup interface{} UseExistingSticker bool FilePath string - FileId string + FileID string } +// VideoConfig contains information about a SendVideo request. type VideoConfig struct { - ChatId int - ReplyToMessageId int + ChatID int + ReplyToMessageID int ReplyMarkup interface{} UseExistingVideo bool FilePath string - FileId string + FileID string } +// LocationConfig contains information about a SendLocation request. type LocationConfig struct { - ChatId int + ChatID int Latitude float64 Longitude float64 - ReplyToMessageId int + ReplyToMessageID int ReplyMarkup interface{} } +// ChatActionConfig contains information about a SendChatAction request. type ChatActionConfig struct { - ChatId int + ChatID int Action string } +// UserProfilePhotosConfig contains information about a GetUserProfilePhotos request. type UserProfilePhotosConfig struct { - UserId int + UserID int Offset int Limit int } +// UpdateConfig contains information about a GetUpdates request. type UpdateConfig struct { Offset int Limit int Timeout int } +// WebhookConfig contains information about a SetWebhook request. type WebhookConfig struct { Clear bool - Url *url.URL + URL *url.URL } -// Makes a request to a specific endpoint with our token. +// MakeRequest makes a request to a specific endpoint with our token. // All requests are POSTs because Telegram doesn't care, and it's easier. -func (bot *BotApi) MakeRequest(endpoint string, params url.Values) (ApiResponse, error) { +func (bot *BotAPI) MakeRequest(endpoint string, params url.Values) (APIResponse, error) { resp, err := http.PostForm("https://api.telegram.org/bot"+bot.Token+"/"+endpoint, params) defer resp.Body.Close() if err != nil { - return ApiResponse{}, err + return APIResponse{}, err } bytes, err := ioutil.ReadAll(resp.Body) if err != nil { - return ApiResponse{}, err + return APIResponse{}, err } if bot.Debug { log.Println(endpoint, string(bytes)) } - var apiResp ApiResponse + var apiResp APIResponse json.Unmarshal(bytes, &apiResp) if !apiResp.Ok { - return ApiResponse{}, errors.New(apiResp.Description) + return APIResponse{}, errors.New(apiResp.Description) } return apiResp, nil } -// Makes a request to the API with a file. +// UploadFile makes a request to the API with a file. // // Requires the parameter to hold the file not be in the params. -func (bot *BotApi) UploadFile(endpoint string, params map[string]string, fieldname string, filename string) (ApiResponse, error) { +func (bot *BotAPI) UploadFile(endpoint string, params map[string]string, fieldname string, filename string) (APIResponse, error) { var b bytes.Buffer w := multipart.NewWriter(&b) f, err := os.Open(filename) if err != nil { - return ApiResponse{}, err + return APIResponse{}, err } fw, err := w.CreateFormFile(fieldname, filename) if err != nil { - return ApiResponse{}, err + return APIResponse{}, err } if _, err = io.Copy(fw, f); err != nil { - return ApiResponse{}, err + return APIResponse{}, err } for key, val := range params { if fw, err = w.CreateFormField(key); err != nil { - return ApiResponse{}, err + return APIResponse{}, err } if _, err = fw.Write([]byte(val)); err != nil { - return ApiResponse{}, err + return APIResponse{}, err } }@@ -178,7 +191,7 @@ w.Close()
req, err := http.NewRequest("POST", "https://api.telegram.org/bot"+bot.Token+"/"+endpoint, &b) if err != nil { - return ApiResponse{}, err + return APIResponse{}, err } req.Header.Set("Content-Type", w.FormDataContentType())@@ -186,28 +199,28 @@
client := &http.Client{} res, err := client.Do(req) if err != nil { - return ApiResponse{}, err + return APIResponse{}, err } bytes, err := ioutil.ReadAll(res.Body) if err != nil { - return ApiResponse{}, err + return APIResponse{}, err } if bot.Debug { log.Println(string(bytes[:])) } - var apiResp ApiResponse + var apiResp APIResponse json.Unmarshal(bytes, &apiResp) return apiResp, nil } -// Fetches the currently authenticated bot. +// GetMe fetches the currently authenticated bot. // // There are no parameters for this method. -func (bot *BotApi) GetMe() (User, error) { +func (bot *BotAPI) GetMe() (User, error) { resp, err := bot.MakeRequest("getMe", nil) if err != nil { return User{}, err@@ -223,17 +236,17 @@
return user, nil } -// Sends a Message to a chat. +// SendMessage sends a Message to a chat. // -// Requires ChatId and Text. -// DisableWebPagePreview, ReplyToMessageId, and ReplyMarkup are optional. -func (bot *BotApi) SendMessage(config MessageConfig) (Message, error) { +// Requires ChatID and Text. +// DisableWebPagePreview, ReplyToMessageID, and ReplyMarkup are optional. +func (bot *BotAPI) SendMessage(config MessageConfig) (Message, error) { v := url.Values{} - v.Add("chat_id", strconv.Itoa(config.ChatId)) + v.Add("chat_id", strconv.Itoa(config.ChatID)) v.Add("text", config.Text) v.Add("disable_web_page_preview", strconv.FormatBool(config.DisableWebPagePreview)) - if config.ReplyToMessageId != 0 { - v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageId)) + if config.ReplyToMessageID != 0 { + v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageID)) } if config.ReplyMarkup != nil { data, err := json.Marshal(config.ReplyMarkup)@@ -260,14 +273,14 @@
return message, nil } -// Forwards a message from one chat to another. +// ForwardMessage forwards a message from one chat to another. // -// Requires ChatId (destionation), FromChatId (source), and MessageId. -func (bot *BotApi) ForwardMessage(config ForwardConfig) (Message, error) { +// Requires ChatID (destionation), FromChatID (source), and MessageID. +func (bot *BotAPI) ForwardMessage(config ForwardConfig) (Message, error) { v := url.Values{} - v.Add("chat_id", strconv.Itoa(config.ChatId)) - v.Add("from_chat_id", strconv.Itoa(config.FromChatId)) - v.Add("message_id", strconv.Itoa(config.MessageId)) + v.Add("chat_id", strconv.Itoa(config.ChatID)) + v.Add("from_chat_id", strconv.Itoa(config.FromChatID)) + v.Add("message_id", strconv.Itoa(config.MessageID)) resp, err := bot.MakeRequest("forwardMessage", v) if err != nil {@@ -285,20 +298,20 @@
return message, nil } -// Sends or uploads a photo to a chat. +// SendPhoto sends or uploads a photo to a chat. // -// Requires ChatId and FileId OR FilePath. -// Caption, ReplyToMessageId, and ReplyMarkup are optional. -func (bot *BotApi) SendPhoto(config PhotoConfig) (Message, error) { +// Requires ChatID and FileID OR FilePath. +// Caption, ReplyToMessageID, and ReplyMarkup are optional. +func (bot *BotAPI) SendPhoto(config PhotoConfig) (Message, error) { if config.UseExistingPhoto { v := url.Values{} - v.Add("chat_id", strconv.Itoa(config.ChatId)) - v.Add("photo", config.FileId) + v.Add("chat_id", strconv.Itoa(config.ChatID)) + v.Add("photo", config.FileID) if config.Caption != "" { v.Add("caption", config.Caption) } - if config.ReplyToMessageId != 0 { - v.Add("reply_to_message_id", strconv.Itoa(config.ChatId)) + if config.ReplyToMessageID != 0 { + v.Add("reply_to_message_id", strconv.Itoa(config.ChatID)) } if config.ReplyMarkup != nil { data, err := json.Marshal(config.ReplyMarkup)@@ -326,12 +339,12 @@ return message, nil
} params := make(map[string]string) - params["chat_id"] = strconv.Itoa(config.ChatId) + params["chat_id"] = strconv.Itoa(config.ChatID) if config.Caption != "" { params["caption"] = config.Caption } - if config.ReplyToMessageId != 0 { - params["reply_to_message_id"] = strconv.Itoa(config.ReplyToMessageId) + if config.ReplyToMessageID != 0 { + params["reply_to_message_id"] = strconv.Itoa(config.ReplyToMessageID) } if config.ReplyMarkup != nil { data, err := json.Marshal(config.ReplyMarkup)@@ -357,17 +370,18 @@
return message, nil } -// Sends or uploads an audio clip to a chat. +// SendAudio sends or uploads an audio clip to a chat. +// If using a file, the file must be encoded as an .ogg with OPUS. // -// Requires ChatId and FileId OR FilePath. -// ReplyToMessageId and ReplyMarkup are optional. -func (bot *BotApi) SendAudio(config AudioConfig) (Message, error) { +// Requires ChatID and FileID OR FilePath. +// ReplyToMessageID and ReplyMarkup are optional. +func (bot *BotAPI) SendAudio(config AudioConfig) (Message, error) { if config.UseExistingAudio { v := url.Values{} - v.Add("chat_id", strconv.Itoa(config.ChatId)) - v.Add("audio", config.FileId) - if config.ReplyToMessageId != 0 { - v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageId)) + v.Add("chat_id", strconv.Itoa(config.ChatID)) + v.Add("audio", config.FileID) + if config.ReplyToMessageID != 0 { + v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageID)) } if config.ReplyMarkup != nil { data, err := json.Marshal(config.ReplyMarkup)@@ -396,9 +410,9 @@ }
params := make(map[string]string) - params["chat_id"] = strconv.Itoa(config.ChatId) - if config.ReplyToMessageId != 0 { - params["reply_to_message_id"] = strconv.Itoa(config.ReplyToMessageId) + params["chat_id"] = strconv.Itoa(config.ChatID) + if config.ReplyToMessageID != 0 { + params["reply_to_message_id"] = strconv.Itoa(config.ReplyToMessageID) } if config.ReplyMarkup != nil { data, err := json.Marshal(config.ReplyMarkup)@@ -424,17 +438,17 @@
return message, nil } -// Sends or uploads a document to a chat. +// SendDocument sends or uploads a document to a chat. // -// Requires ChatId and FileId OR FilePath. -// ReplyToMessageId and ReplyMarkup are optional. -func (bot *BotApi) SendDocument(config DocumentConfig) (Message, error) { +// Requires ChatID and FileID OR FilePath. +// ReplyToMessageID and ReplyMarkup are optional. +func (bot *BotAPI) SendDocument(config DocumentConfig) (Message, error) { if config.UseExistingDocument { v := url.Values{} - v.Add("chat_id", strconv.Itoa(config.ChatId)) - v.Add("document", config.FileId) - if config.ReplyToMessageId != 0 { - v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageId)) + v.Add("chat_id", strconv.Itoa(config.ChatID)) + v.Add("document", config.FileID) + if config.ReplyToMessageID != 0 { + v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageID)) } if config.ReplyMarkup != nil { data, err := json.Marshal(config.ReplyMarkup)@@ -463,9 +477,9 @@ }
params := make(map[string]string) - params["chat_id"] = strconv.Itoa(config.ChatId) - if config.ReplyToMessageId != 0 { - params["reply_to_message_id"] = strconv.Itoa(config.ReplyToMessageId) + params["chat_id"] = strconv.Itoa(config.ChatID) + if config.ReplyToMessageID != 0 { + params["reply_to_message_id"] = strconv.Itoa(config.ReplyToMessageID) } if config.ReplyMarkup != nil { data, err := json.Marshal(config.ReplyMarkup)@@ -491,17 +505,17 @@
return message, nil } -// Sends or uploads a sticker to a chat. +// SendSticker sends or uploads a sticker to a chat. // -// Requires ChatId and FileId OR FilePath. -// ReplyToMessageId and ReplyMarkup are optional. -func (bot *BotApi) SendSticker(config StickerConfig) (Message, error) { +// Requires ChatID and FileID OR FilePath. +// ReplyToMessageID and ReplyMarkup are optional. +func (bot *BotAPI) SendSticker(config StickerConfig) (Message, error) { if config.UseExistingSticker { v := url.Values{} - v.Add("chat_id", strconv.Itoa(config.ChatId)) - v.Add("sticker", config.FileId) - if config.ReplyToMessageId != 0 { - v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageId)) + v.Add("chat_id", strconv.Itoa(config.ChatID)) + v.Add("sticker", config.FileID) + if config.ReplyToMessageID != 0 { + v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageID)) } if config.ReplyMarkup != nil { data, err := json.Marshal(config.ReplyMarkup)@@ -530,9 +544,9 @@ }
params := make(map[string]string) - params["chat_id"] = strconv.Itoa(config.ChatId) - if config.ReplyToMessageId != 0 { - params["reply_to_message_id"] = strconv.Itoa(config.ReplyToMessageId) + params["chat_id"] = strconv.Itoa(config.ChatID) + if config.ReplyToMessageID != 0 { + params["reply_to_message_id"] = strconv.Itoa(config.ReplyToMessageID) } if config.ReplyMarkup != nil { data, err := json.Marshal(config.ReplyMarkup)@@ -558,17 +572,17 @@
return message, nil } -// Sends or uploads a video to a chat. +// SendVideo sends or uploads a video to a chat. // -// Requires ChatId and FileId OR FilePath. -// ReplyToMessageId and ReplyMarkup are optional. -func (bot *BotApi) SendVideo(config VideoConfig) (Message, error) { +// Requires ChatID and FileID OR FilePath. +// ReplyToMessageID and ReplyMarkup are optional. +func (bot *BotAPI) SendVideo(config VideoConfig) (Message, error) { if config.UseExistingVideo { v := url.Values{} - v.Add("chat_id", strconv.Itoa(config.ChatId)) - v.Add("video", config.FileId) - if config.ReplyToMessageId != 0 { - v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageId)) + v.Add("chat_id", strconv.Itoa(config.ChatID)) + v.Add("video", config.FileID) + if config.ReplyToMessageID != 0 { + v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageID)) } if config.ReplyMarkup != nil { data, err := json.Marshal(config.ReplyMarkup)@@ -597,9 +611,9 @@ }
params := make(map[string]string) - params["chat_id"] = strconv.Itoa(config.ChatId) - if config.ReplyToMessageId != 0 { - params["reply_to_message_id"] = strconv.Itoa(config.ReplyToMessageId) + params["chat_id"] = strconv.Itoa(config.ChatID) + if config.ReplyToMessageID != 0 { + params["reply_to_message_id"] = strconv.Itoa(config.ReplyToMessageID) } if config.ReplyMarkup != nil { data, err := json.Marshal(config.ReplyMarkup)@@ -625,17 +639,17 @@
return message, nil } -// Sends a location to a chat. +// SendLocation sends a location to a chat. // -// Requires ChatId, Latitude, and Longitude. -// ReplyToMessageId and ReplyMarkup are optional. -func (bot *BotApi) SendLocation(config LocationConfig) (Message, error) { +// Requires ChatID, Latitude, and Longitude. +// ReplyToMessageID and ReplyMarkup are optional. +func (bot *BotAPI) SendLocation(config LocationConfig) (Message, error) { v := url.Values{} - v.Add("chat_id", strconv.Itoa(config.ChatId)) + v.Add("chat_id", strconv.Itoa(config.ChatID)) v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64)) v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64)) - if config.ReplyToMessageId != 0 { - v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageId)) + if config.ReplyToMessageID != 0 { + v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageID)) } if config.ReplyMarkup != nil { data, err := json.Marshal(config.ReplyMarkup)@@ -662,12 +676,12 @@
return message, nil } -// Sets a current action in a chat. +// SendChatAction sets a current action in a chat. // -// Requires ChatId and a valid Action (see CHAT constants). -func (bot *BotApi) SendChatAction(config ChatActionConfig) error { +// Requires ChatID and a valid Action (see Chat constants). +func (bot *BotAPI) SendChatAction(config ChatActionConfig) error { v := url.Values{} - v.Add("chat_id", strconv.Itoa(config.ChatId)) + v.Add("chat_id", strconv.Itoa(config.ChatID)) v.Add("action", config.Action) _, err := bot.MakeRequest("sendChatAction", v)@@ -678,13 +692,13 @@
return nil } -// Gets a user's profile photos. +// GetUserProfilePhotos gets a user's profile photos. // -// Requires UserId. +// Requires UserID. // Offset and Limit are optional. -func (bot *BotApi) GetUserProfilePhotos(config UserProfilePhotosConfig) (UserProfilePhotos, error) { +func (bot *BotAPI) GetUserProfilePhotos(config UserProfilePhotosConfig) (UserProfilePhotos, error) { v := url.Values{} - v.Add("user_id", strconv.Itoa(config.UserId)) + v.Add("user_id", strconv.Itoa(config.UserID)) if config.Offset != 0 { v.Add("offset", strconv.Itoa(config.Offset)) }@@ -708,13 +722,13 @@
return profilePhotos, nil } -// Fetches updates. +// GetUpdates fetches updates. // If a WebHook is set, this will not return any data! // // Offset, Limit, and Timeout are optional. // To not get old items, set Offset to one higher than the previous item. // Set Timeout to a large number to reduce requests and get responses instantly. -func (bot *BotApi) GetUpdates(config UpdateConfig) ([]Update, error) { +func (bot *BotAPI) GetUpdates(config UpdateConfig) ([]Update, error) { v := url.Values{} if config.Offset > 0 { v.Add("offset", strconv.Itoa(config.Offset))@@ -741,14 +755,14 @@
return updates, nil } -// Sets a webhook. +// SetWebhook sets a webhook. // If this is set, GetUpdates will not get any data! // // Requires Url OR to set Clear to true. -func (bot *BotApi) SetWebhook(config WebhookConfig) error { +func (bot *BotAPI) SetWebhook(config WebhookConfig) error { v := url.Values{} if !config.Clear { - v.Add("url", config.Url.String()) + v.Add("url", config.URL.String()) } _, err := bot.MakeRequest("setWebhook", v)
@@ -4,40 +4,46 @@ import (
"encoding/json" ) -type ApiResponse struct { +// APIResponse is a response from the Telegram API with the result stored raw. +type APIResponse struct { Ok bool `json:"ok"` Result json.RawMessage `json:"result"` ErrorCode int `json:"error_code"` Description string `json:"description"` } +// Update is an update response, from GetUpdates. type Update struct { - UpdateId int `json:"update_id"` + UpdateID int `json:"update_id"` Message Message `json:"message"` } +// User is a user, contained in Message and returned by GetSelf. type User struct { - Id int `json:"id"` + ID int `json:"id"` FirstName string `json:"first_name"` LastName string `json:"last_name"` UserName string `json:"username"` } +// GroupChat is a group chat, and not currently in use. type GroupChat struct { - Id int `json:"id"` + ID int `json:"id"` Title string `json:"title"` } +// UserOrGroupChat is returned in Message, because it's not clear which it is. type UserOrGroupChat struct { - Id int `json:"id"` + ID int `json:"id"` FirstName string `json:"first_name"` LastName string `json:"last_name"` UserName string `json:"username"` Title string `json:"title"` } +// Message is returned by almost every request, and contains data about almost anything. type Message struct { - MessageId int `json:"message_id"` + MessageID int `json:"message_id"` From User `json:"from"` Date int `json:"date"` Chat UserOrGroupChat `json:"chat"`@@ -60,64 +66,73 @@ DeleteChatPhoto bool `json:"delete_chat_photo"`
GroupChatCreated bool `json:"group_chat_created"` } +// PhotoSize contains information about photos, including ID and Width and Height. type PhotoSize struct { - FileId string `json:"file_id"` + FileID string `json:"file_id"` Width int `json:"width"` Height int `json:"height"` FileSize int `json:"file_size"` } +// Audio contains information about audio, including ID and Duration. type Audio struct { - FileId string `json:"file_id"` + FileID string `json:"file_id"` Duration int `json:"duration"` MimeType string `json:"mime_type"` FileSize int `json:"file_size"` } +// Document contains information about a document, including ID and a Thumbnail. type Document struct { - FileId string `json:"file_id"` - Thumb PhotoSize `json:"thumb"` - FileName string `json:"file_name"` - MimeType string `json:"mime_type"` - FileSize int `json:"file_size"` + FileID string `json:"file_id"` + Thumbnail PhotoSize `json:"thumb"` + FileName string `json:"file_name"` + MimeType string `json:"mime_type"` + FileSize int `json:"file_size"` } +// Sticker contains information about a sticker, including ID and Thumbnail. type Sticker struct { - FileId string `json:"file_id"` - Width int `json:"width"` - Height int `json:"height"` - Thumb PhotoSize `json:"thumb"` - FileSize int `json:"file_size"` + FileID string `json:"file_id"` + Width int `json:"width"` + Height int `json:"height"` + Thumbnail PhotoSize `json:"thumb"` + FileSize int `json:"file_size"` } +// Video contains information about a video, including ID and duration and Thumbnail. type Video struct { - FileId string `json:"file_id"` - Width int `json:"width"` - Height int `json:"height"` - Duration int `json:"duration"` - Thumb PhotoSize `json:"thumb"` - MimeType string `json:"mime_type"` - FileSize int `json:"file_size"` - Caption string `json:"caption"` + FileID string `json:"file_id"` + Width int `json:"width"` + Height int `json:"height"` + Duration int `json:"duration"` + Thumbnail PhotoSize `json:"thumb"` + MimeType string `json:"mime_type"` + FileSize int `json:"file_size"` + Caption string `json:"caption"` } +// Contact contains information about a contact, such as PhoneNumber and UserId. type Contact struct { PhoneNumber string `json:"phone_number"` FirstName string `json:"first_name"` LastName string `json:"last_name"` - UserId string `json:"user_id"` + UserID string `json:"user_id"` } +// Location contains information about a place, such as Longitude and Latitude. type Location struct { Longitude float32 `json:"longitude"` Latitude float32 `json:"latitude"` } +// UserProfilePhotos contains information a set of user profile photos. type UserProfilePhotos struct { TotalCount int `json:"total_count"` Photos []PhotoSize `json:"photos"` } +// ReplyKeyboardMarkup allows the Bot to set a custom keyboard. type ReplyKeyboardMarkup struct { Keyboard [][]string `json:"keyboard"` ResizeKeyboard bool `json:"resize_keyboard"`@@ -125,11 +140,13 @@ OneTimeKeyboard bool `json:"one_time_keyboard"`
Selective bool `json:"selective"` } +// ReplyKeyboardHide allows the Bot to hide a custom keyboard. type ReplyKeyboardHide struct { HideKeyboard bool `json:"hide_keyboard"` Selective bool `json:"selective"` } +// ForceReply allows the Bot to have users directly reply to it without additional interaction. type ForceReply struct { ForceReply bool `json:"force_reply"` Selective bool `json:"force_reply"`
@@ -1,7 +1,7 @@
package tgbotapi -// Returns a chan that is called whenever a new message is gotten. -func (bot *BotApi) UpdatesChan(config UpdateConfig) (chan Update, error) { +// UpdatesChan returns a chan that is called whenever a new message is gotten. +func (bot *BotAPI) UpdatesChan(config UpdateConfig) (chan Update, error) { bot.Updates = make(chan Update, 100) go func() {@@ -11,8 +11,8 @@ panic(err)
} for _, update := range updates { - if update.UpdateId > config.Offset { - config.Offset = update.UpdateId + 1 + if update.UpdateID > config.Offset { + config.Offset = update.UpdateID + 1 } bot.Updates <- update