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 ErrBadURL = "bad or empty url"
48)
49
50// Chattable is any config type that can be sent.
51type Chattable interface {
52 values() (url.Values, error)
53 method() string
54}
55
56// Fileable is any config type that can be sent that includes a file.
57type Fileable interface {
58 Chattable
59 params() (map[string]string, error)
60 name() string
61 getFile() interface{}
62 useExistingFile() bool
63}
64
65// BaseChat is base type for all chat config types.
66type BaseChat struct {
67 ChatID int64 // required
68 ChannelUsername string
69 ReplyToMessageID int
70 ReplyMarkup interface{}
71 DisableNotification bool
72}
73
74// values returns url.Values representation of BaseChat
75func (chat *BaseChat) values() (url.Values, error) {
76 v := url.Values{}
77 if chat.ChannelUsername != "" {
78 v.Add("chat_id", chat.ChannelUsername)
79 } else {
80 v.Add("chat_id", strconv.FormatInt(chat.ChatID, 10))
81 }
82
83 if chat.ReplyToMessageID != 0 {
84 v.Add("reply_to_message_id", strconv.Itoa(chat.ReplyToMessageID))
85 }
86
87 if chat.ReplyMarkup != nil {
88 data, err := json.Marshal(chat.ReplyMarkup)
89 if err != nil {
90 return v, err
91 }
92
93 v.Add("reply_markup", string(data))
94 }
95
96 v.Add("disable_notification", strconv.FormatBool(chat.DisableNotification))
97
98 return v, nil
99}
100
101// BaseFile is a base type for all file config types.
102type BaseFile struct {
103 BaseChat
104 File interface{}
105 FileID string
106 UseExisting bool
107 MimeType string
108 FileSize int
109}
110
111// params returns a map[string]string representation of BaseFile.
112func (file BaseFile) params() (map[string]string, error) {
113 params := make(map[string]string)
114
115 if file.ChannelUsername != "" {
116 params["chat_id"] = file.ChannelUsername
117 } else {
118 params["chat_id"] = strconv.FormatInt(file.ChatID, 10)
119 }
120
121 if file.ReplyToMessageID != 0 {
122 params["reply_to_message_id"] = strconv.Itoa(file.ReplyToMessageID)
123 }
124
125 if file.ReplyMarkup != nil {
126 data, err := json.Marshal(file.ReplyMarkup)
127 if err != nil {
128 return params, err
129 }
130
131 params["reply_markup"] = string(data)
132 }
133
134 if file.MimeType != "" {
135 params["mime_type"] = file.MimeType
136 }
137
138 if file.FileSize > 0 {
139 params["file_size"] = strconv.Itoa(file.FileSize)
140 }
141
142 params["disable_notification"] = strconv.FormatBool(file.DisableNotification)
143
144 return params, nil
145}
146
147// getFile returns the file.
148func (file BaseFile) getFile() interface{} {
149 return file.File
150}
151
152// useExistingFile returns if the BaseFile has already been uploaded.
153func (file BaseFile) useExistingFile() bool {
154 return file.UseExisting
155}
156
157// BaseEdit is base type of all chat edits.
158type BaseEdit struct {
159 ChatID int64
160 ChannelUsername string
161 MessageID int
162 InlineMessageID string
163 ReplyMarkup *InlineKeyboardMarkup
164}
165
166func (edit BaseEdit) values() (url.Values, error) {
167 v := url.Values{}
168
169 if edit.InlineMessageID == "" {
170 if edit.ChannelUsername != "" {
171 v.Add("chat_id", edit.ChannelUsername)
172 } else {
173 v.Add("chat_id", strconv.FormatInt(edit.ChatID, 10))
174 }
175 v.Add("message_id", strconv.Itoa(edit.MessageID))
176 } else {
177 v.Add("inline_message_id", edit.InlineMessageID)
178 }
179
180 if edit.ReplyMarkup != nil {
181 data, err := json.Marshal(edit.ReplyMarkup)
182 if err != nil {
183 return v, err
184 }
185 v.Add("reply_markup", string(data))
186 }
187
188 return v, nil
189}
190
191// MessageConfig contains information about a SendMessage request.
192type MessageConfig struct {
193 BaseChat
194 Text string
195 ParseMode string
196 DisableWebPagePreview bool
197}
198
199// values returns a url.Values representation of MessageConfig.
200func (config MessageConfig) values() (url.Values, error) {
201 v, err := config.BaseChat.values()
202 if err != nil {
203 data := url.Values{}
204 return data, err
205 }
206 v.Add("text", config.Text)
207 v.Add("disable_web_page_preview", strconv.FormatBool(config.DisableWebPagePreview))
208 if config.ParseMode != "" {
209 v.Add("parse_mode", config.ParseMode)
210 }
211
212 return v, nil
213}
214
215// method returns Telegram API method name for sending Message.
216func (config MessageConfig) method() string {
217 return "sendMessage"
218}
219
220// ForwardConfig contains information about a ForwardMessage request.
221type ForwardConfig struct {
222 BaseChat
223 FromChatID int64 // required
224 FromChannelUsername string
225 MessageID int // required
226}
227
228// values returns a url.Values representation of ForwardConfig.
229func (config ForwardConfig) values() (url.Values, error) {
230 v, _ := config.BaseChat.values()
231 v.Add("from_chat_id", strconv.FormatInt(config.FromChatID, 10))
232 v.Add("message_id", strconv.Itoa(config.MessageID))
233 return v, nil
234}
235
236// method returns Telegram API method name for sending Forward.
237func (config ForwardConfig) method() string {
238 return "forwardMessage"
239}
240
241// PhotoConfig contains information about a SendPhoto request.
242type PhotoConfig struct {
243 BaseFile
244 Caption string
245}
246
247// Params returns a map[string]string representation of PhotoConfig.
248func (config PhotoConfig) params() (map[string]string, error) {
249 params, _ := config.BaseFile.params()
250
251 if config.Caption != "" {
252 params["caption"] = config.Caption
253 }
254
255 return params, nil
256}
257
258// Values returns a url.Values representation of PhotoConfig.
259func (config PhotoConfig) values() (url.Values, error) {
260 v, _ := config.BaseChat.values()
261
262 v.Add(config.name(), config.FileID)
263 if config.Caption != "" {
264 v.Add("caption", config.Caption)
265 }
266 return v, nil
267}
268
269// name returns the field name for the Photo.
270func (config PhotoConfig) name() string {
271 return "photo"
272}
273
274// method returns Telegram API method name for sending Photo.
275func (config PhotoConfig) method() string {
276 return "sendPhoto"
277}
278
279// AudioConfig contains information about a SendAudio request.
280type AudioConfig struct {
281 BaseFile
282 Caption string
283 Duration int
284 Performer string
285 Title string
286}
287
288// values returns a url.Values representation of AudioConfig.
289func (config AudioConfig) values() (url.Values, error) {
290 v, _ := config.BaseChat.values()
291
292 v.Add(config.name(), config.FileID)
293 if config.Duration != 0 {
294 v.Add("duration", strconv.Itoa(config.Duration))
295 }
296
297 if config.Performer != "" {
298 v.Add("performer", config.Performer)
299 }
300 if config.Title != "" {
301 v.Add("title", config.Title)
302 }
303 if config.Caption != "" {
304 v.Add("caption", config.Caption)
305 }
306
307 return v, nil
308}
309
310// params returns a map[string]string representation of AudioConfig.
311func (config AudioConfig) params() (map[string]string, error) {
312 params, _ := config.BaseFile.params()
313
314 if config.Duration != 0 {
315 params["duration"] = strconv.Itoa(config.Duration)
316 }
317
318 if config.Performer != "" {
319 params["performer"] = config.Performer
320 }
321 if config.Title != "" {
322 params["title"] = config.Title
323 }
324 if config.Caption != "" {
325 params["caption"] = config.Caption
326 }
327
328 return params, nil
329}
330
331// name returns the field name for the Audio.
332func (config AudioConfig) name() string {
333 return "audio"
334}
335
336// method returns Telegram API method name for sending Audio.
337func (config AudioConfig) method() string {
338 return "sendAudio"
339}
340
341// DocumentConfig contains information about a SendDocument request.
342type DocumentConfig struct {
343 BaseFile
344}
345
346// values returns a url.Values representation of DocumentConfig.
347func (config DocumentConfig) values() (url.Values, error) {
348 v, _ := config.BaseChat.values()
349
350 v.Add(config.name(), config.FileID)
351
352 return v, nil
353}
354
355// params returns a map[string]string representation of DocumentConfig.
356func (config DocumentConfig) params() (map[string]string, error) {
357 params, _ := config.BaseFile.params()
358
359 return params, nil
360}
361
362// name returns the field name for the Document.
363func (config DocumentConfig) name() string {
364 return "document"
365}
366
367// method returns Telegram API method name for sending Document.
368func (config DocumentConfig) method() string {
369 return "sendDocument"
370}
371
372// StickerConfig contains information about a SendSticker request.
373type StickerConfig struct {
374 BaseFile
375}
376
377// values returns a url.Values representation of StickerConfig.
378func (config StickerConfig) values() (url.Values, error) {
379 v, _ := config.BaseChat.values()
380
381 v.Add(config.name(), config.FileID)
382
383 return v, nil
384}
385
386// params returns a map[string]string representation of StickerConfig.
387func (config StickerConfig) params() (map[string]string, error) {
388 params, _ := config.BaseFile.params()
389
390 return params, nil
391}
392
393// name returns the field name for the Sticker.
394func (config StickerConfig) name() string {
395 return "sticker"
396}
397
398// method returns Telegram API method name for sending Sticker.
399func (config StickerConfig) method() string {
400 return "sendSticker"
401}
402
403// VideoConfig contains information about a SendVideo request.
404type VideoConfig struct {
405 BaseFile
406 Duration int
407 Caption string
408}
409
410// values returns a url.Values representation of VideoConfig.
411func (config VideoConfig) values() (url.Values, error) {
412 v, _ := config.BaseChat.values()
413
414 v.Add(config.name(), config.FileID)
415 if config.Duration != 0 {
416 v.Add("duration", strconv.Itoa(config.Duration))
417 }
418 if config.Caption != "" {
419 v.Add("caption", config.Caption)
420 }
421
422 return v, nil
423}
424
425// params returns a map[string]string representation of VideoConfig.
426func (config VideoConfig) params() (map[string]string, error) {
427 params, _ := config.BaseFile.params()
428
429 return params, nil
430}
431
432// name returns the field name for the Video.
433func (config VideoConfig) name() string {
434 return "video"
435}
436
437// method returns Telegram API method name for sending Video.
438func (config VideoConfig) method() string {
439 return "sendVideo"
440}
441
442// VoiceConfig contains information about a SendVoice request.
443type VoiceConfig struct {
444 BaseFile
445 Caption string
446 Duration int
447}
448
449// values returns a url.Values representation of VoiceConfig.
450func (config VoiceConfig) values() (url.Values, error) {
451 v, _ := config.BaseChat.values()
452
453 v.Add(config.name(), config.FileID)
454 if config.Duration != 0 {
455 v.Add("duration", strconv.Itoa(config.Duration))
456 }
457
458 return v, nil
459}
460
461// params returns a map[string]string representation of VoiceConfig.
462func (config VoiceConfig) params() (map[string]string, error) {
463 params, _ := config.BaseFile.params()
464
465 if config.Duration != 0 {
466 params["duration"] = strconv.Itoa(config.Duration)
467 }
468
469 return params, nil
470}
471
472// name returns the field name for the Voice.
473func (config VoiceConfig) name() string {
474 return "voice"
475}
476
477// method returns Telegram API method name for sending Voice.
478func (config VoiceConfig) method() string {
479 return "sendVoice"
480}
481
482// LocationConfig contains information about a SendLocation request.
483type LocationConfig struct {
484 BaseChat
485 Latitude float64 // required
486 Longitude float64 // required
487}
488
489// values returns a url.Values representation of LocationConfig.
490func (config LocationConfig) values() (url.Values, error) {
491 v, _ := config.BaseChat.values()
492
493 v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
494 v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
495
496 return v, nil
497}
498
499// method returns Telegram API method name for sending Location.
500func (config LocationConfig) method() string {
501 return "sendLocation"
502}
503
504// VenueConfig contains information about a SendVenue request.
505type VenueConfig struct {
506 BaseChat
507 Latitude float64 // required
508 Longitude float64 // required
509 Title string // required
510 Address string // required
511 FoursquareID string
512}
513
514func (config VenueConfig) values() (url.Values, error) {
515 v, _ := config.BaseChat.values()
516
517 v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
518 v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
519 v.Add("title", config.Title)
520 v.Add("address", config.Address)
521 if config.FoursquareID != "" {
522 v.Add("foursquare_id", config.FoursquareID)
523 }
524
525 return v, nil
526}
527
528func (config VenueConfig) method() string {
529 return "sendVenue"
530}
531
532// ContactConfig allows you to send a contact.
533type ContactConfig struct {
534 BaseChat
535 PhoneNumber string
536 FirstName string
537 LastName string
538}
539
540func (config ContactConfig) values() (url.Values, error) {
541 v, _ := config.BaseChat.values()
542
543 v.Add("phone_number", config.PhoneNumber)
544 v.Add("first_name", config.FirstName)
545 v.Add("last_name", config.LastName)
546
547 return v, nil
548}
549
550func (config ContactConfig) method() string {
551 return "sendContact"
552}
553
554// GameConfig allows you to send a game.
555type GameConfig struct {
556 BaseChat
557 GameShortName string
558}
559
560func (config GameConfig) values() (url.Values, error) {
561 v, _ := config.BaseChat.values()
562
563 v.Add("game_short_name", config.GameShortName)
564
565 return v, nil
566}
567
568func (config GameConfig) method() string {
569 return "sendGame"
570}
571
572// SetGameScoreConfig allows you to update the game score in a chat.
573type SetGameScoreConfig struct {
574 UserID int
575 Score int
576 Force bool
577 DisableEditMessage bool
578 ChatID int
579 ChannelUsername string
580 MessageID int
581 InlineMessageID string
582}
583
584func (config SetGameScoreConfig) values() (url.Values, error) {
585 v := url.Values{}
586
587 v.Add("user_id", strconv.Itoa(config.UserID))
588 v.Add("score", strconv.Itoa(config.Score))
589 if config.InlineMessageID == "" {
590 if config.ChannelUsername == "" {
591 v.Add("chat_id", strconv.Itoa(config.ChatID))
592 } else {
593 v.Add("chat_id", config.ChannelUsername)
594 }
595 v.Add("message_id", strconv.Itoa(config.MessageID))
596 } else {
597 v.Add("inline_message_id", config.InlineMessageID)
598 }
599 v.Add("disable_edit_message", strconv.FormatBool(config.DisableEditMessage))
600
601 return v, nil
602}
603
604func (config SetGameScoreConfig) method() string {
605 return "setGameScore"
606}
607
608// GetGameHighScoresConfig allows you to fetch the high scores for a game.
609type GetGameHighScoresConfig struct {
610 UserID int
611 ChatID int
612 ChannelUsername string
613 MessageID int
614 InlineMessageID string
615}
616
617func (config GetGameHighScoresConfig) values() (url.Values, error) {
618 v := url.Values{}
619
620 v.Add("user_id", strconv.Itoa(config.UserID))
621 if config.InlineMessageID == "" {
622 if config.ChannelUsername == "" {
623 v.Add("chat_id", strconv.Itoa(config.ChatID))
624 } else {
625 v.Add("chat_id", config.ChannelUsername)
626 }
627 v.Add("message_id", strconv.Itoa(config.MessageID))
628 } else {
629 v.Add("inline_message_id", config.InlineMessageID)
630 }
631
632 return v, nil
633}
634
635func (config GetGameHighScoresConfig) method() string {
636 return "getGameHighScores"
637}
638
639// ChatActionConfig contains information about a SendChatAction request.
640type ChatActionConfig struct {
641 BaseChat
642 Action string // required
643}
644
645// values returns a url.Values representation of ChatActionConfig.
646func (config ChatActionConfig) values() (url.Values, error) {
647 v, _ := config.BaseChat.values()
648 v.Add("action", config.Action)
649 return v, nil
650}
651
652// method returns Telegram API method name for sending ChatAction.
653func (config ChatActionConfig) method() string {
654 return "sendChatAction"
655}
656
657// EditMessageTextConfig allows you to modify the text in a message.
658type EditMessageTextConfig struct {
659 BaseEdit
660 Text string
661 ParseMode string
662 DisableWebPagePreview bool
663}
664
665func (config EditMessageTextConfig) values() (url.Values, error) {
666 v, _ := config.BaseEdit.values()
667
668 v.Add("text", config.Text)
669 v.Add("parse_mode", config.ParseMode)
670 v.Add("disable_web_page_preview", strconv.FormatBool(config.DisableWebPagePreview))
671
672 return v, nil
673}
674
675func (config EditMessageTextConfig) method() string {
676 return "editMessageText"
677}
678
679// EditMessageCaptionConfig allows you to modify the caption of a message.
680type EditMessageCaptionConfig struct {
681 BaseEdit
682 Caption string
683}
684
685func (config EditMessageCaptionConfig) values() (url.Values, error) {
686 v, _ := config.BaseEdit.values()
687
688 v.Add("caption", config.Caption)
689
690 return v, nil
691}
692
693func (config EditMessageCaptionConfig) method() string {
694 return "editMessageCaption"
695}
696
697// EditMessageReplyMarkupConfig allows you to modify the reply markup
698// of a message.
699type EditMessageReplyMarkupConfig struct {
700 BaseEdit
701}
702
703func (config EditMessageReplyMarkupConfig) values() (url.Values, error) {
704 return config.BaseEdit.values()
705}
706
707func (config EditMessageReplyMarkupConfig) method() string {
708 return "editMessageReplyMarkup"
709}
710
711// UserProfilePhotosConfig contains information about a
712// GetUserProfilePhotos request.
713type UserProfilePhotosConfig struct {
714 UserID int
715 Offset int
716 Limit int
717}
718
719// FileConfig has information about a file hosted on Telegram.
720type FileConfig struct {
721 FileID string
722}
723
724// UpdateConfig contains information about a GetUpdates request.
725type UpdateConfig struct {
726 Offset int
727 Limit int
728 Timeout int
729}
730
731// WebhookConfig contains information about a SetWebhook request.
732type WebhookConfig struct {
733 URL *url.URL
734 Certificate interface{}
735}
736
737// FileBytes contains information about a set of bytes to upload
738// as a File.
739type FileBytes struct {
740 Name string
741 Bytes []byte
742}
743
744// FileReader contains information about a reader to upload as a File.
745// If Size is -1, it will read the entire Reader into memory to
746// calculate a Size.
747type FileReader struct {
748 Name string
749 Reader io.Reader
750 Size int64
751}
752
753// InlineConfig contains information on making an InlineQuery response.
754type InlineConfig struct {
755 InlineQueryID string `json:"inline_query_id"`
756 Results []interface{} `json:"results"`
757 CacheTime int `json:"cache_time"`
758 IsPersonal bool `json:"is_personal"`
759 NextOffset string `json:"next_offset"`
760 SwitchPMText string `json:"switch_pm_text"`
761 SwitchPMParameter string `json:"switch_pm_parameter"`
762}
763
764// CallbackConfig contains information on making a CallbackQuery response.
765type CallbackConfig struct {
766 CallbackQueryID string `json:"callback_query_id"`
767 Text string `json:"text"`
768 ShowAlert bool `json:"show_alert"`
769 URL string `json:"url"`
770 CacheTime int `json:"cache_time"`
771}
772
773// ChatMemberConfig contains information about a user in a chat for use
774// with administrative functions such as kicking or unbanning a user.
775type ChatMemberConfig struct {
776 ChatID int64
777 SuperGroupUsername string
778 UserID int
779}
780
781// ChatConfig contains information about getting information on a chat.
782type ChatConfig struct {
783 ChatID int64
784 SuperGroupUsername string
785}
786
787// ChatConfigWithUser contains information about getting information on
788// a specific user within a chat.
789type ChatConfigWithUser struct {
790 ChatID int64
791 SuperGroupUsername string
792 UserID int
793}