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 return v, err
204 }
205 v.Add("text", config.Text)
206 v.Add("disable_web_page_preview", strconv.FormatBool(config.DisableWebPagePreview))
207 if config.ParseMode != "" {
208 v.Add("parse_mode", config.ParseMode)
209 }
210
211 return v, nil
212}
213
214// method returns Telegram API method name for sending Message.
215func (config MessageConfig) method() string {
216 return "sendMessage"
217}
218
219// ForwardConfig contains information about a ForwardMessage request.
220type ForwardConfig struct {
221 BaseChat
222 FromChatID int64 // required
223 FromChannelUsername string
224 MessageID int // required
225}
226
227// values returns a url.Values representation of ForwardConfig.
228func (config ForwardConfig) values() (url.Values, error) {
229 v, err := config.BaseChat.values()
230 if err != nil {
231 return v, err
232 }
233 v.Add("from_chat_id", strconv.FormatInt(config.FromChatID, 10))
234 v.Add("message_id", strconv.Itoa(config.MessageID))
235 return v, nil
236}
237
238// method returns Telegram API method name for sending Forward.
239func (config ForwardConfig) method() string {
240 return "forwardMessage"
241}
242
243// PhotoConfig contains information about a SendPhoto request.
244type PhotoConfig struct {
245 BaseFile
246 Caption string
247}
248
249// Params returns a map[string]string representation of PhotoConfig.
250func (config PhotoConfig) params() (map[string]string, error) {
251 params, _ := config.BaseFile.params()
252
253 if config.Caption != "" {
254 params["caption"] = config.Caption
255 }
256
257 return params, nil
258}
259
260// Values returns a url.Values representation of PhotoConfig.
261func (config PhotoConfig) values() (url.Values, error) {
262 v, err := config.BaseChat.values()
263 if err != nil {
264 return v, err
265 }
266
267 v.Add(config.name(), config.FileID)
268 if config.Caption != "" {
269 v.Add("caption", config.Caption)
270 }
271 return v, nil
272}
273
274// name returns the field name for the Photo.
275func (config PhotoConfig) name() string {
276 return "photo"
277}
278
279// method returns Telegram API method name for sending Photo.
280func (config PhotoConfig) method() string {
281 return "sendPhoto"
282}
283
284// AudioConfig contains information about a SendAudio request.
285type AudioConfig struct {
286 BaseFile
287 Caption string
288 Duration int
289 Performer string
290 Title string
291}
292
293// values returns a url.Values representation of AudioConfig.
294func (config AudioConfig) values() (url.Values, error) {
295 v, err := config.BaseChat.values()
296 if err != nil {
297 return v, err
298 }
299
300 v.Add(config.name(), config.FileID)
301 if config.Duration != 0 {
302 v.Add("duration", strconv.Itoa(config.Duration))
303 }
304
305 if config.Performer != "" {
306 v.Add("performer", config.Performer)
307 }
308 if config.Title != "" {
309 v.Add("title", config.Title)
310 }
311 if config.Caption != "" {
312 v.Add("caption", config.Caption)
313 }
314
315 return v, nil
316}
317
318// params returns a map[string]string representation of AudioConfig.
319func (config AudioConfig) params() (map[string]string, error) {
320 params, _ := config.BaseFile.params()
321
322 if config.Duration != 0 {
323 params["duration"] = strconv.Itoa(config.Duration)
324 }
325
326 if config.Performer != "" {
327 params["performer"] = config.Performer
328 }
329 if config.Title != "" {
330 params["title"] = config.Title
331 }
332 if config.Caption != "" {
333 params["caption"] = config.Caption
334 }
335
336 return params, nil
337}
338
339// name returns the field name for the Audio.
340func (config AudioConfig) name() string {
341 return "audio"
342}
343
344// method returns Telegram API method name for sending Audio.
345func (config AudioConfig) method() string {
346 return "sendAudio"
347}
348
349// DocumentConfig contains information about a SendDocument request.
350type DocumentConfig struct {
351 BaseFile
352 Caption string
353}
354
355// values returns a url.Values representation of DocumentConfig.
356func (config DocumentConfig) values() (url.Values, error) {
357 v, err := config.BaseChat.values()
358 if err != nil {
359 return v, err
360 }
361
362 v.Add(config.name(), config.FileID)
363 if config.Caption != "" {
364 v.Add("caption", config.Caption)
365 }
366
367 return v, nil
368}
369
370// params returns a map[string]string representation of DocumentConfig.
371func (config DocumentConfig) params() (map[string]string, error) {
372 params, _ := config.BaseFile.params()
373
374 if config.Caption != "" {
375 params["caption"] = config.Caption
376 }
377
378 return params, nil
379}
380
381// name returns the field name for the Document.
382func (config DocumentConfig) name() string {
383 return "document"
384}
385
386// method returns Telegram API method name for sending Document.
387func (config DocumentConfig) method() string {
388 return "sendDocument"
389}
390
391// StickerConfig contains information about a SendSticker request.
392type StickerConfig struct {
393 BaseFile
394}
395
396// values returns a url.Values representation of StickerConfig.
397func (config StickerConfig) values() (url.Values, error) {
398 v, err := config.BaseChat.values()
399 if err != nil {
400 return v, err
401 }
402
403 v.Add(config.name(), config.FileID)
404
405 return v, nil
406}
407
408// params returns a map[string]string representation of StickerConfig.
409func (config StickerConfig) params() (map[string]string, error) {
410 params, _ := config.BaseFile.params()
411
412 return params, nil
413}
414
415// name returns the field name for the Sticker.
416func (config StickerConfig) name() string {
417 return "sticker"
418}
419
420// method returns Telegram API method name for sending Sticker.
421func (config StickerConfig) method() string {
422 return "sendSticker"
423}
424
425// VideoConfig contains information about a SendVideo request.
426type VideoConfig struct {
427 BaseFile
428 Duration int
429 Caption string
430}
431
432// values returns a url.Values representation of VideoConfig.
433func (config VideoConfig) values() (url.Values, error) {
434 v, err := config.BaseChat.values()
435 if err != nil {
436 return v, err
437 }
438
439 v.Add(config.name(), config.FileID)
440 if config.Duration != 0 {
441 v.Add("duration", strconv.Itoa(config.Duration))
442 }
443 if config.Caption != "" {
444 v.Add("caption", config.Caption)
445 }
446
447 return v, nil
448}
449
450// params returns a map[string]string representation of VideoConfig.
451func (config VideoConfig) params() (map[string]string, error) {
452 params, _ := config.BaseFile.params()
453
454 if config.Caption != "" {
455 params["caption"] = config.Caption
456 }
457
458 return params, nil
459}
460
461// name returns the field name for the Video.
462func (config VideoConfig) name() string {
463 return "video"
464}
465
466// method returns Telegram API method name for sending Video.
467func (config VideoConfig) method() string {
468 return "sendVideo"
469}
470
471// VideoNoteConfig contains information about a SendVideoNote request.
472type VideoNoteConfig struct {
473 BaseFile
474 Duration int
475 Length int
476}
477
478// values returns a url.Values representation of VideoNoteConfig.
479func (config VideoNoteConfig) values() (url.Values, error) {
480 v, err := config.BaseChat.values()
481 if err != nil {
482 return v, err
483 }
484
485 v.Add(config.name(), config.FileID)
486 if config.Duration != 0 {
487 v.Add("duration", strconv.Itoa(config.Duration))
488 }
489
490 // Telegram API seems to have a bug, if no length is provided or it is 0, it will send an error response
491 if config.Length != 0 {
492 v.Add("length", strconv.Itoa(config.Length))
493 }
494
495 return v, nil
496}
497
498// params returns a map[string]string representation of VideoNoteConfig.
499func (config VideoNoteConfig) params() (map[string]string, error) {
500 params, _ := config.BaseFile.params()
501
502 if config.Length != 0 {
503 params["length"] = strconv.Itoa(config.Length)
504 }
505 if config.Duration != 0 {
506 params["duration"] = strconv.Itoa(config.Duration)
507 }
508
509 return params, nil
510}
511
512// name returns the field name for the VideoNote.
513func (config VideoNoteConfig) name() string {
514 return "video_note"
515}
516
517// method returns Telegram API method name for sending VideoNote.
518func (config VideoNoteConfig) method() string {
519 return "sendVideoNote"
520}
521
522// VoiceConfig contains information about a SendVoice request.
523type VoiceConfig struct {
524 BaseFile
525 Caption string
526 Duration int
527}
528
529// values returns a url.Values representation of VoiceConfig.
530func (config VoiceConfig) values() (url.Values, error) {
531 v, err := config.BaseChat.values()
532 if err != nil {
533 return v, err
534 }
535
536 v.Add(config.name(), config.FileID)
537 if config.Duration != 0 {
538 v.Add("duration", strconv.Itoa(config.Duration))
539 }
540 if config.Caption != "" {
541 v.Add("caption", config.Caption)
542 }
543
544 return v, nil
545}
546
547// params returns a map[string]string representation of VoiceConfig.
548func (config VoiceConfig) params() (map[string]string, error) {
549 params, _ := config.BaseFile.params()
550
551 if config.Duration != 0 {
552 params["duration"] = strconv.Itoa(config.Duration)
553 }
554 if config.Caption != "" {
555 params["caption"] = config.Caption
556 }
557
558 return params, nil
559}
560
561// name returns the field name for the Voice.
562func (config VoiceConfig) name() string {
563 return "voice"
564}
565
566// method returns Telegram API method name for sending Voice.
567func (config VoiceConfig) method() string {
568 return "sendVoice"
569}
570
571// LocationConfig contains information about a SendLocation request.
572type LocationConfig struct {
573 BaseChat
574 Latitude float64 // required
575 Longitude float64 // required
576}
577
578// values returns a url.Values representation of LocationConfig.
579func (config LocationConfig) values() (url.Values, error) {
580 v, err := config.BaseChat.values()
581 if err != nil {
582 return v, err
583 }
584
585 v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
586 v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
587
588 return v, nil
589}
590
591// method returns Telegram API method name for sending Location.
592func (config LocationConfig) method() string {
593 return "sendLocation"
594}
595
596// VenueConfig contains information about a SendVenue request.
597type VenueConfig struct {
598 BaseChat
599 Latitude float64 // required
600 Longitude float64 // required
601 Title string // required
602 Address string // required
603 FoursquareID string
604}
605
606func (config VenueConfig) values() (url.Values, error) {
607 v, err := config.BaseChat.values()
608 if err != nil {
609 return v, err
610 }
611
612 v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
613 v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
614 v.Add("title", config.Title)
615 v.Add("address", config.Address)
616 if config.FoursquareID != "" {
617 v.Add("foursquare_id", config.FoursquareID)
618 }
619
620 return v, nil
621}
622
623func (config VenueConfig) method() string {
624 return "sendVenue"
625}
626
627// ContactConfig allows you to send a contact.
628type ContactConfig struct {
629 BaseChat
630 PhoneNumber string
631 FirstName string
632 LastName string
633}
634
635func (config ContactConfig) values() (url.Values, error) {
636 v, err := config.BaseChat.values()
637 if err != nil {
638 return v, err
639 }
640
641 v.Add("phone_number", config.PhoneNumber)
642 v.Add("first_name", config.FirstName)
643 v.Add("last_name", config.LastName)
644
645 return v, nil
646}
647
648func (config ContactConfig) method() string {
649 return "sendContact"
650}
651
652// GameConfig allows you to send a game.
653type GameConfig struct {
654 BaseChat
655 GameShortName string
656}
657
658func (config GameConfig) values() (url.Values, error) {
659 v, err := config.BaseChat.values()
660 if err != nil {
661 return v, err
662 }
663
664 v.Add("game_short_name", config.GameShortName)
665
666 return v, nil
667}
668
669func (config GameConfig) method() string {
670 return "sendGame"
671}
672
673// SetGameScoreConfig allows you to update the game score in a chat.
674type SetGameScoreConfig struct {
675 UserID int
676 Score int
677 Force bool
678 DisableEditMessage bool
679 ChatID int
680 ChannelUsername string
681 MessageID int
682 InlineMessageID string
683}
684
685func (config SetGameScoreConfig) values() (url.Values, error) {
686 v := url.Values{}
687
688 v.Add("user_id", strconv.Itoa(config.UserID))
689 v.Add("score", strconv.Itoa(config.Score))
690 if config.InlineMessageID == "" {
691 if config.ChannelUsername == "" {
692 v.Add("chat_id", strconv.Itoa(config.ChatID))
693 } else {
694 v.Add("chat_id", config.ChannelUsername)
695 }
696 v.Add("message_id", strconv.Itoa(config.MessageID))
697 } else {
698 v.Add("inline_message_id", config.InlineMessageID)
699 }
700 v.Add("disable_edit_message", strconv.FormatBool(config.DisableEditMessage))
701
702 return v, nil
703}
704
705func (config SetGameScoreConfig) method() string {
706 return "setGameScore"
707}
708
709// GetGameHighScoresConfig allows you to fetch the high scores for a game.
710type GetGameHighScoresConfig struct {
711 UserID int
712 ChatID int
713 ChannelUsername string
714 MessageID int
715 InlineMessageID string
716}
717
718func (config GetGameHighScoresConfig) values() (url.Values, error) {
719 v := url.Values{}
720
721 v.Add("user_id", strconv.Itoa(config.UserID))
722 if config.InlineMessageID == "" {
723 if config.ChannelUsername == "" {
724 v.Add("chat_id", strconv.Itoa(config.ChatID))
725 } else {
726 v.Add("chat_id", config.ChannelUsername)
727 }
728 v.Add("message_id", strconv.Itoa(config.MessageID))
729 } else {
730 v.Add("inline_message_id", config.InlineMessageID)
731 }
732
733 return v, nil
734}
735
736func (config GetGameHighScoresConfig) method() string {
737 return "getGameHighScores"
738}
739
740// ChatActionConfig contains information about a SendChatAction request.
741type ChatActionConfig struct {
742 BaseChat
743 Action string // required
744}
745
746// values returns a url.Values representation of ChatActionConfig.
747func (config ChatActionConfig) values() (url.Values, error) {
748 v, err := config.BaseChat.values()
749 if err != nil {
750 return v, err
751 }
752 v.Add("action", config.Action)
753 return v, nil
754}
755
756// method returns Telegram API method name for sending ChatAction.
757func (config ChatActionConfig) method() string {
758 return "sendChatAction"
759}
760
761// EditMessageTextConfig allows you to modify the text in a message.
762type EditMessageTextConfig struct {
763 BaseEdit
764 Text string
765 ParseMode string
766 DisableWebPagePreview bool
767}
768
769func (config EditMessageTextConfig) values() (url.Values, error) {
770 v, err := config.BaseEdit.values()
771 if err != nil {
772 return v, err
773 }
774
775 v.Add("text", config.Text)
776 v.Add("parse_mode", config.ParseMode)
777 v.Add("disable_web_page_preview", strconv.FormatBool(config.DisableWebPagePreview))
778
779 return v, nil
780}
781
782func (config EditMessageTextConfig) method() string {
783 return "editMessageText"
784}
785
786// EditMessageCaptionConfig allows you to modify the caption of a message.
787type EditMessageCaptionConfig struct {
788 BaseEdit
789 Caption string
790}
791
792func (config EditMessageCaptionConfig) values() (url.Values, error) {
793 v, _ := config.BaseEdit.values()
794
795 v.Add("caption", config.Caption)
796
797 return v, nil
798}
799
800func (config EditMessageCaptionConfig) method() string {
801 return "editMessageCaption"
802}
803
804// EditMessageReplyMarkupConfig allows you to modify the reply markup
805// of a message.
806type EditMessageReplyMarkupConfig struct {
807 BaseEdit
808}
809
810func (config EditMessageReplyMarkupConfig) values() (url.Values, error) {
811 return config.BaseEdit.values()
812}
813
814func (config EditMessageReplyMarkupConfig) method() string {
815 return "editMessageReplyMarkup"
816}
817
818// UserProfilePhotosConfig contains information about a
819// GetUserProfilePhotos request.
820type UserProfilePhotosConfig struct {
821 UserID int
822 Offset int
823 Limit int
824}
825
826// FileConfig has information about a file hosted on Telegram.
827type FileConfig struct {
828 FileID string
829}
830
831// UpdateConfig contains information about a GetUpdates request.
832type UpdateConfig struct {
833 Offset int
834 Limit int
835 Timeout int
836}
837
838// WebhookConfig contains information about a SetWebhook request.
839type WebhookConfig struct {
840 URL *url.URL
841 Certificate interface{}
842 MaxConnections int
843}
844
845func (config WebhookConfig) method() string {
846 return "setWebhook"
847}
848
849func (config WebhookConfig) values() (url.Values, error) {
850 v := url.Values{}
851
852 if config.URL != nil {
853 v.Add("url", config.URL.String())
854 }
855 if config.MaxConnections != 0 {
856 v.Add("max_connections", strconv.Itoa(config.MaxConnections))
857 }
858
859 return v, nil
860}
861
862func (config WebhookConfig) params() (map[string]string, error) {
863 params := make(map[string]string)
864
865 if config.URL != nil {
866 params["url"] = config.URL.String()
867 }
868 if config.MaxConnections != 0 {
869 params["max_connections"] = strconv.Itoa(config.MaxConnections)
870 }
871
872 return params, nil
873}
874
875func (config WebhookConfig) name() string {
876 return "certificate"
877}
878
879func (config WebhookConfig) getFile() interface{} {
880 return config.Certificate
881}
882
883func (config WebhookConfig) useExistingFile() bool {
884 return config.URL != nil
885}
886
887// RemoveWebhookConfig is a helper to remove a webhook.
888type RemoveWebhookConfig struct {
889}
890
891func (config RemoveWebhookConfig) method() string {
892 return "setWebhook"
893}
894
895func (config RemoveWebhookConfig) values() (url.Values, error) {
896 return url.Values{}, nil
897}
898
899// FileBytes contains information about a set of bytes to upload
900// as a File.
901type FileBytes struct {
902 Name string
903 Bytes []byte
904}
905
906// FileReader contains information about a reader to upload as a File.
907// If Size is -1, it will read the entire Reader into memory to
908// calculate a Size.
909type FileReader struct {
910 Name string
911 Reader io.Reader
912 Size int64
913}
914
915// InlineConfig contains information on making an InlineQuery response.
916type InlineConfig struct {
917 InlineQueryID string `json:"inline_query_id"`
918 Results []interface{} `json:"results"`
919 CacheTime int `json:"cache_time"`
920 IsPersonal bool `json:"is_personal"`
921 NextOffset string `json:"next_offset"`
922 SwitchPMText string `json:"switch_pm_text"`
923 SwitchPMParameter string `json:"switch_pm_parameter"`
924}
925
926func (config InlineConfig) method() string {
927 return "answerInlineQuery"
928}
929
930func (config InlineConfig) values() (url.Values, error) {
931 v := url.Values{}
932
933 v.Add("inline_query_id", config.InlineQueryID)
934 v.Add("cache_time", strconv.Itoa(config.CacheTime))
935 v.Add("is_personal", strconv.FormatBool(config.IsPersonal))
936 v.Add("next_offset", config.NextOffset)
937 data, err := json.Marshal(config.Results)
938 if err != nil {
939 return v, err
940 }
941 v.Add("results", string(data))
942 v.Add("switch_pm_text", config.SwitchPMText)
943 v.Add("switch_pm_parameter", config.SwitchPMParameter)
944
945 return v, nil
946}
947
948// CallbackConfig contains information on making a CallbackQuery response.
949type CallbackConfig struct {
950 CallbackQueryID string `json:"callback_query_id"`
951 Text string `json:"text"`
952 ShowAlert bool `json:"show_alert"`
953 URL string `json:"url"`
954 CacheTime int `json:"cache_time"`
955}
956
957func (config CallbackConfig) method() string {
958 return "answerCallbackQuery"
959}
960
961func (config CallbackConfig) values() (url.Values, error) {
962 v := url.Values{}
963
964 v.Add("callback_query_id", config.CallbackQueryID)
965 if config.Text != "" {
966 v.Add("text", config.Text)
967 }
968 v.Add("show_alert", strconv.FormatBool(config.ShowAlert))
969 if config.URL != "" {
970 v.Add("url", config.URL)
971 }
972 v.Add("cache_time", strconv.Itoa(config.CacheTime))
973
974 return v, nil
975}
976
977// ChatMemberConfig contains information about a user in a chat for use
978// with administrative functions such as kicking or unbanning a user.
979type ChatMemberConfig struct {
980 ChatID int64
981 SuperGroupUsername string
982 ChannelUsername string
983 UserID int
984}
985
986// UnbanChatMemberConfig allows you to unban a user.
987type UnbanChatMemberConfig struct {
988 ChatMemberConfig
989}
990
991func (config UnbanChatMemberConfig) method() string {
992 return "unbanChatMember"
993}
994
995func (config UnbanChatMemberConfig) values() (url.Values, error) {
996 v := url.Values{}
997
998 if config.SuperGroupUsername != "" {
999 v.Add("chat_id", config.SuperGroupUsername)
1000 } else if config.ChannelUsername != "" {
1001 v.Add("chat_id", config.ChannelUsername)
1002 } else {
1003 v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1004 }
1005 v.Add("user_id", strconv.Itoa(config.UserID))
1006
1007 return v, nil
1008}
1009
1010// KickChatMemberConfig contains extra fields to kick user
1011type KickChatMemberConfig struct {
1012 ChatMemberConfig
1013 UntilDate int64
1014}
1015
1016func (config KickChatMemberConfig) method() string {
1017 return "kickChatMember"
1018}
1019
1020func (config KickChatMemberConfig) values() (url.Values, error) {
1021 v := url.Values{}
1022
1023 if config.SuperGroupUsername == "" {
1024 v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1025 } else {
1026 v.Add("chat_id", config.SuperGroupUsername)
1027 }
1028 v.Add("user_id", strconv.Itoa(config.UserID))
1029
1030 if config.UntilDate != 0 {
1031 v.Add("until_date", strconv.FormatInt(config.UntilDate, 10))
1032 }
1033
1034 return v, nil
1035}
1036
1037// RestrictChatMemberConfig contains fields to restrict members of chat
1038type RestrictChatMemberConfig struct {
1039 ChatMemberConfig
1040 UntilDate int64
1041 CanSendMessages *bool
1042 CanSendMediaMessages *bool
1043 CanSendOtherMessages *bool
1044 CanAddWebPagePreviews *bool
1045}
1046
1047func (config RestrictChatMemberConfig) method() string {
1048 return "restrictChatMember"
1049}
1050
1051func (config RestrictChatMemberConfig) values() (url.Values, error) {
1052 v := url.Values{}
1053
1054 if config.SuperGroupUsername != "" {
1055 v.Add("chat_id", config.SuperGroupUsername)
1056 } else if config.ChannelUsername != "" {
1057 v.Add("chat_id", config.ChannelUsername)
1058 } else {
1059 v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1060 }
1061 v.Add("user_id", strconv.Itoa(config.UserID))
1062
1063 if config.CanSendMessages != nil {
1064 v.Add("can_send_messages", strconv.FormatBool(*config.CanSendMessages))
1065 }
1066 if config.CanSendMediaMessages != nil {
1067 v.Add("can_send_media_messages", strconv.FormatBool(*config.CanSendMediaMessages))
1068 }
1069 if config.CanSendOtherMessages != nil {
1070 v.Add("can_send_other_messages", strconv.FormatBool(*config.CanSendOtherMessages))
1071 }
1072 if config.CanAddWebPagePreviews != nil {
1073 v.Add("can_add_web_page_previews", strconv.FormatBool(*config.CanAddWebPagePreviews))
1074 }
1075 if config.UntilDate != 0 {
1076 v.Add("until_date", strconv.FormatInt(config.UntilDate, 10))
1077 }
1078
1079 return v, nil
1080}
1081
1082// PromoteChatMemberConfig contains fields to promote members of chat
1083type PromoteChatMemberConfig struct {
1084 ChatMemberConfig
1085 CanChangeInfo *bool
1086 CanPostMessages *bool
1087 CanEditMessages *bool
1088 CanDeleteMessages *bool
1089 CanInviteUsers *bool
1090 CanRestrictMembers *bool
1091 CanPinMessages *bool
1092 CanPromoteMembers *bool
1093}
1094
1095func (config PromoteChatMemberConfig) method() string {
1096 return "promoteChatMember"
1097}
1098
1099func (config PromoteChatMemberConfig) values() (url.Values, error) {
1100 v := url.Values{}
1101
1102 if config.SuperGroupUsername != "" {
1103 v.Add("chat_id", config.SuperGroupUsername)
1104 } else if config.ChannelUsername != "" {
1105 v.Add("chat_id", config.ChannelUsername)
1106 } else {
1107 v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1108 }
1109 v.Add("user_id", strconv.Itoa(config.UserID))
1110
1111 if config.CanChangeInfo != nil {
1112 v.Add("can_change_info", strconv.FormatBool(*config.CanChangeInfo))
1113 }
1114 if config.CanPostMessages != nil {
1115 v.Add("can_post_messages", strconv.FormatBool(*config.CanPostMessages))
1116 }
1117 if config.CanEditMessages != nil {
1118 v.Add("can_edit_messages", strconv.FormatBool(*config.CanEditMessages))
1119 }
1120 if config.CanDeleteMessages != nil {
1121 v.Add("can_delete_messages", strconv.FormatBool(*config.CanDeleteMessages))
1122 }
1123 if config.CanInviteUsers != nil {
1124 v.Add("can_invite_users", strconv.FormatBool(*config.CanInviteUsers))
1125 }
1126 if config.CanRestrictMembers != nil {
1127 v.Add("can_restrict_members", strconv.FormatBool(*config.CanRestrictMembers))
1128 }
1129 if config.CanPinMessages != nil {
1130 v.Add("can_pin_messages", strconv.FormatBool(*config.CanPinMessages))
1131 }
1132 if config.CanPromoteMembers != nil {
1133 v.Add("can_promote_members", strconv.FormatBool(*config.CanPromoteMembers))
1134 }
1135
1136 return v, nil
1137}
1138
1139// ChatConfig contains information about getting information on a chat.
1140type ChatConfig struct {
1141 ChatID int64
1142 SuperGroupUsername string
1143}
1144
1145// LeaveChatConfig allows you to leave a chat.
1146type LeaveChatConfig struct {
1147 ChatID int64
1148 ChannelUsername string
1149}
1150
1151func (config LeaveChatConfig) method() string {
1152 return "leaveChat"
1153}
1154
1155func (config LeaveChatConfig) values() (url.Values, error) {
1156 v := url.Values{}
1157
1158 if config.ChannelUsername == "" {
1159 v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1160 } else {
1161 v.Add("chat_id", config.ChannelUsername)
1162 }
1163
1164 return v, nil
1165}
1166
1167// ChatConfigWithUser contains information about getting information on
1168// a specific user within a chat.
1169type ChatConfigWithUser struct {
1170 ChatID int64
1171 SuperGroupUsername string
1172 UserID int
1173}
1174
1175// InvoiceConfig contains information for sendInvoice request.
1176type InvoiceConfig struct {
1177 BaseChat
1178 Title string // required
1179 Description string // required
1180 Payload string // required
1181 ProviderToken string // required
1182 StartParameter string // required
1183 Currency string // required
1184 Prices *[]LabeledPrice // required
1185 PhotoURL string
1186 PhotoSize int
1187 PhotoWidth int
1188 PhotoHeight int
1189 NeedName bool
1190 NeedPhoneNumber bool
1191 NeedEmail bool
1192 NeedShippingAddress bool
1193 IsFlexible bool
1194}
1195
1196func (config InvoiceConfig) values() (url.Values, error) {
1197 v, err := config.BaseChat.values()
1198 if err != nil {
1199 return v, err
1200 }
1201 v.Add("title", config.Title)
1202 v.Add("description", config.Description)
1203 v.Add("payload", config.Payload)
1204 v.Add("provider_token", config.ProviderToken)
1205 v.Add("start_parameter", config.StartParameter)
1206 v.Add("currency", config.Currency)
1207 data, err := json.Marshal(config.Prices)
1208 if err != nil {
1209 return v, err
1210 }
1211 v.Add("prices", string(data))
1212 if config.PhotoURL != "" {
1213 v.Add("photo_url", config.PhotoURL)
1214 }
1215 if config.PhotoSize != 0 {
1216 v.Add("photo_size", strconv.Itoa(config.PhotoSize))
1217 }
1218 if config.PhotoWidth != 0 {
1219 v.Add("photo_width", strconv.Itoa(config.PhotoWidth))
1220 }
1221 if config.PhotoHeight != 0 {
1222 v.Add("photo_height", strconv.Itoa(config.PhotoHeight))
1223 }
1224 if config.NeedName != false {
1225 v.Add("need_name", strconv.FormatBool(config.NeedName))
1226 }
1227 if config.NeedPhoneNumber != false {
1228 v.Add("need_phone_number", strconv.FormatBool(config.NeedPhoneNumber))
1229 }
1230 if config.NeedEmail != false {
1231 v.Add("need_email", strconv.FormatBool(config.NeedEmail))
1232 }
1233 if config.NeedShippingAddress != false {
1234 v.Add("need_shipping_address", strconv.FormatBool(config.NeedShippingAddress))
1235 }
1236 if config.IsFlexible != false {
1237 v.Add("is_flexible", strconv.FormatBool(config.IsFlexible))
1238 }
1239
1240 return v, nil
1241}
1242
1243func (config InvoiceConfig) method() string {
1244 return "sendInvoice"
1245}
1246
1247// ShippingConfig contains information for answerShippingQuery request.
1248type ShippingConfig struct {
1249 ShippingQueryID string // required
1250 OK bool // required
1251 ShippingOptions *[]ShippingOption
1252 ErrorMessage string
1253}
1254
1255// PreCheckoutConfig conatins information for answerPreCheckoutQuery request.
1256type PreCheckoutConfig struct {
1257 PreCheckoutQueryID string // required
1258 OK bool // required
1259 ErrorMessage string
1260}
1261
1262// DeleteMessageConfig contains information of a message in a chat to delete.
1263type DeleteMessageConfig struct {
1264 ChatID int64
1265 MessageID int
1266}
1267
1268func (config DeleteMessageConfig) method() string {
1269 return "deleteMessage"
1270}
1271
1272func (config DeleteMessageConfig) values() (url.Values, error) {
1273 v := url.Values{}
1274
1275 v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1276 v.Add("message_id", strconv.Itoa(config.MessageID))
1277
1278 return v, nil
1279}
1280
1281// PinChatMessageConfig contains information of a message in a chat to pin.
1282type PinChatMessageConfig struct {
1283 ChatID int64
1284 MessageID int
1285 DisableNotification bool
1286}
1287
1288func (config PinChatMessageConfig) method() string {
1289 return "pinChatMessage"
1290}
1291
1292func (config PinChatMessageConfig) values() (url.Values, error) {
1293 v := url.Values{}
1294
1295 v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1296 v.Add("message_id", strconv.Itoa(config.MessageID))
1297 v.Add("disable_notification", strconv.FormatBool(config.DisableNotification))
1298
1299 return v, nil
1300}
1301
1302// UnpinChatMessageConfig contains information of chat to unpin.
1303type UnpinChatMessageConfig struct {
1304 ChatID int64
1305}
1306
1307func (config UnpinChatMessageConfig) method() string {
1308 return "unpinChatMessage"
1309}
1310
1311func (config UnpinChatMessageConfig) values() (url.Values, error) {
1312 v := url.Values{}
1313
1314 v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1315
1316 return v, nil
1317}
1318
1319// SetChatPhotoConfig allows you to set a group, supergroup, or channel's photo.
1320type SetChatPhotoConfig struct {
1321 ChatID int64
1322 ChannelUsername string
1323
1324 Photo interface{}
1325}
1326
1327func (config SetChatPhotoConfig) method() string {
1328 return "setChatPhoto"
1329}
1330
1331func (config SetChatPhotoConfig) name() string {
1332 return "photo"
1333}
1334
1335func (config SetChatPhotoConfig) values() (url.Values, error) {
1336 v := url.Values{}
1337
1338 if config.ChannelUsername == "" {
1339 v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1340 } else {
1341 v.Add("chat_id", config.ChannelUsername)
1342 }
1343
1344 return v, nil
1345}
1346
1347func (config SetChatPhotoConfig) params() map[string]string {
1348 params := make(map[string]string)
1349
1350 if config.ChannelUsername == "" {
1351 params["chat_id"] = strconv.FormatInt(config.ChatID, 10)
1352 } else {
1353 params["chat_id"] = config.ChannelUsername
1354 }
1355
1356 return params
1357}
1358
1359func (config SetChatPhotoConfig) getFile() interface{} {
1360 return config.Photo
1361}
1362
1363func (config SetChatPhotoConfig) useExistingFile() bool {
1364 return false
1365}
1366
1367// DeleteChatPhotoConfig allows you to delete a group, supergroup, or channel's photo.
1368type DeleteChatPhotoConfig struct {
1369 ChatID int64
1370 ChannelUsername string
1371}
1372
1373func (config DeleteChatPhotoConfig) method() string {
1374 return "deleteChatPhoto"
1375}
1376
1377func (config DeleteChatPhotoConfig) values() (url.Values, error) {
1378 v := url.Values{}
1379
1380 if config.ChannelUsername == "" {
1381 v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1382 } else {
1383 v.Add("chat_id", config.ChannelUsername)
1384 }
1385
1386 return v, nil
1387}
1388
1389// SetChatTitleConfig allows you to set the title of something other than a private chat.
1390type SetChatTitleConfig struct {
1391 ChatID int64
1392 ChannelUsername string
1393
1394 Title string
1395}
1396
1397func (config SetChatTitleConfig) method() string {
1398 return "setChatTitle"
1399}
1400
1401func (config SetChatTitleConfig) values() (url.Values, error) {
1402 v := url.Values{}
1403
1404 if config.ChannelUsername == "" {
1405 v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1406 } else {
1407 v.Add("chat_id", config.ChannelUsername)
1408 }
1409
1410 v.Add("title", config.Title)
1411
1412 return v, nil
1413}
1414
1415// SetChatDescriptionConfig allows you to set the description of a supergroup or channel.
1416type SetChatDescriptionConfig struct {
1417 ChatID int64
1418 ChannelUsername string
1419
1420 Description string
1421}
1422
1423func (config SetChatDescriptionConfig) method() string {
1424 return "setChatDescription"
1425}
1426
1427func (config SetChatDescriptionConfig) values() (url.Values, error) {
1428 v := url.Values{}
1429
1430 if config.ChannelUsername == "" {
1431 v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1432 } else {
1433 v.Add("chat_id", config.ChannelUsername)
1434 }
1435
1436 v.Add("description", config.Description)
1437
1438 return v, nil
1439}
1440
1441// GetStickerSetConfig allows you to get the stickers in a set.
1442type GetStickerSetConfig struct {
1443 Name string
1444}
1445
1446func (config GetStickerSetConfig) method() string {
1447 return "getStickerSet"
1448}
1449
1450func (config GetStickerSetConfig) values() (url.Values, error) {
1451 v := url.Values{}
1452
1453 v.Add("name", config.Name)
1454
1455 return v, nil
1456}
1457
1458// UploadStickerConfig allows you to upload a sticker for use in a set later.
1459type UploadStickerConfig struct {
1460 UserID int64
1461 PNGSticker interface{}
1462}
1463
1464func (config UploadStickerConfig) method() string {
1465 return "uploadStickerFile"
1466}
1467
1468func (config UploadStickerConfig) values() (url.Values, error) {
1469 v := url.Values{}
1470
1471 v.Add("user_id", strconv.FormatInt(config.UserID, 10))
1472
1473 return v, nil
1474}
1475
1476func (config UploadStickerConfig) params() (map[string]string, error) {
1477 params := make(map[string]string)
1478
1479 params["user_id"] = strconv.FormatInt(config.UserID, 10)
1480
1481 return params, nil
1482}
1483
1484func (config UploadStickerConfig) name() string {
1485 return "png_sticker"
1486}
1487
1488func (config UploadStickerConfig) getFile() interface{} {
1489 return config.PNGSticker
1490}
1491
1492func (config UploadStickerConfig) useExistingFile() bool {
1493 return false
1494}
1495
1496// NewStickerSetConfig allows creating a new sticker set.
1497type NewStickerSetConfig struct {
1498 UserID int64
1499 Name string
1500 Title string
1501 PNGSticker interface{}
1502 Emojis string
1503 ContainsMasks bool
1504 MaskPosition *MaskPosition
1505}
1506
1507func (config NewStickerSetConfig) method() string {
1508 return "createNewStickerSet"
1509}
1510
1511func (config NewStickerSetConfig) values() (url.Values, error) {
1512 v := url.Values{}
1513
1514 v.Add("user_id", strconv.FormatInt(config.UserID, 10))
1515 v.Add("name", config.Name)
1516 v.Add("title", config.Title)
1517 if sticker, ok := config.PNGSticker.(string); ok {
1518 v.Add("png_sticker", sticker)
1519 }
1520 v.Add("emojis", config.Emojis)
1521 if config.ContainsMasks {
1522 v.Add("contains_masks", strconv.FormatBool(config.ContainsMasks))
1523
1524 data, err := json.Marshal(config.MaskPosition)
1525 if err != nil {
1526 return v, err
1527 }
1528
1529 v.Add("mask_position", string(data))
1530 }
1531
1532 return v, nil
1533}
1534
1535func (config NewStickerSetConfig) params() (map[string]string, error) {
1536 params := make(map[string]string)
1537
1538 params["user_id"] = strconv.FormatInt(config.UserID, 10)
1539 params["name"] = config.Name
1540 params["title"] = config.Title
1541 params["emojis"] = config.Emojis
1542 if config.ContainsMasks {
1543 params["contains_masks"] = strconv.FormatBool(config.ContainsMasks)
1544
1545 data, err := json.Marshal(config.MaskPosition)
1546 if err != nil {
1547 return params, err
1548 }
1549
1550 params["mask_position"] = string(data)
1551 }
1552
1553 return params, nil
1554}
1555
1556func (config NewStickerSetConfig) getFile() interface{} {
1557 return config.PNGSticker
1558}
1559
1560func (config NewStickerSetConfig) name() string {
1561 return "png_sticker"
1562}
1563
1564func (config NewStickerSetConfig) useExistingFile() bool {
1565 _, ok := config.PNGSticker.(string)
1566
1567 return ok
1568}
1569
1570// AddStickerConfig allows you to add a sticker to a set.
1571type AddStickerConfig struct {
1572 UserID int64
1573 Name string
1574 PNGSticker interface{}
1575 Emojis string
1576 MaskPosition *MaskPosition
1577}
1578
1579func (config AddStickerConfig) method() string {
1580 return "addStickerToSet"
1581}
1582
1583func (config AddStickerConfig) values() (url.Values, error) {
1584 v := url.Values{}
1585
1586 v.Add("user_id", strconv.FormatInt(config.UserID, 10))
1587 v.Add("name", config.Name)
1588 if sticker, ok := config.PNGSticker.(string); ok {
1589 v.Add("png_sticker", sticker)
1590 }
1591 v.Add("emojis", config.Emojis)
1592 if config.MaskPosition != nil {
1593 data, err := json.Marshal(config.MaskPosition)
1594 if err != nil {
1595 return v, err
1596 }
1597
1598 v.Add("mask_position", string(data))
1599 }
1600
1601 return v, nil
1602}
1603
1604func (config AddStickerConfig) params() (map[string]string, error) {
1605 params := make(map[string]string)
1606
1607 params["user_id"] = strconv.FormatInt(config.UserID, 10)
1608 params["name"] = config.Name
1609 params["emojis"] = config.Emojis
1610 if config.MaskPosition != nil {
1611 data, err := json.Marshal(config.MaskPosition)
1612 if err != nil {
1613 return params, err
1614 }
1615
1616 params["mask_position"] = string(data)
1617 }
1618
1619 return params, nil
1620}
1621
1622func (config AddStickerConfig) name() string {
1623 return "png_sticker"
1624}
1625
1626func (config AddStickerConfig) getFile() interface{} {
1627 return config.PNGSticker
1628}
1629
1630func (config AddStickerConfig) useExistingFile() bool {
1631 return false
1632}
1633
1634// SetStickerPositionConfig allows you to change the position of a sticker in a set.
1635type SetStickerPositionConfig struct {
1636 Sticker string
1637 Position int
1638}
1639
1640func (config SetStickerPositionConfig) method() string {
1641 return "setStickerPositionInSet"
1642}
1643
1644func (config SetStickerPositionConfig) values() (url.Values, error) {
1645 v := url.Values{}
1646
1647 v.Add("sticker", config.Sticker)
1648 v.Add("position", strconv.Itoa(config.Position))
1649
1650 return v, nil
1651}
1652
1653// DeleteStickerConfig allows you to delete a sticker from a set.
1654type DeleteStickerConfig struct {
1655 Sticker string
1656}
1657
1658func (config DeleteStickerConfig) method() string {
1659 return "deleteStickerFromSet"
1660}
1661
1662func (config DeleteStickerConfig) values() (url.Values, error) {
1663 v := url.Values{}
1664
1665 v.Add("sticker", config.Sticker)
1666
1667 return v, nil
1668}