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