configs.go (view raw)
1package tgbotapi
2
3import (
4 "encoding/json"
5 "io"
6 "net/url"
7 "strconv"
8)
9
10// Telegram constants
11const (
12 // APIEndpoint is the endpoint for all API methods,
13 // with formatting for Sprintf.
14 APIEndpoint = "https://api.telegram.org/bot%s/%s"
15 // FileEndpoint is the endpoint for downloading a file from Telegram.
16 FileEndpoint = "https://api.telegram.org/file/bot%s/%s"
17)
18
19// Constant values for ChatActions
20const (
21 ChatTyping = "typing"
22 ChatUploadPhoto = "upload_photo"
23 ChatRecordVideo = "record_video"
24 ChatUploadVideo = "upload_video"
25 ChatRecordAudio = "record_audio"
26 ChatUploadAudio = "upload_audio"
27 ChatUploadDocument = "upload_document"
28 ChatFindLocation = "find_location"
29)
30
31// API errors
32const (
33 // ErrAPIForbidden happens when a token is bad
34 ErrAPIForbidden = "forbidden"
35)
36
37// Constant values for ParseMode in MessageConfig
38const (
39 ModeMarkdown = "Markdown"
40 ModeHTML = "HTML"
41)
42
43// Library errors
44const (
45 // ErrBadFileType happens when you pass an unknown type
46 ErrBadFileType = "bad file type"
47)
48
49// Chattable is any config type that can be sent.
50type Chattable interface {
51 values() (url.Values, error)
52 method() string
53}
54
55// Fileable is any config type that can be sent that includes a file.
56type Fileable interface {
57 Chattable
58 params() (map[string]string, error)
59 name() string
60 getFile() interface{}
61 useExistingFile() bool
62}
63
64// BaseChat is base type for all chat config types.
65type BaseChat struct {
66 ChatID int64 // required
67 ChannelUsername string
68 ReplyToMessageID int
69 ReplyMarkup interface{}
70 DisableNotification bool
71}
72
73// values returns url.Values representation of BaseChat
74func (chat *BaseChat) values() (url.Values, error) {
75 v := url.Values{}
76 if chat.ChannelUsername != "" {
77 v.Add("chat_id", chat.ChannelUsername)
78 } else {
79 v.Add("chat_id", strconv.FormatInt(chat.ChatID, 10))
80 }
81
82 if chat.ReplyToMessageID != 0 {
83 v.Add("reply_to_message_id", strconv.Itoa(chat.ReplyToMessageID))
84 }
85
86 if chat.ReplyMarkup != nil {
87 data, err := json.Marshal(chat.ReplyMarkup)
88 if err != nil {
89 return v, err
90 }
91
92 v.Add("reply_markup", string(data))
93 }
94
95 v.Add("disable_notification", strconv.FormatBool(chat.DisableNotification))
96
97 return v, nil
98}
99
100// BaseFile is a base type for all file config types.
101type BaseFile struct {
102 BaseChat
103 File interface{}
104 FileID string
105 UseExisting bool
106 MimeType string
107 FileSize int
108}
109
110// params returns a map[string]string representation of BaseFile.
111func (file BaseFile) params() (map[string]string, error) {
112 params := make(map[string]string)
113
114 if file.ChannelUsername != "" {
115 params["chat_id"] = file.ChannelUsername
116 } else {
117 params["chat_id"] = strconv.FormatInt(file.ChatID, 10)
118 }
119
120 if file.ReplyToMessageID != 0 {
121 params["reply_to_message_id"] = strconv.Itoa(file.ReplyToMessageID)
122 }
123
124 if file.ReplyMarkup != nil {
125 data, err := json.Marshal(file.ReplyMarkup)
126 if err != nil {
127 return params, err
128 }
129
130 params["reply_markup"] = string(data)
131 }
132
133 if file.MimeType != "" {
134 params["mime_type"] = file.MimeType
135 }
136
137 if file.FileSize > 0 {
138 params["file_size"] = strconv.Itoa(file.FileSize)
139 }
140
141 params["disable_notification"] = strconv.FormatBool(file.DisableNotification)
142
143 return params, nil
144}
145
146// getFile returns the file.
147func (file BaseFile) getFile() interface{} {
148 return file.File
149}
150
151// useExistingFile returns if the BaseFile has already been uploaded.
152func (file BaseFile) useExistingFile() bool {
153 return file.UseExisting
154}
155
156// BaseEdit is base type of all chat edits.
157type BaseEdit struct {
158 ChatID int64
159 ChannelUsername string
160 MessageID int
161 InlineMessageID string
162 ReplyMarkup *InlineKeyboardMarkup
163}
164
165func (edit BaseEdit) values() (url.Values, error) {
166 v := url.Values{}
167
168 if edit.ChannelUsername != "" {
169 v.Add("chat_id", edit.ChannelUsername)
170 } else {
171 v.Add("chat_id", strconv.FormatInt(edit.ChatID, 10))
172 }
173 v.Add("message_id", strconv.Itoa(edit.MessageID))
174 v.Add("inline_message_id", edit.InlineMessageID)
175
176 if edit.ReplyMarkup != nil {
177 data, err := json.Marshal(edit.ReplyMarkup)
178 if err != nil {
179 return v, err
180 }
181 v.Add("reply_markup", string(data))
182 }
183
184 return v, nil
185}
186
187// MessageConfig contains information about a SendMessage request.
188type MessageConfig struct {
189 BaseChat
190 Text string
191 ParseMode string
192 DisableWebPagePreview bool
193}
194
195// values returns a url.Values representation of MessageConfig.
196func (config MessageConfig) values() (url.Values, error) {
197 v, _ := config.BaseChat.values()
198 v.Add("text", config.Text)
199 v.Add("disable_web_page_preview", strconv.FormatBool(config.DisableWebPagePreview))
200 if config.ParseMode != "" {
201 v.Add("parse_mode", config.ParseMode)
202 }
203
204 return v, nil
205}
206
207// method returns Telegram API method name for sending Message.
208func (config MessageConfig) method() string {
209 return "sendMessage"
210}
211
212// ForwardConfig contains information about a ForwardMessage request.
213type ForwardConfig struct {
214 BaseChat
215 FromChatID int64 // required
216 FromChannelUsername string
217 MessageID int // required
218}
219
220// values returns a url.Values representation of ForwardConfig.
221func (config ForwardConfig) values() (url.Values, error) {
222 v, _ := config.BaseChat.values()
223 v.Add("from_chat_id", strconv.FormatInt(config.FromChatID, 10))
224 v.Add("message_id", strconv.Itoa(config.MessageID))
225 return v, nil
226}
227
228// method returns Telegram API method name for sending Forward.
229func (config ForwardConfig) method() string {
230 return "forwardMessage"
231}
232
233// PhotoConfig contains information about a SendPhoto request.
234type PhotoConfig struct {
235 BaseFile
236 Caption string
237}
238
239// Params returns a map[string]string representation of PhotoConfig.
240func (config PhotoConfig) params() (map[string]string, error) {
241 params, _ := config.BaseFile.params()
242
243 if config.Caption != "" {
244 params["caption"] = config.Caption
245 }
246
247 return params, nil
248}
249
250// Values returns a url.Values representation of PhotoConfig.
251func (config PhotoConfig) values() (url.Values, error) {
252 v, _ := config.BaseChat.values()
253
254 v.Add(config.name(), config.FileID)
255 if config.Caption != "" {
256 v.Add("caption", config.Caption)
257 }
258 return v, nil
259}
260
261// name returns the field name for the Photo.
262func (config PhotoConfig) name() string {
263 return "photo"
264}
265
266// method returns Telegram API method name for sending Photo.
267func (config PhotoConfig) method() string {
268 return "sendPhoto"
269}
270
271// AudioConfig contains information about a SendAudio request.
272type AudioConfig struct {
273 BaseFile
274 Duration int
275 Performer string
276 Title string
277}
278
279// values returns a url.Values representation of AudioConfig.
280func (config AudioConfig) values() (url.Values, error) {
281 v, _ := config.BaseChat.values()
282
283 v.Add(config.name(), config.FileID)
284 if config.Duration != 0 {
285 v.Add("duration", strconv.Itoa(config.Duration))
286 }
287
288 if config.Performer != "" {
289 v.Add("performer", config.Performer)
290 }
291 if config.Title != "" {
292 v.Add("title", config.Title)
293 }
294
295 return v, nil
296}
297
298// params returns a map[string]string representation of AudioConfig.
299func (config AudioConfig) params() (map[string]string, error) {
300 params, _ := config.BaseFile.params()
301
302 if config.Duration != 0 {
303 params["duration"] = strconv.Itoa(config.Duration)
304 }
305
306 if config.Performer != "" {
307 params["performer"] = config.Performer
308 }
309 if config.Title != "" {
310 params["title"] = config.Title
311 }
312
313 return params, nil
314}
315
316// name returns the field name for the Audio.
317func (config AudioConfig) name() string {
318 return "audio"
319}
320
321// method returns Telegram API method name for sending Audio.
322func (config AudioConfig) method() string {
323 return "sendAudio"
324}
325
326// DocumentConfig contains information about a SendDocument request.
327type DocumentConfig struct {
328 BaseFile
329}
330
331// values returns a url.Values representation of DocumentConfig.
332func (config DocumentConfig) values() (url.Values, error) {
333 v, _ := config.BaseChat.values()
334
335 v.Add(config.name(), config.FileID)
336
337 return v, nil
338}
339
340// params returns a map[string]string representation of DocumentConfig.
341func (config DocumentConfig) params() (map[string]string, error) {
342 params, _ := config.BaseFile.params()
343
344 return params, nil
345}
346
347// name returns the field name for the Document.
348func (config DocumentConfig) name() string {
349 return "document"
350}
351
352// method returns Telegram API method name for sending Document.
353func (config DocumentConfig) method() string {
354 return "sendDocument"
355}
356
357// StickerConfig contains information about a SendSticker request.
358type StickerConfig struct {
359 BaseFile
360}
361
362// values returns a url.Values representation of StickerConfig.
363func (config StickerConfig) values() (url.Values, error) {
364 v, _ := config.BaseChat.values()
365
366 v.Add(config.name(), config.FileID)
367
368 return v, nil
369}
370
371// params returns a map[string]string representation of StickerConfig.
372func (config StickerConfig) params() (map[string]string, error) {
373 params, _ := config.BaseFile.params()
374
375 return params, nil
376}
377
378// name returns the field name for the Sticker.
379func (config StickerConfig) name() string {
380 return "sticker"
381}
382
383// method returns Telegram API method name for sending Sticker.
384func (config StickerConfig) method() string {
385 return "sendSticker"
386}
387
388// VideoConfig contains information about a SendVideo request.
389type VideoConfig struct {
390 BaseFile
391 Duration int
392 Caption string
393}
394
395// values returns a url.Values representation of VideoConfig.
396func (config VideoConfig) values() (url.Values, error) {
397 v, _ := config.BaseChat.values()
398
399 v.Add(config.name(), config.FileID)
400 if config.Duration != 0 {
401 v.Add("duration", strconv.Itoa(config.Duration))
402 }
403 if config.Caption != "" {
404 v.Add("caption", config.Caption)
405 }
406
407 return v, nil
408}
409
410// params returns a map[string]string representation of VideoConfig.
411func (config VideoConfig) params() (map[string]string, error) {
412 params, _ := config.BaseFile.params()
413
414 return params, nil
415}
416
417// name returns the field name for the Video.
418func (config VideoConfig) name() string {
419 return "video"
420}
421
422// method returns Telegram API method name for sending Video.
423func (config VideoConfig) method() string {
424 return "sendVideo"
425}
426
427// VoiceConfig contains information about a SendVoice request.
428type VoiceConfig struct {
429 BaseFile
430 Duration int
431}
432
433// values returns a url.Values representation of VoiceConfig.
434func (config VoiceConfig) values() (url.Values, error) {
435 v, _ := config.BaseChat.values()
436
437 v.Add(config.name(), config.FileID)
438 if config.Duration != 0 {
439 v.Add("duration", strconv.Itoa(config.Duration))
440 }
441
442 return v, nil
443}
444
445// params returns a map[string]string representation of VoiceConfig.
446func (config VoiceConfig) params() (map[string]string, error) {
447 params, _ := config.BaseFile.params()
448
449 if config.Duration != 0 {
450 params["duration"] = strconv.Itoa(config.Duration)
451 }
452
453 return params, nil
454}
455
456// name returns the field name for the Voice.
457func (config VoiceConfig) name() string {
458 return "voice"
459}
460
461// method returns Telegram API method name for sending Voice.
462func (config VoiceConfig) method() string {
463 return "sendVoice"
464}
465
466// LocationConfig contains information about a SendLocation request.
467type LocationConfig struct {
468 BaseChat
469 Latitude float64 // required
470 Longitude float64 // required
471}
472
473// values returns a url.Values representation of LocationConfig.
474func (config LocationConfig) values() (url.Values, error) {
475 v, _ := config.BaseChat.values()
476
477 v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
478 v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
479
480 return v, nil
481}
482
483// method returns Telegram API method name for sending Location.
484func (config LocationConfig) method() string {
485 return "sendLocation"
486}
487
488// VenueConfig contains information about a SendVenue request.
489type VenueConfig struct {
490 BaseChat
491 Latitude float64 // required
492 Longitude float64 // required
493 Title string // required
494 Address string // required
495 FoursquareID string
496}
497
498func (config VenueConfig) values() (url.Values, error) {
499 v, _ := config.BaseChat.values()
500
501 v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
502 v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
503 v.Add("title", config.Title)
504 v.Add("address", config.Address)
505 if config.FoursquareID != "" {
506 v.Add("foursquare_id", config.FoursquareID)
507 }
508
509 return v, nil
510}
511
512func (config VenueConfig) method() string {
513 return "sendVenue"
514}
515
516// ContactConfig allows you to send a contact.
517type ContactConfig struct {
518 BaseChat
519 PhoneNumber string
520 FirstName string
521 LastName string
522}
523
524func (config ContactConfig) values() (url.Values, error) {
525 v, _ := config.BaseChat.values()
526
527 v.Add("phone_number", config.PhoneNumber)
528 v.Add("first_name", config.FirstName)
529 v.Add("last_name", config.LastName)
530
531 return v, nil
532}
533
534func (config ContactConfig) method() string {
535 return "sendContact"
536}
537
538// ChatActionConfig contains information about a SendChatAction request.
539type ChatActionConfig struct {
540 BaseChat
541 Action string // required
542}
543
544// values returns a url.Values representation of ChatActionConfig.
545func (config ChatActionConfig) values() (url.Values, error) {
546 v, _ := config.BaseChat.values()
547 v.Add("action", config.Action)
548 return v, nil
549}
550
551// method returns Telegram API method name for sending ChatAction.
552func (config ChatActionConfig) method() string {
553 return "sendChatAction"
554}
555
556// EditMessageTextConfig allows you to modify the text in a message.
557type EditMessageTextConfig struct {
558 BaseEdit
559 Text string
560 ParseMode string
561 DisableWebPagePreview bool
562 ReplyMarkup InlineKeyboardMarkup
563}
564
565func (config EditMessageTextConfig) values() (url.Values, error) {
566 v, _ := config.BaseEdit.values()
567
568 v.Add("text", config.Text)
569 v.Add("parse_mode", config.ParseMode)
570 v.Add("disable_web_page_preview", strconv.FormatBool(config.DisableWebPagePreview))
571
572 return v, nil
573}
574
575func (config EditMessageTextConfig) method() string {
576 return "editMessageText"
577}
578
579// EditMessageCaptionConfig allows you to modify the caption of a message.
580type EditMessageCaptionConfig struct {
581 BaseEdit
582 Caption string
583 ReplyMarkup InlineKeyboardMarkup
584}
585
586func (config EditMessageCaptionConfig) values() (url.Values, error) {
587 v, _ := config.BaseEdit.values()
588
589 v.Add("caption", config.Caption)
590
591 return v, nil
592}
593
594func (config EditMessageCaptionConfig) method() string {
595 return "editMessageCaption"
596}
597
598// EditMessageReplyMarkup allows you to modify the reply markup
599// of a message.
600type EditMessageReplyMarkup struct {
601 BaseEdit
602 ReplyMarkup InlineKeyboardMarkup
603}
604
605func (config EditMessageReplyMarkup) values() (url.Values, error) {
606 return config.BaseEdit.values()
607}
608
609func (config EditMessageReplyMarkup) method() string {
610 return "editMessageReplyMarkup"
611}
612
613// UserProfilePhotosConfig contains information about a
614// GetUserProfilePhotos request.
615type UserProfilePhotosConfig struct {
616 UserID int
617 Offset int
618 Limit int
619}
620
621// FileConfig has information about a file hosted on Telegram.
622type FileConfig struct {
623 FileID string
624}
625
626// UpdateConfig contains information about a GetUpdates request.
627type UpdateConfig struct {
628 Offset int
629 Limit int
630 Timeout int
631}
632
633// WebhookConfig contains information about a SetWebhook request.
634type WebhookConfig struct {
635 URL *url.URL
636 Certificate interface{}
637}
638
639// FileBytes contains information about a set of bytes to upload
640// as a File.
641type FileBytes struct {
642 Name string
643 Bytes []byte
644}
645
646// FileReader contains information about a reader to upload as a File.
647// If Size is -1, it will read the entire Reader into memory to
648// calculate a Size.
649type FileReader struct {
650 Name string
651 Reader io.Reader
652 Size int64
653}
654
655// InlineConfig contains information on making an InlineQuery response.
656type InlineConfig struct {
657 InlineQueryID string `json:"inline_query_id"`
658 Results []interface{} `json:"results"`
659 CacheTime int `json:"cache_time"`
660 IsPersonal bool `json:"is_personal"`
661 NextOffset string `json:"next_offset"`
662 SwitchPMText string `json:"switch_pm_text"`
663 SwitchPMParameter string `json:"switch_pm_parameter"`
664}
665
666// CallbackConfig contains information on making a CallbackQuery response.
667type CallbackConfig struct {
668 CallbackQueryID string `json:"callback_query_id"`
669 Text string `json:"text"`
670 ShowAlert bool `json:"show_alert"`
671}
672
673// ChatMemberConfig contains information about a user in a chat for use
674// with administrative functions such as kicking or unbanning a user.
675type ChatMemberConfig struct {
676 ChatID int64
677 SuperGroupUsername string
678 UserID int
679}