all repos — telegram-bot-api @ 434756c165a9b43d750eb56e6a4eaff067f1bcbb

Golang bindings for the Telegram Bot API

methods.go (view raw)

  1package main
  2
  3import (
  4	"encoding/json"
  5	"io/ioutil"
  6	"log"
  7	"net/http"
  8	"net/url"
  9	"strconv"
 10)
 11
 12const (
 13	CHAT_TYPING          = "typing"
 14	CHAT_UPLOAD_PHOTO    = "upload_photo"
 15	CHAT_RECORD_VIDEO    = "record_video"
 16	CHAT_UPLOAD_VIDEO    = "upload_video"
 17	CHAT_RECORD_AUDIO    = "record_audio"
 18	CHAT_UPLOAD_AUDIO    = "upload_audio"
 19	CHAT_UPLOAD_DOCUMENT = "upload_document"
 20	CHAT_FIND_LOCATION   = "find_location"
 21)
 22
 23type BotConfig struct {
 24	token string
 25	debug bool
 26}
 27
 28type BotApi struct {
 29	config BotConfig
 30}
 31
 32type ApiResponse struct {
 33	Ok     bool            `json:"ok"`
 34	Result json.RawMessage `json:"result"`
 35}
 36
 37type Update struct {
 38	UpdateId int     `json:"update_id"`
 39	Message  Message `json:"message"`
 40}
 41
 42type User struct {
 43	Id        int    `json:"id"`
 44	FirstName string `json:"first_name"`
 45	LastName  string `json:"last_name"`
 46	UserName  string `json:"username"`
 47}
 48
 49type GroupChat struct {
 50	Id    int    `json:"id"`
 51	Title string `json:"title"`
 52}
 53
 54type UserOrGroupChat struct {
 55	Id        int    `json:"id"`
 56	FirstName string `json:"first_name"`
 57	LastName  string `json:"last_name"`
 58	UserName  string `json:"username"`
 59	Title     string `json:"title"`
 60}
 61
 62type Message struct {
 63	MessageId           int             `json:"message_id"`
 64	From                User            `json:"from"`
 65	Date                int             `json:"date"`
 66	Chat                UserOrGroupChat `json:"chat"`
 67	ForwardFrom         User            `json:"forward_from"`
 68	ForwardDate         int             `json:"forward_date"`
 69	ReplyToMessage      *Message        `json:"reply_to_message"`
 70	Text                string          `json:"text"`
 71	Audio               Audio           `json:"audio"`
 72	Document            Document        `json:"document"`
 73	Photo               []PhotoSize     `json:"photo"`
 74	Sticker             Sticker         `json:"sticker"`
 75	Video               Video           `json:"video"`
 76	Contact             Contact         `json:"contact"`
 77	Location            Location        `json:"location"`
 78	NewChatParticipant  User            `json:"new_chat_participant"`
 79	LeftChatParticipant User            `json:"left_chat_participant"`
 80	NewChatTitle        string          `json:"new_chat_title"`
 81	NewChatPhoto        string          `json:"new_chat_photo"`
 82	DeleteChatPhoto     bool            `json:"delete_chat_photo"`
 83	GroupChatCreated    bool            `json:"group_chat_created"`
 84}
 85
 86type PhotoSize struct {
 87	FileId   string `json:"file_id"`
 88	Width    int    `json:"width"`
 89	Height   int    `json:"height"`
 90	FileSize int    `json:"file_size"`
 91}
 92
 93type Audio struct {
 94	FileId   string `json:"file_id"`
 95	Duration int    `json:"duration"`
 96	MimeType string `json:"mime_type"`
 97	FileSize int    `json:"file_size"`
 98}
 99
100type Document struct {
101	FileId   string    `json:"file_id"`
102	Thumb    PhotoSize `json:"thumb"`
103	FileName string    `json:"file_name"`
104	MimeType string    `json:"mime_type"`
105	FileSize int       `json:"file_size"`
106}
107
108type Sticker struct {
109	FileId   string    `json:"file_id"`
110	Width    int       `json:"width"`
111	Height   int       `json:"height"`
112	Thumb    PhotoSize `json:"thumb"`
113	FileSize int       `json:"file_size"`
114}
115
116type Video struct {
117	FileId   string    `json:"file_id"`
118	Width    int       `json:"width"`
119	Height   int       `json:"height"`
120	Duration int       `json:"duration"`
121	Thumb    PhotoSize `json:"thumb"`
122	MimeType string    `json:"mime_type"`
123	FileSize int       `json:"file_size"`
124	Caption  string    `json:"caption"`
125}
126
127type Contact struct {
128	PhoneNumber string `json:"phone_number"`
129	FirstName   string `json:"first_name"`
130	LastName    string `json:"last_name"`
131	UserId      string `json:"user_id"`
132}
133
134type Location struct {
135	Longitude float32 `json:"longitude"`
136	Latitude  float32 `json:"latitude"`
137}
138
139type UserProfilePhotos struct {
140	TotalCount int         `json:"total_count"`
141	Photos     []PhotoSize `json:"photos"`
142}
143
144type ReplyKeyboardMarkup struct {
145	Keyboard        map[string]map[string]string `json:"keyboard"`
146	ResizeKeyboard  bool                         `json:"resize_keyboard"`
147	OneTimeKeyboard bool                         `json:"one_time_keyboard"`
148	Selective       bool                         `json:"selective"`
149}
150
151type ReplyKeyboardHide struct {
152	HideKeyboard bool `json:"hide_keyboard"`
153	Selective    bool `json:"selective"`
154}
155
156type ForceReply struct {
157	ForceReply bool `json:"force_reply"`
158	Selective  bool `json:"force_reply"`
159}
160
161type UpdateConfig struct {
162	Offset  int
163	Limit   int
164	Timeout int
165}
166
167type MessageConfig struct {
168	ChatId                int
169	Text                  string
170	DisableWebPagePreview bool
171	ReplyToMessageId      int
172}
173
174type ForwardConfig struct {
175	ChatId     int
176	FromChatId int
177	MessageId  int
178}
179
180type LocationConfig struct {
181	ChatId           int
182	Latitude         float64
183	Longitude        float64
184	ReplyToMessageId int
185	ReplyMarkup      interface{}
186}
187
188type ChatActionConfig struct {
189	ChatId int
190	Action string
191}
192
193type UserProfilePhotosConfig struct {
194	UserId int
195	Offset int
196	Limit  int
197}
198
199func NewBotApi(config BotConfig) *BotApi {
200	return &BotApi{
201		config: config,
202	}
203}
204
205func (bot *BotApi) makeRequest(endpoint string, params url.Values) (ApiResponse, error) {
206	resp, err := http.PostForm("https://api.telegram.org/bot"+bot.config.token+"/"+endpoint, params)
207	defer resp.Body.Close()
208	if err != nil {
209		return ApiResponse{}, err
210	}
211
212	bytes, err := ioutil.ReadAll(resp.Body)
213	if err != nil {
214		return ApiResponse{}, nil
215	}
216
217	if bot.config.debug {
218		log.Println(string(bytes[:]))
219	}
220
221	var apiResp ApiResponse
222	json.Unmarshal(bytes, &apiResp)
223
224	return apiResp, nil
225}
226
227func (bot *BotApi) getMe() (User, error) {
228	resp, err := bot.makeRequest("getMe", nil)
229	if err != nil {
230		return User{}, err
231	}
232
233	var user User
234	json.Unmarshal(resp.Result, &user)
235
236	if bot.config.debug {
237		log.Printf("getMe: %+v\n", user)
238	}
239
240	return user, nil
241}
242
243func (bot *BotApi) sendMessage(config MessageConfig) (Message, error) {
244	v := url.Values{}
245	v.Add("chat_id", strconv.Itoa(config.ChatId))
246	v.Add("text", config.Text)
247	v.Add("disable_web_page_preview", strconv.FormatBool(config.DisableWebPagePreview))
248	if config.ReplyToMessageId != 0 {
249		v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageId))
250	}
251
252	resp, err := bot.makeRequest("sendMessage", v)
253	if err != nil {
254		return Message{}, err
255	}
256
257	var message Message
258	json.Unmarshal(resp.Result, &message)
259
260	if bot.config.debug {
261		log.Printf("sendMessage req : %+v\n", v)
262		log.Printf("sendMessage resp: %+v\n", message)
263	}
264
265	return message, nil
266}
267
268func (bot *BotApi) forwardMessage(config ForwardConfig) (Message, error) {
269	v := url.Values{}
270	v.Add("chat_id", strconv.Itoa(config.ChatId))
271	v.Add("from_chat_id", strconv.Itoa(config.FromChatId))
272	v.Add("message_id", strconv.Itoa(config.MessageId))
273
274	resp, err := bot.makeRequest("forwardMessage", v)
275	if err != nil {
276		return Message{}, err
277	}
278
279	var message Message
280	json.Unmarshal(resp.Result, &message)
281
282	if bot.config.debug {
283		log.Printf("forwardMessage req : %+v\n", v)
284		log.Printf("forwardMessage resp: %+v\n", message)
285	}
286
287	return message, nil
288}
289
290func (bot *BotApi) sendLocation(config LocationConfig) (Message, error) {
291	v := url.Values{}
292	v.Add("chat_id", strconv.Itoa(config.ChatId))
293	v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
294	v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
295	if config.ReplyToMessageId != 0 {
296		v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageId))
297	}
298	if config.ReplyMarkup != nil {
299		data, err := json.Marshal(config.ReplyMarkup)
300		if err != nil {
301			return Message{}, err
302		}
303
304		v.Add("reply_markup", string(data))
305	}
306
307	resp, err := bot.makeRequest("sendLocation", v)
308	if err != nil {
309		return Message{}, err
310	}
311
312	var message Message
313	json.Unmarshal(resp.Result, &message)
314
315	if bot.config.debug {
316		log.Printf("sendLocation req : %+v\n", v)
317		log.Printf("sendLocation resp: %+v\n", message)
318	}
319
320	return message, nil
321}
322
323func (bot *BotApi) sendChatAction(config ChatActionConfig) error {
324	v := url.Values{}
325	v.Add("chat_id", strconv.Itoa(config.ChatId))
326	v.Add("action", config.Action)
327
328	_, err := bot.makeRequest("sendChatAction", v)
329	if err != nil {
330		return err
331	}
332
333	return nil
334}
335
336func (bot *BotApi) getUserProfilePhotos(config UserProfilePhotosConfig) (UserProfilePhotos, error) {
337	v := url.Values{}
338	v.Add("user_id", strconv.Itoa(config.UserId))
339	if config.Offset != 0 {
340		v.Add("offset", strconv.Itoa(config.Offset))
341	}
342	if config.Limit != 0 {
343		v.Add("limit", strconv.Itoa(config.Limit))
344	}
345
346	resp, err := bot.makeRequest("getUserProfilePhotos", v)
347	if err != nil {
348		return UserProfilePhotos{}, err
349	}
350
351	var profilePhotos UserProfilePhotos
352	json.Unmarshal(resp.Result, &profilePhotos)
353
354	if bot.config.debug {
355		log.Printf("getUserProfilePhotos req : %+v\n", v)
356		log.Printf("getUserProfilePhotos resp: %+v\n", profilePhotos)
357	}
358
359	return profilePhotos, nil
360}
361
362func (bot *BotApi) getUpdates(config UpdateConfig) ([]Update, error) {
363	v := url.Values{}
364	if config.Offset > 0 {
365		v.Add("offset", strconv.Itoa(config.Offset))
366	}
367	if config.Limit > 0 {
368		v.Add("limit", strconv.Itoa(config.Limit))
369	}
370	if config.Timeout > 0 {
371		v.Add("timeout", strconv.Itoa(config.Timeout))
372	}
373
374	resp, err := bot.makeRequest("getUpdates", v)
375	if err != nil {
376		return []Update{}, err
377	}
378
379	var updates []Update
380	json.Unmarshal(resp.Result, &updates)
381
382	if bot.config.debug {
383		log.Printf("getUpdates: %+v\n", updates)
384	}
385
386	return updates, nil
387}
388
389func (bot *BotApi) setWebhook(v url.Values) error {
390	_, err := bot.makeRequest("setWebhook", v)
391
392	return err
393}
394
395func NewMessage(chatId int, text string) MessageConfig {
396	return MessageConfig{
397		ChatId: chatId,
398		Text:   text,
399		DisableWebPagePreview: false,
400		ReplyToMessageId:      0,
401	}
402}
403
404func NewForward(chatId int, fromChatId int, messageId int) ForwardConfig {
405	return ForwardConfig{
406		ChatId:     chatId,
407		FromChatId: fromChatId,
408		MessageId:  messageId,
409	}
410}
411
412func NewLocation(chatId int, latitude float64, longitude float64) LocationConfig {
413	return LocationConfig{
414		ChatId:           chatId,
415		Latitude:         latitude,
416		Longitude:        longitude,
417		ReplyToMessageId: 0,
418		ReplyMarkup:      nil,
419	}
420}
421
422func NewChatAction(chatId int, action string) ChatActionConfig {
423	return ChatActionConfig{
424		ChatId: chatId,
425		Action: action,
426	}
427}
428
429func NewUserProfilePhotos(userId int) UserProfilePhotosConfig {
430	return UserProfilePhotosConfig{
431		UserId: userId,
432		Offset: 0,
433		Limit:  0,
434	}
435}
436
437func NewUpdate(offset int) UpdateConfig {
438	return UpdateConfig{
439		Offset:  offset,
440		Limit:   0,
441		Timeout: 0,
442	}
443}