configs.go (view raw)
1package tgbotapi
2
3import (
4 "fmt"
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 ChatRecordVideoNote = "record_video_note"
30 ChatUploadVideoNote = "upload_video_note"
31)
32
33// API errors
34const (
35 // ErrAPIForbidden happens when a token is bad
36 ErrAPIForbidden = "forbidden"
37)
38
39// Constant values for ParseMode in MessageConfig
40const (
41 ModeMarkdown = "Markdown"
42 ModeMarkdownV2 = "MarkdownV2"
43 ModeHTML = "HTML"
44)
45
46// Library errors
47const (
48 // ErrBadFileType happens when you pass an unknown type
49 ErrBadFileType = "bad file type"
50 ErrBadURL = "bad or empty url"
51)
52
53// Chattable is any config type that can be sent.
54type Chattable interface {
55 params() (Params, error)
56 method() string
57}
58
59// RequestFile represents a file associated with a request. May involve
60// uploading a file, or passing an existing ID.
61type RequestFile struct {
62 // The multipart upload field name.
63 Name string
64 // The file to upload.
65 File interface{}
66}
67
68// Fileable is any config type that can be sent that includes a file.
69type Fileable interface {
70 Chattable
71 files() []RequestFile
72}
73
74// BaseChat is base type for all chat config types.
75type BaseChat struct {
76 ChatID int64 // required
77 ChannelUsername string
78 ReplyToMessageID int
79 ReplyMarkup interface{}
80 DisableNotification bool
81}
82
83func (chat *BaseChat) params() (Params, error) {
84 params := make(Params)
85
86 params.AddFirstValid("chat_id", chat.ChatID, chat.ChannelUsername)
87 params.AddNonZero("reply_to_message_id", chat.ReplyToMessageID)
88 params.AddBool("disable_notification", chat.DisableNotification)
89
90 err := params.AddInterface("reply_markup", chat.ReplyMarkup)
91
92 return params, err
93}
94
95// BaseFile is a base type for all file config types.
96type BaseFile struct {
97 BaseChat
98 File interface{}
99}
100
101func (file BaseFile) params() (Params, error) {
102 return file.BaseChat.params()
103}
104
105// BaseEdit is base type of all chat edits.
106type BaseEdit struct {
107 ChatID int64
108 ChannelUsername string
109 MessageID int
110 InlineMessageID string
111 ReplyMarkup *InlineKeyboardMarkup
112}
113
114func (edit BaseEdit) params() (Params, error) {
115 params := make(Params)
116
117 if edit.InlineMessageID != "" {
118 params["inline_message_id"] = edit.InlineMessageID
119 } else {
120 params.AddFirstValid("chat_id", edit.ChatID, edit.ChannelUsername)
121 params.AddNonZero("message_id", edit.MessageID)
122 }
123
124 err := params.AddInterface("reply_markup", edit.ReplyMarkup)
125
126 return params, err
127}
128
129// MessageConfig contains information about a SendMessage request.
130type MessageConfig struct {
131 BaseChat
132 Text string
133 ParseMode string
134 DisableWebPagePreview bool
135}
136
137func (config MessageConfig) params() (Params, error) {
138 params, err := config.BaseChat.params()
139 if err != nil {
140 return params, err
141 }
142
143 params.AddNonEmpty("text", config.Text)
144 params.AddBool("disable_web_page_preview", config.DisableWebPagePreview)
145 params.AddNonEmpty("parse_mode", config.ParseMode)
146
147 return params, nil
148}
149
150func (config MessageConfig) method() string {
151 return "sendMessage"
152}
153
154// ForwardConfig contains information about a ForwardMessage request.
155type ForwardConfig struct {
156 BaseChat
157 FromChatID int64 // required
158 FromChannelUsername string
159 MessageID int // required
160}
161
162func (config ForwardConfig) params() (Params, error) {
163 params, err := config.BaseChat.params()
164 if err != nil {
165 return params, err
166 }
167
168 params.AddNonZero64("from_chat_id", config.FromChatID)
169 params.AddNonZero("message_id", config.MessageID)
170
171 return params, nil
172}
173
174func (config ForwardConfig) method() string {
175 return "forwardMessage"
176}
177
178// PhotoConfig contains information about a SendPhoto request.
179type PhotoConfig struct {
180 BaseFile
181 Thumb interface{}
182 Caption string
183 ParseMode string
184}
185
186func (config PhotoConfig) params() (Params, error) {
187 params, err := config.BaseFile.params()
188
189 params.AddNonEmpty("caption", config.Caption)
190 params.AddNonEmpty("parse_mode", config.ParseMode)
191
192 return params, err
193}
194
195func (config PhotoConfig) method() string {
196 return "sendPhoto"
197}
198
199func (config PhotoConfig) files() []RequestFile {
200 files := []RequestFile{{
201 Name: "photo",
202 File: config.File,
203 }}
204
205 if config.Thumb != nil {
206 files = append(files, RequestFile{
207 Name: "thumb",
208 File: config.Thumb,
209 })
210 }
211
212 return files
213}
214
215// AudioConfig contains information about a SendAudio request.
216type AudioConfig struct {
217 BaseFile
218 Thumb interface{}
219 Caption string
220 ParseMode string
221 Duration int
222 Performer string
223 Title string
224}
225
226func (config AudioConfig) params() (Params, error) {
227 params, err := config.BaseChat.params()
228 if err != nil {
229 return params, err
230 }
231
232 params.AddNonZero("duration", config.Duration)
233 params.AddNonEmpty("performer", config.Performer)
234 params.AddNonEmpty("title", config.Title)
235 params.AddNonEmpty("caption", config.Caption)
236 params.AddNonEmpty("parse_mode", config.ParseMode)
237
238 return params, nil
239}
240
241func (config AudioConfig) method() string {
242 return "sendAudio"
243}
244
245func (config AudioConfig) files() []RequestFile {
246 files := []RequestFile{{
247 Name: "audio",
248 File: config.File,
249 }}
250
251 if config.Thumb != nil {
252 files = append(files, RequestFile{
253 Name: "thumb",
254 File: config.Thumb,
255 })
256 }
257
258 return files
259}
260
261// DocumentConfig contains information about a SendDocument request.
262type DocumentConfig struct {
263 BaseFile
264 Thumb interface{}
265 Caption string
266 ParseMode string
267}
268
269func (config DocumentConfig) params() (Params, error) {
270 params, err := config.BaseFile.params()
271
272 params.AddNonEmpty("caption", config.Caption)
273 params.AddNonEmpty("parse_mode", config.ParseMode)
274
275 return params, err
276}
277
278func (config DocumentConfig) method() string {
279 return "sendDocument"
280}
281
282func (config DocumentConfig) files() []RequestFile {
283 files := []RequestFile{{
284 Name: "document",
285 File: config.File,
286 }}
287
288 if config.Thumb != nil {
289 files = append(files, RequestFile{
290 Name: "thumb",
291 File: config.Thumb,
292 })
293 }
294
295 return files
296}
297
298// StickerConfig contains information about a SendSticker request.
299type StickerConfig struct {
300 BaseFile
301}
302
303func (config StickerConfig) params() (Params, error) {
304 return config.BaseChat.params()
305}
306
307func (config StickerConfig) method() string {
308 return "sendSticker"
309}
310
311func (config StickerConfig) files() []RequestFile {
312 return []RequestFile{{
313 Name: "sticker",
314 File: config.File,
315 }}
316}
317
318// VideoConfig contains information about a SendVideo request.
319type VideoConfig struct {
320 BaseFile
321 Thumb interface{}
322 Duration int
323 Caption string
324 ParseMode string
325 SupportsStreaming bool
326}
327
328func (config VideoConfig) params() (Params, error) {
329 params, err := config.BaseChat.params()
330
331 params.AddNonZero("duration", config.Duration)
332 params.AddNonEmpty("caption", config.Caption)
333 params.AddNonEmpty("parse_mode", config.ParseMode)
334 params.AddBool("supports_streaming", config.SupportsStreaming)
335
336 return params, err
337}
338
339func (config VideoConfig) method() string {
340 return "sendVideo"
341}
342
343func (config VideoConfig) files() []RequestFile {
344 files := []RequestFile{{
345 Name: "video",
346 File: config.File,
347 }}
348
349 if config.Thumb != nil {
350 files = append(files, RequestFile{
351 Name: "thumb",
352 File: config.Thumb,
353 })
354 }
355
356 return files
357}
358
359// AnimationConfig contains information about a SendAnimation request.
360type AnimationConfig struct {
361 BaseFile
362 Duration int
363 Thumb interface{}
364 Caption string
365 ParseMode string
366}
367
368func (config AnimationConfig) params() (Params, error) {
369 params, err := config.BaseChat.params()
370
371 params.AddNonZero("duration", config.Duration)
372 params.AddNonEmpty("caption", config.Caption)
373 params.AddNonEmpty("parse_mode", config.ParseMode)
374
375 return params, err
376}
377
378func (config AnimationConfig) name() string {
379 return "animation"
380}
381
382func (config AnimationConfig) method() string {
383 return "sendAnimation"
384}
385
386func (config AnimationConfig) files() []RequestFile {
387 files := []RequestFile{{
388 Name: "animation",
389 File: config.File,
390 }}
391
392 if config.Thumb != nil {
393 files = append(files, RequestFile{
394 Name: "thumb",
395 File: config.Thumb,
396 })
397 }
398
399 return files
400}
401
402// VideoNoteConfig contains information about a SendVideoNote request.
403type VideoNoteConfig struct {
404 BaseFile
405 Thumb interface{}
406 Duration int
407 Length int
408}
409
410func (config VideoNoteConfig) params() (Params, error) {
411 params, err := config.BaseChat.params()
412
413 params.AddNonZero("duration", config.Duration)
414 params.AddNonZero("length", config.Length)
415
416 return params, err
417}
418
419func (config VideoNoteConfig) method() string {
420 return "sendVideoNote"
421}
422
423func (config VideoNoteConfig) files() []RequestFile {
424 files := []RequestFile{{
425 Name: "video_note",
426 File: config.File,
427 }}
428
429 if config.Thumb != nil {
430 files = append(files, RequestFile{
431 Name: "thumb",
432 File: config.Thumb,
433 })
434 }
435
436 return files
437}
438
439// VoiceConfig contains information about a SendVoice request.
440type VoiceConfig struct {
441 BaseFile
442 Thumb interface{}
443 Caption string
444 ParseMode string
445 Duration int
446}
447
448func (config VoiceConfig) params() (Params, error) {
449 params, err := config.BaseChat.params()
450
451 params.AddNonZero("duration", config.Duration)
452 params.AddNonEmpty("caption", config.Caption)
453 params.AddNonEmpty("parse_mode", config.ParseMode)
454
455 return params, err
456}
457
458func (config VoiceConfig) method() string {
459 return "sendVoice"
460}
461
462func (config VoiceConfig) files() []RequestFile {
463 files := []RequestFile{{
464 Name: "voice",
465 File: config.File,
466 }}
467
468 if config.Thumb != nil {
469 files = append(files, RequestFile{
470 Name: "thumb",
471 File: config.Thumb,
472 })
473 }
474
475 return files
476}
477
478// LocationConfig contains information about a SendLocation request.
479type LocationConfig struct {
480 BaseChat
481 Latitude float64 // required
482 Longitude float64 // required
483 LivePeriod int // optional
484}
485
486func (config LocationConfig) params() (Params, error) {
487 params, err := config.BaseChat.params()
488
489 params.AddNonZeroFloat("latitude", config.Latitude)
490 params.AddNonZeroFloat("longitude", config.Longitude)
491 params.AddNonZero("live_period", config.LivePeriod)
492
493 return params, err
494}
495
496func (config LocationConfig) method() string {
497 return "sendLocation"
498}
499
500// EditMessageLiveLocationConfig allows you to update a live location.
501type EditMessageLiveLocationConfig struct {
502 BaseEdit
503 Latitude float64 // required
504 Longitude float64 // required
505}
506
507func (config EditMessageLiveLocationConfig) params() (Params, error) {
508 params, err := config.BaseEdit.params()
509
510 params.AddNonZeroFloat("latitude", config.Latitude)
511 params.AddNonZeroFloat("longitude", config.Longitude)
512
513 return params, err
514}
515
516func (config EditMessageLiveLocationConfig) method() string {
517 return "editMessageLiveLocation"
518}
519
520// StopMessageLiveLocationConfig stops updating a live location.
521type StopMessageLiveLocationConfig struct {
522 BaseEdit
523}
524
525func (config StopMessageLiveLocationConfig) params() (Params, error) {
526 return config.BaseEdit.params()
527}
528
529func (config StopMessageLiveLocationConfig) method() string {
530 return "stopMessageLiveLocation"
531}
532
533// VenueConfig contains information about a SendVenue request.
534type VenueConfig struct {
535 BaseChat
536 Latitude float64 // required
537 Longitude float64 // required
538 Title string // required
539 Address string // required
540 FoursquareID string
541}
542
543func (config VenueConfig) params() (Params, error) {
544 params, err := config.BaseChat.params()
545
546 params.AddNonZeroFloat("latitude", config.Latitude)
547 params.AddNonZeroFloat("longitude", config.Longitude)
548 params["title"] = config.Title
549 params["address"] = config.Address
550 params.AddNonEmpty("foursquare_id", config.FoursquareID)
551
552 return params, err
553}
554
555func (config VenueConfig) method() string {
556 return "sendVenue"
557}
558
559// ContactConfig allows you to send a contact.
560type ContactConfig struct {
561 BaseChat
562 PhoneNumber string
563 FirstName string
564 LastName string
565 VCard string
566}
567
568func (config ContactConfig) params() (Params, error) {
569 params, err := config.BaseChat.params()
570
571 params["phone_number"] = config.PhoneNumber
572 params["first_name"] = config.FirstName
573
574 params.AddNonEmpty("last_name", config.LastName)
575 params.AddNonEmpty("vcard", config.VCard)
576
577 return params, err
578}
579
580func (config ContactConfig) method() string {
581 return "sendContact"
582}
583
584// SendPollConfig allows you to send a poll.
585type SendPollConfig struct {
586 BaseChat
587 Question string
588 Options []string
589 IsAnonymous bool
590 Type string
591 AllowsMultipleAnswers bool
592 CorrectOptionID int64
593 Explanation string
594 ExplanationParseMode string
595 OpenPeriod int
596 CloseDate int
597 IsClosed bool
598}
599
600func (config SendPollConfig) params() (Params, error) {
601 params, err := config.BaseChat.params()
602 if err != nil {
603 return params, err
604 }
605
606 params["question"] = config.Question
607 err = params.AddInterface("options", config.Options)
608 params["is_anonymous"] = strconv.FormatBool(config.IsAnonymous)
609 params.AddNonEmpty("type", config.Type)
610 params["allows_multiple_answers"] = strconv.FormatBool(config.AllowsMultipleAnswers)
611 params["correct_option_id"] = strconv.FormatInt(config.CorrectOptionID, 10)
612 params.AddBool("is_closed", config.IsClosed)
613 params.AddNonEmpty("explanation", config.Explanation)
614 params.AddNonEmpty("explanation_parse_mode", config.ExplanationParseMode)
615 params.AddNonZero("open_period", config.OpenPeriod)
616 params.AddNonZero("close_date", config.CloseDate)
617
618 return params, err
619}
620
621func (SendPollConfig) method() string {
622 return "sendPoll"
623}
624
625// GameConfig allows you to send a game.
626type GameConfig struct {
627 BaseChat
628 GameShortName string
629}
630
631func (config GameConfig) params() (Params, error) {
632 params, err := config.BaseChat.params()
633
634 params["game_short_name"] = config.GameShortName
635
636 return params, err
637}
638
639func (config GameConfig) method() string {
640 return "sendGame"
641}
642
643// SetGameScoreConfig allows you to update the game score in a chat.
644type SetGameScoreConfig struct {
645 UserID int
646 Score int
647 Force bool
648 DisableEditMessage bool
649 ChatID int64
650 ChannelUsername string
651 MessageID int
652 InlineMessageID string
653}
654
655func (config SetGameScoreConfig) params() (Params, error) {
656 params := make(Params)
657
658 params.AddNonZero("user_id", config.UserID)
659 params.AddNonZero("scrore", config.Score)
660 params.AddBool("disable_edit_message", config.DisableEditMessage)
661
662 if config.InlineMessageID != "" {
663 params["inline_message_id"] = config.InlineMessageID
664 } else {
665 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
666 params.AddNonZero("message_id", config.MessageID)
667 }
668
669 return params, nil
670}
671
672func (config SetGameScoreConfig) method() string {
673 return "setGameScore"
674}
675
676// GetGameHighScoresConfig allows you to fetch the high scores for a game.
677type GetGameHighScoresConfig struct {
678 UserID int
679 ChatID int
680 ChannelUsername string
681 MessageID int
682 InlineMessageID string
683}
684
685func (config GetGameHighScoresConfig) params() (Params, error) {
686 params := make(Params)
687
688 params.AddNonZero("user_id", config.UserID)
689
690 if config.InlineMessageID != "" {
691 params["inline_message_id"] = config.InlineMessageID
692 } else {
693 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
694 params.AddNonZero("message_id", config.MessageID)
695 }
696
697 return params, nil
698}
699
700func (config GetGameHighScoresConfig) method() string {
701 return "getGameHighScores"
702}
703
704// ChatActionConfig contains information about a SendChatAction request.
705type ChatActionConfig struct {
706 BaseChat
707 Action string // required
708}
709
710func (config ChatActionConfig) params() (Params, error) {
711 params, err := config.BaseChat.params()
712
713 params["action"] = config.Action
714
715 return params, err
716}
717
718func (config ChatActionConfig) method() string {
719 return "sendChatAction"
720}
721
722// EditMessageTextConfig allows you to modify the text in a message.
723type EditMessageTextConfig struct {
724 BaseEdit
725 Text string
726 ParseMode string
727 DisableWebPagePreview bool
728}
729
730func (config EditMessageTextConfig) params() (Params, error) {
731 params, err := config.BaseEdit.params()
732
733 params["text"] = config.Text
734 params.AddNonEmpty("parse_mode", config.ParseMode)
735 params.AddBool("disable_web_page_preview", config.DisableWebPagePreview)
736
737 return params, err
738}
739
740func (config EditMessageTextConfig) method() string {
741 return "editMessageText"
742}
743
744// EditMessageCaptionConfig allows you to modify the caption of a message.
745type EditMessageCaptionConfig struct {
746 BaseEdit
747 Caption string
748 ParseMode string
749}
750
751func (config EditMessageCaptionConfig) params() (Params, error) {
752 params, err := config.BaseEdit.params()
753
754 params["caption"] = config.Caption
755 params.AddNonEmpty("parse_mode", config.ParseMode)
756
757 return params, err
758}
759
760func (config EditMessageCaptionConfig) method() string {
761 return "editMessageCaption"
762}
763
764// EditMessageMediaConfig allows you to make an editMessageMedia request.
765type EditMessageMediaConfig struct {
766 BaseEdit
767
768 Media interface{}
769}
770
771func (EditMessageMediaConfig) method() string {
772 return "editMessageMedia"
773}
774
775func (config EditMessageMediaConfig) params() (Params, error) {
776 params, err := config.BaseEdit.params()
777 if err != nil {
778 return params, err
779 }
780
781 err = params.AddInterface("media", prepareInputMediaParam(config.Media, 0))
782
783 return params, err
784}
785
786func (config EditMessageMediaConfig) files() []RequestFile {
787 return prepareInputMediaFile(config.Media, 0)
788}
789
790// EditMessageReplyMarkupConfig allows you to modify the reply markup
791// of a message.
792type EditMessageReplyMarkupConfig struct {
793 BaseEdit
794}
795
796func (config EditMessageReplyMarkupConfig) params() (Params, error) {
797 return config.BaseEdit.params()
798}
799
800func (config EditMessageReplyMarkupConfig) method() string {
801 return "editMessageReplyMarkup"
802}
803
804// StopPollConfig allows you to stop a poll sent by the bot.
805type StopPollConfig struct {
806 BaseEdit
807}
808
809func (config StopPollConfig) params() (Params, error) {
810 return config.BaseEdit.params()
811}
812
813func (StopPollConfig) method() string {
814 return "stopPoll"
815}
816
817// UserProfilePhotosConfig contains information about a
818// GetUserProfilePhotos request.
819type UserProfilePhotosConfig struct {
820 UserID int
821 Offset int
822 Limit int
823}
824
825func (UserProfilePhotosConfig) method() string {
826 return "getUserProfilePhotos"
827}
828
829func (config UserProfilePhotosConfig) params() (Params, error) {
830 params := make(Params)
831
832 params.AddNonZero("user_id", config.UserID)
833 params.AddNonZero("offset", config.Offset)
834 params.AddNonZero("limit", config.Limit)
835
836 return params, nil
837}
838
839// FileConfig has information about a file hosted on Telegram.
840type FileConfig struct {
841 FileID string
842}
843
844func (FileConfig) method() string {
845 return "getFile"
846}
847
848func (config FileConfig) params() (Params, error) {
849 params := make(Params)
850
851 params["file_id"] = config.FileID
852
853 return params, nil
854}
855
856// UpdateConfig contains information about a GetUpdates request.
857type UpdateConfig struct {
858 Offset int
859 Limit int
860 Timeout int
861}
862
863func (UpdateConfig) method() string {
864 return "getUpdates"
865}
866
867func (config UpdateConfig) params() (Params, error) {
868 params := make(Params)
869
870 params.AddNonZero("offset", config.Offset)
871 params.AddNonZero("limit", config.Limit)
872 params.AddNonZero("timeout", config.Timeout)
873
874 return params, nil
875}
876
877// WebhookConfig contains information about a SetWebhook request.
878type WebhookConfig struct {
879 URL *url.URL
880 Certificate interface{}
881 MaxConnections int
882 AllowedUpdates []string
883}
884
885func (config WebhookConfig) method() string {
886 return "setWebhook"
887}
888
889func (config WebhookConfig) params() (Params, error) {
890 params := make(Params)
891
892 if config.URL != nil {
893 params["url"] = config.URL.String()
894 }
895
896 params.AddNonZero("max_connections", config.MaxConnections)
897 err := params.AddInterface("allowed_updates", config.AllowedUpdates)
898
899 return params, err
900}
901
902func (config WebhookConfig) name() string {
903 return "certificate"
904}
905
906// RemoveWebhookConfig is a helper to remove a webhook.
907type RemoveWebhookConfig struct {
908}
909
910func (config RemoveWebhookConfig) method() string {
911 return "setWebhook"
912}
913
914func (config RemoveWebhookConfig) params() (Params, error) {
915 return nil, nil
916}
917
918// FileBytes contains information about a set of bytes to upload
919// as a File.
920type FileBytes struct {
921 Name string
922 Bytes []byte
923}
924
925// FileReader contains information about a reader to upload as a File.
926// If Size is -1, it will read the entire Reader into memory to
927// calculate a Size.
928type FileReader struct {
929 Name string
930 Reader io.Reader
931 Size int64
932}
933
934// FileURL is a URL to use as a file for a request.
935type FileURL string
936
937// FileID is an ID of a file already uploaded to Telegram.
938type FileID string
939
940// InlineConfig contains information on making an InlineQuery response.
941type InlineConfig struct {
942 InlineQueryID string `json:"inline_query_id"`
943 Results []interface{} `json:"results"`
944 CacheTime int `json:"cache_time"`
945 IsPersonal bool `json:"is_personal"`
946 NextOffset string `json:"next_offset"`
947 SwitchPMText string `json:"switch_pm_text"`
948 SwitchPMParameter string `json:"switch_pm_parameter"`
949}
950
951func (config InlineConfig) method() string {
952 return "answerInlineQuery"
953}
954
955func (config InlineConfig) params() (Params, error) {
956 params := make(Params)
957
958 params["inline_query_id"] = config.InlineQueryID
959 params.AddNonZero("cache_time", config.CacheTime)
960 params.AddBool("is_personal", config.IsPersonal)
961 params.AddNonEmpty("next_offset", config.NextOffset)
962 params.AddNonEmpty("switch_pm_text", config.SwitchPMText)
963 params.AddNonEmpty("switch_pm_parameter", config.SwitchPMParameter)
964
965 if err := params.AddInterface("results", config.Results); err != nil {
966 return params, err
967 }
968
969 return params, nil
970}
971
972// CallbackConfig contains information on making a CallbackQuery response.
973type CallbackConfig struct {
974 CallbackQueryID string `json:"callback_query_id"`
975 Text string `json:"text"`
976 ShowAlert bool `json:"show_alert"`
977 URL string `json:"url"`
978 CacheTime int `json:"cache_time"`
979}
980
981func (config CallbackConfig) method() string {
982 return "answerCallbackQuery"
983}
984
985func (config CallbackConfig) params() (Params, error) {
986 params := make(Params)
987
988 params["callback_query_id"] = config.CallbackQueryID
989 params.AddNonEmpty("text", config.Text)
990 params.AddBool("show_alert", config.ShowAlert)
991 params.AddNonEmpty("url", config.URL)
992 params.AddNonZero("cache_time", config.CacheTime)
993
994 return params, nil
995}
996
997// ChatMemberConfig contains information about a user in a chat for use
998// with administrative functions such as kicking or unbanning a user.
999type ChatMemberConfig struct {
1000 ChatID int64
1001 SuperGroupUsername string
1002 ChannelUsername string
1003 UserID int
1004}
1005
1006// UnbanChatMemberConfig allows you to unban a user.
1007type UnbanChatMemberConfig struct {
1008 ChatMemberConfig
1009}
1010
1011func (config UnbanChatMemberConfig) method() string {
1012 return "unbanChatMember"
1013}
1014
1015func (config UnbanChatMemberConfig) params() (Params, error) {
1016 params := make(Params)
1017
1018 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername)
1019 params.AddNonZero("user_id", config.UserID)
1020
1021 return params, nil
1022}
1023
1024// KickChatMemberConfig contains extra fields to kick user
1025type KickChatMemberConfig struct {
1026 ChatMemberConfig
1027 UntilDate int64
1028}
1029
1030func (config KickChatMemberConfig) method() string {
1031 return "kickChatMember"
1032}
1033
1034func (config KickChatMemberConfig) params() (Params, error) {
1035 params := make(Params)
1036
1037 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1038 params.AddNonZero("user_id", config.UserID)
1039 params.AddNonZero64("until_date", config.UntilDate)
1040
1041 return params, nil
1042}
1043
1044// RestrictChatMemberConfig contains fields to restrict members of chat
1045type RestrictChatMemberConfig struct {
1046 ChatMemberConfig
1047 UntilDate int64
1048 Permissions *ChatPermissions
1049}
1050
1051func (config RestrictChatMemberConfig) method() string {
1052 return "restrictChatMember"
1053}
1054
1055func (config RestrictChatMemberConfig) params() (Params, error) {
1056 params := make(Params)
1057
1058 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername)
1059 params.AddNonZero("user_id", config.UserID)
1060
1061 if err := params.AddInterface("permissions", config.Permissions); err != nil {
1062 return params, err
1063 }
1064 params.AddNonZero64("until_date", config.UntilDate)
1065
1066 return params, nil
1067}
1068
1069// PromoteChatMemberConfig contains fields to promote members of chat
1070type PromoteChatMemberConfig struct {
1071 ChatMemberConfig
1072 CanChangeInfo bool
1073 CanPostMessages bool
1074 CanEditMessages bool
1075 CanDeleteMessages bool
1076 CanInviteUsers bool
1077 CanRestrictMembers bool
1078 CanPinMessages bool
1079 CanPromoteMembers bool
1080}
1081
1082func (config PromoteChatMemberConfig) method() string {
1083 return "promoteChatMember"
1084}
1085
1086func (config PromoteChatMemberConfig) params() (Params, error) {
1087 params := make(Params)
1088
1089 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername)
1090 params.AddNonZero("user_id", config.UserID)
1091
1092 params.AddBool("can_change_info", config.CanChangeInfo)
1093 params.AddBool("can_post_messages", config.CanPostMessages)
1094 params.AddBool("can_edit_messages", config.CanEditMessages)
1095 params.AddBool("can_delete_messages", config.CanDeleteMessages)
1096 params.AddBool("can_invite_users", config.CanInviteUsers)
1097 params.AddBool("can_restrict_members", config.CanRestrictMembers)
1098 params.AddBool("can_pin_messages", config.CanPinMessages)
1099 params.AddBool("can_promote_members", config.CanPromoteMembers)
1100
1101 return params, nil
1102}
1103
1104// SetChatAdministratorCustomTitle sets the title of an administrative user
1105// promoted by the bot for a chat.
1106type SetChatAdministratorCustomTitle struct {
1107 ChatMemberConfig
1108 CustomTitle string
1109}
1110
1111func (SetChatAdministratorCustomTitle) method() string {
1112 return "setChatAdministratorCustomTitle"
1113}
1114
1115func (config SetChatAdministratorCustomTitle) params() (Params, error) {
1116 params := make(Params)
1117
1118 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername)
1119 params.AddNonZero("user_id", config.UserID)
1120 params.AddNonEmpty("custom_title", config.CustomTitle)
1121
1122 return params, nil
1123}
1124
1125// ChatConfig contains information about getting information on a chat.
1126type ChatConfig struct {
1127 ChatID int64
1128 SuperGroupUsername string
1129}
1130
1131func (config ChatConfig) params() (Params, error) {
1132 params := make(Params)
1133
1134 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1135
1136 return params, nil
1137}
1138
1139// ChatInfoConfig contains information about getting chat information.
1140type ChatInfoConfig struct {
1141 ChatConfig
1142}
1143
1144func (ChatInfoConfig) method() string {
1145 return "getChat"
1146}
1147
1148// ChatMemberCountConfig contains information about getting the number of users in a chat.
1149type ChatMemberCountConfig struct {
1150 ChatConfig
1151}
1152
1153func (ChatMemberCountConfig) method() string {
1154 return "getChatMembersCount"
1155}
1156
1157// ChatAdministratorsConfig contains information about getting chat administrators.
1158type ChatAdministratorsConfig struct {
1159 ChatConfig
1160}
1161
1162func (ChatAdministratorsConfig) method() string {
1163 return "getChatAdministrators"
1164}
1165
1166// SetChatPermissionsConfig allows you to set default permissions for the
1167// members in a group. The bot must be an administrator and have rights to
1168// restrict members.
1169type SetChatPermissionsConfig struct {
1170 ChatConfig
1171 Permissions *ChatPermissions
1172}
1173
1174func (SetChatPermissionsConfig) method() string {
1175 return "setChatPermissions"
1176}
1177
1178func (config SetChatPermissionsConfig) params() (Params, error) {
1179 params := make(Params)
1180
1181 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1182 err := params.AddInterface("permissions", config.Permissions)
1183
1184 return params, err
1185}
1186
1187// ChatInviteLinkConfig contains information about getting a chat link.
1188//
1189// Note that generating a new link will revoke any previous links.
1190type ChatInviteLinkConfig struct {
1191 ChatConfig
1192}
1193
1194func (ChatInviteLinkConfig) method() string {
1195 return "exportChatInviteLink"
1196}
1197
1198func (config ChatInviteLinkConfig) params() (Params, error) {
1199 params := make(Params)
1200
1201 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1202
1203 return params, nil
1204}
1205
1206// LeaveChatConfig allows you to leave a chat.
1207type LeaveChatConfig struct {
1208 ChatID int64
1209 ChannelUsername string
1210}
1211
1212func (config LeaveChatConfig) method() string {
1213 return "leaveChat"
1214}
1215
1216func (config LeaveChatConfig) params() (Params, error) {
1217 params := make(Params)
1218
1219 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1220
1221 return params, nil
1222}
1223
1224// ChatConfigWithUser contains information about a chat and a user.
1225type ChatConfigWithUser struct {
1226 ChatID int64
1227 SuperGroupUsername string
1228 UserID int
1229}
1230
1231func (config ChatConfigWithUser) params() (Params, error) {
1232 params := make(Params)
1233
1234 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1235 params.AddNonZero("user_id", config.UserID)
1236
1237 return params, nil
1238}
1239
1240// GetChatMemberConfig is information about getting a specific member in a chat.
1241type GetChatMemberConfig struct {
1242 ChatConfigWithUser
1243}
1244
1245func (GetChatMemberConfig) method() string {
1246 return "getChatMember"
1247}
1248
1249// InvoiceConfig contains information for sendInvoice request.
1250type InvoiceConfig struct {
1251 BaseChat
1252 Title string // required
1253 Description string // required
1254 Payload string // required
1255 ProviderToken string // required
1256 StartParameter string // required
1257 Currency string // required
1258 Prices []LabeledPrice // required
1259 ProviderData string
1260 PhotoURL string
1261 PhotoSize int
1262 PhotoWidth int
1263 PhotoHeight int
1264 NeedName bool
1265 NeedPhoneNumber bool
1266 NeedEmail bool
1267 NeedShippingAddress bool
1268 SendPhoneNumberToProvider bool
1269 SendEmailToProvider bool
1270 IsFlexible bool
1271}
1272
1273func (config InvoiceConfig) params() (Params, error) {
1274 params, err := config.BaseChat.params()
1275 if err != nil {
1276 return params, err
1277 }
1278
1279 params["title"] = config.Title
1280 params["description"] = config.Description
1281 params["payload"] = config.Payload
1282 params["provider_token"] = config.ProviderToken
1283 params["start_parameter"] = config.StartParameter
1284 params["currency"] = config.Currency
1285
1286 if err = params.AddInterface("prices", config.Prices); err != nil {
1287 return params, err
1288 }
1289
1290 params.AddNonEmpty("provider_data", config.ProviderData)
1291 params.AddNonEmpty("photo_url", config.PhotoURL)
1292 params.AddNonZero("photo_size", config.PhotoSize)
1293 params.AddNonZero("photo_width", config.PhotoWidth)
1294 params.AddNonZero("photo_height", config.PhotoHeight)
1295 params.AddBool("need_name", config.NeedName)
1296 params.AddBool("need_phone_number", config.NeedPhoneNumber)
1297 params.AddBool("need_email", config.NeedEmail)
1298 params.AddBool("need_shipping_address", config.NeedShippingAddress)
1299 params.AddBool("is_flexible", config.IsFlexible)
1300 params.AddBool("send_phone_number_to_provider", config.SendPhoneNumberToProvider)
1301 params.AddBool("send_email_to_provider", config.SendEmailToProvider)
1302
1303 return params, nil
1304}
1305
1306func (config InvoiceConfig) method() string {
1307 return "sendInvoice"
1308}
1309
1310// ShippingConfig contains information for answerShippingQuery request.
1311type ShippingConfig struct {
1312 ShippingQueryID string // required
1313 OK bool // required
1314 ShippingOptions []ShippingOption
1315 ErrorMessage string
1316}
1317
1318// PreCheckoutConfig conatins information for answerPreCheckoutQuery request.
1319type PreCheckoutConfig struct {
1320 PreCheckoutQueryID string // required
1321 OK bool // required
1322 ErrorMessage string
1323}
1324
1325// DeleteMessageConfig contains information of a message in a chat to delete.
1326type DeleteMessageConfig struct {
1327 ChannelUsername string
1328 ChatID int64
1329 MessageID int
1330}
1331
1332func (config DeleteMessageConfig) method() string {
1333 return "deleteMessage"
1334}
1335
1336func (config DeleteMessageConfig) params() (Params, error) {
1337 params := make(Params)
1338
1339 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1340 params.AddNonZero("message_id", config.MessageID)
1341
1342 return params, nil
1343}
1344
1345// PinChatMessageConfig contains information of a message in a chat to pin.
1346type PinChatMessageConfig struct {
1347 ChatID int64
1348 ChannelUsername string
1349 MessageID int
1350 DisableNotification bool
1351}
1352
1353func (config PinChatMessageConfig) method() string {
1354 return "pinChatMessage"
1355}
1356
1357func (config PinChatMessageConfig) params() (Params, error) {
1358 params := make(Params)
1359
1360 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1361 params.AddNonZero("message_id", config.MessageID)
1362 params.AddBool("disable_notification", config.DisableNotification)
1363
1364 return params, nil
1365}
1366
1367// UnpinChatMessageConfig contains information of chat to unpin.
1368type UnpinChatMessageConfig struct {
1369 ChatID int64
1370 ChannelUsername string
1371}
1372
1373func (config UnpinChatMessageConfig) method() string {
1374 return "unpinChatMessage"
1375}
1376
1377func (config UnpinChatMessageConfig) params() (Params, error) {
1378 params := make(Params)
1379
1380 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1381
1382 return params, nil
1383}
1384
1385// SetChatPhotoConfig allows you to set a group, supergroup, or channel's photo.
1386type SetChatPhotoConfig struct {
1387 BaseFile
1388}
1389
1390func (config SetChatPhotoConfig) method() string {
1391 return "setChatPhoto"
1392}
1393
1394func (config SetChatPhotoConfig) files() []RequestFile {
1395 return []RequestFile{{
1396 Name: "photo",
1397 File: config.File,
1398 }}
1399}
1400
1401// DeleteChatPhotoConfig allows you to delete a group, supergroup, or channel's photo.
1402type DeleteChatPhotoConfig struct {
1403 ChatID int64
1404 ChannelUsername string
1405}
1406
1407func (config DeleteChatPhotoConfig) method() string {
1408 return "deleteChatPhoto"
1409}
1410
1411func (config DeleteChatPhotoConfig) params() (Params, error) {
1412 params := make(Params)
1413
1414 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1415
1416 return params, nil
1417}
1418
1419// SetChatTitleConfig allows you to set the title of something other than a private chat.
1420type SetChatTitleConfig struct {
1421 ChatID int64
1422 ChannelUsername string
1423
1424 Title string
1425}
1426
1427func (config SetChatTitleConfig) method() string {
1428 return "setChatTitle"
1429}
1430
1431func (config SetChatTitleConfig) params() (Params, error) {
1432 params := make(Params)
1433
1434 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1435 params["title"] = config.Title
1436
1437 return params, nil
1438}
1439
1440// SetChatDescriptionConfig allows you to set the description of a supergroup or channel.
1441type SetChatDescriptionConfig struct {
1442 ChatID int64
1443 ChannelUsername string
1444
1445 Description string
1446}
1447
1448func (config SetChatDescriptionConfig) method() string {
1449 return "setChatDescription"
1450}
1451
1452func (config SetChatDescriptionConfig) params() (Params, error) {
1453 params := make(Params)
1454
1455 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1456 params["description"] = config.Description
1457
1458 return params, nil
1459}
1460
1461// GetStickerSetConfig allows you to get the stickers in a set.
1462type GetStickerSetConfig struct {
1463 Name string
1464}
1465
1466func (config GetStickerSetConfig) method() string {
1467 return "getStickerSet"
1468}
1469
1470func (config GetStickerSetConfig) params() (Params, error) {
1471 params := make(Params)
1472
1473 params["name"] = config.Name
1474
1475 return params, nil
1476}
1477
1478// UploadStickerConfig allows you to upload a sticker for use in a set later.
1479type UploadStickerConfig struct {
1480 UserID int64
1481 PNGSticker interface{}
1482}
1483
1484func (config UploadStickerConfig) method() string {
1485 return "uploadStickerFile"
1486}
1487
1488func (config UploadStickerConfig) params() (Params, error) {
1489 params := make(Params)
1490
1491 params.AddNonZero64("user_id", config.UserID)
1492
1493 return params, nil
1494}
1495
1496func (config UploadStickerConfig) files() []RequestFile {
1497 return []RequestFile{{
1498 Name: "png_sticker",
1499 File: config.PNGSticker,
1500 }}
1501}
1502
1503// NewStickerSetConfig allows creating a new sticker set.
1504//
1505// You must set either PNGSticker or TGSSticker.
1506type NewStickerSetConfig struct {
1507 UserID int64
1508 Name string
1509 Title string
1510 PNGSticker interface{}
1511 TGSSticker interface{}
1512 Emojis string
1513 ContainsMasks bool
1514 MaskPosition *MaskPosition
1515}
1516
1517func (config NewStickerSetConfig) method() string {
1518 return "createNewStickerSet"
1519}
1520
1521func (config NewStickerSetConfig) params() (Params, error) {
1522 params := make(Params)
1523
1524 params.AddNonZero64("user_id", config.UserID)
1525 params["name"] = config.Name
1526 params["title"] = config.Title
1527
1528 params["emojis"] = config.Emojis
1529
1530 params.AddBool("contains_masks", config.ContainsMasks)
1531
1532 err := params.AddInterface("mask_position", config.MaskPosition)
1533
1534 return params, err
1535}
1536
1537func (config NewStickerSetConfig) files() []RequestFile {
1538 if config.PNGSticker != nil {
1539 return []RequestFile{{
1540 Name: "png_sticker",
1541 File: config.PNGSticker,
1542 }}
1543 }
1544
1545 return []RequestFile{{
1546 Name: "tgs_sticker",
1547 File: config.TGSSticker,
1548 }}
1549}
1550
1551// AddStickerConfig allows you to add a sticker to a set.
1552type AddStickerConfig struct {
1553 UserID int64
1554 Name string
1555 PNGSticker interface{}
1556 TGSSticker interface{}
1557 Emojis string
1558 MaskPosition *MaskPosition
1559}
1560
1561func (config AddStickerConfig) method() string {
1562 return "addStickerToSet"
1563}
1564
1565func (config AddStickerConfig) params() (Params, error) {
1566 params := make(Params)
1567
1568 params.AddNonZero64("user_id", config.UserID)
1569 params["name"] = config.Name
1570 params["emojis"] = config.Emojis
1571
1572 err := params.AddInterface("mask_position", config.MaskPosition)
1573
1574 return params, err
1575}
1576
1577func (config AddStickerConfig) files() []RequestFile {
1578 if config.PNGSticker != nil {
1579 return []RequestFile{{
1580 Name: "png_sticker",
1581 File: config.PNGSticker,
1582 }}
1583 }
1584
1585 return []RequestFile{{
1586 Name: "tgs_sticker",
1587 File: config.TGSSticker,
1588 }}
1589
1590}
1591
1592// SetStickerPositionConfig allows you to change the position of a sticker in a set.
1593type SetStickerPositionConfig struct {
1594 Sticker string
1595 Position int
1596}
1597
1598func (config SetStickerPositionConfig) method() string {
1599 return "setStickerPositionInSet"
1600}
1601
1602func (config SetStickerPositionConfig) params() (Params, error) {
1603 params := make(Params)
1604
1605 params["sticker"] = config.Sticker
1606 params.AddNonZero("position", config.Position)
1607
1608 return params, nil
1609}
1610
1611// DeleteStickerConfig allows you to delete a sticker from a set.
1612type DeleteStickerConfig struct {
1613 Sticker string
1614}
1615
1616func (config DeleteStickerConfig) method() string {
1617 return "deleteStickerFromSet"
1618}
1619
1620func (config DeleteStickerConfig) params() (Params, error) {
1621 params := make(Params)
1622
1623 params["sticker"] = config.Sticker
1624
1625 return params, nil
1626}
1627
1628// SetStickerSetThumbConfig allows you to set the thumbnail for a sticker set.
1629type SetStickerSetThumbConfig struct {
1630 Name string
1631 UserID int
1632 Thumb interface{}
1633}
1634
1635func (config SetStickerSetThumbConfig) method() string {
1636 return "setStickerSetThumb"
1637}
1638
1639func (config SetStickerSetThumbConfig) params() (Params, error) {
1640 params := make(Params)
1641
1642 params["name"] = config.Name
1643 params.AddNonZero("user_id", config.UserID)
1644
1645 if thumb, ok := config.Thumb.(string); ok {
1646 params["thumb"] = thumb
1647 }
1648
1649 return params, nil
1650}
1651
1652func (config SetStickerSetThumbConfig) name() string {
1653 return "thumb"
1654}
1655
1656// SetChatStickerSetConfig allows you to set the sticker set for a supergroup.
1657type SetChatStickerSetConfig struct {
1658 ChatID int64
1659 SuperGroupUsername string
1660
1661 StickerSetName string
1662}
1663
1664func (config SetChatStickerSetConfig) method() string {
1665 return "setChatStickerSet"
1666}
1667
1668func (config SetChatStickerSetConfig) params() (Params, error) {
1669 params := make(Params)
1670
1671 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1672 params["sticker_set_name"] = config.StickerSetName
1673
1674 return params, nil
1675}
1676
1677// DeleteChatStickerSetConfig allows you to remove a supergroup's sticker set.
1678type DeleteChatStickerSetConfig struct {
1679 ChatID int64
1680 SuperGroupUsername string
1681}
1682
1683func (config DeleteChatStickerSetConfig) method() string {
1684 return "deleteChatStickerSet"
1685}
1686
1687func (config DeleteChatStickerSetConfig) params() (Params, error) {
1688 params := make(Params)
1689
1690 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1691
1692 return params, nil
1693}
1694
1695// MediaGroupConfig allows you to send a group of media.
1696//
1697// Media consist of InputMedia items (InputMediaPhoto, InputMediaVideo).
1698type MediaGroupConfig struct {
1699 ChatID int64
1700 ChannelUsername string
1701
1702 Media []interface{}
1703 DisableNotification bool
1704 ReplyToMessageID int
1705}
1706
1707func (config MediaGroupConfig) method() string {
1708 return "sendMediaGroup"
1709}
1710
1711func (config MediaGroupConfig) params() (Params, error) {
1712 params := make(Params)
1713
1714 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1715 params.AddBool("disable_notification", config.DisableNotification)
1716 params.AddNonZero("reply_to_message_id", config.ReplyToMessageID)
1717
1718 err := params.AddInterface("media", prepareInputMediaForParams(config.Media))
1719
1720 return params, err
1721}
1722
1723func (config MediaGroupConfig) files() []RequestFile {
1724 return prepareInputMediaForFiles(config.Media)
1725}
1726
1727// DiceConfig allows you to send a random dice roll to Telegram.
1728//
1729// Emoji may be one of the following: 🎲 (1-6), 🎯 (1-6), 🏀 (1-5).
1730type DiceConfig struct {
1731 BaseChat
1732
1733 Emoji string
1734}
1735
1736func (config DiceConfig) method() string {
1737 return "sendDice"
1738}
1739
1740func (config DiceConfig) params() (Params, error) {
1741 params, err := config.BaseChat.params()
1742 if err != nil {
1743 return params, err
1744 }
1745
1746 params.AddNonEmpty("emoji", config.Emoji)
1747
1748 return params, err
1749}
1750
1751// GetMyCommandsConfig gets a list of the currently registered commands.
1752type GetMyCommandsConfig struct{}
1753
1754func (config GetMyCommandsConfig) method() string {
1755 return "getMyCommands"
1756}
1757
1758func (config GetMyCommandsConfig) params() (Params, error) {
1759 return make(Params), nil
1760}
1761
1762// SetMyCommandsConfig sets a list of commands the bot understands.
1763type SetMyCommandsConfig struct {
1764 commands []BotCommand
1765}
1766
1767func (config SetMyCommandsConfig) method() string {
1768 return "setMyCommands"
1769}
1770
1771func (config SetMyCommandsConfig) params() (Params, error) {
1772 params := make(Params)
1773
1774 err := params.AddInterface("commands", config.commands)
1775
1776 return params, err
1777}
1778
1779// prepareInputMediaParam evaluates a single InputMedia and determines if it
1780// needs to be modified for a successful upload. If it returns nil, then the
1781// value does not need to be included in the params. Otherwise, it will return
1782// the same type as was originally provided.
1783//
1784// The idx is used to calculate the file field name. If you only have a single
1785// file, 0 may be used. It is formatted into "attach://file-%d" for the primary
1786// media and "attach://file-%d-thumb" for thumbnails.
1787//
1788// It is expected to be used in conjunction with prepareInputMediaFile.
1789func prepareInputMediaParam(inputMedia interface{}, idx int) interface{} {
1790 switch m := inputMedia.(type) {
1791 case InputMediaPhoto:
1792 switch m.Media.(type) {
1793 case string, FileBytes, FileReader:
1794 m.Media = fmt.Sprintf("attach://file-%d", idx)
1795 }
1796
1797 return m
1798 case InputMediaVideo:
1799 switch m.Media.(type) {
1800 case string, FileBytes, FileReader:
1801 m.Media = fmt.Sprintf("attach://file-%d", idx)
1802 }
1803
1804 switch m.Thumb.(type) {
1805 case string, FileBytes, FileReader:
1806 m.Thumb = fmt.Sprintf("attach://file-%d-thumb", idx)
1807 }
1808
1809 return m
1810 }
1811
1812 return nil
1813}
1814
1815// prepareInputMediaFile generates an array of RequestFile to provide for
1816// Fileable's files method. It returns an array as a single InputMedia may have
1817// multiple files, for the primary media and a thumbnail.
1818//
1819// The idx parameter is used to generate file field names. It uses the names
1820// "file-%d" for the main file and "file-%d-thumb" for the thumbnail.
1821//
1822// It is expected to be used in conjunction with prepareInputMediaParam.
1823func prepareInputMediaFile(inputMedia interface{}, idx int) []RequestFile {
1824 files := []RequestFile{}
1825
1826 switch m := inputMedia.(type) {
1827 case InputMediaPhoto:
1828 switch f := m.Media.(type) {
1829 case string, FileBytes, FileReader:
1830 files = append(files, RequestFile{
1831 Name: fmt.Sprintf("file-%d", idx),
1832 File: f,
1833 })
1834 }
1835 case InputMediaVideo:
1836 switch f := m.Media.(type) {
1837 case string, FileBytes, FileReader:
1838 files = append(files, RequestFile{
1839 Name: fmt.Sprintf("file-%d", idx),
1840 File: f,
1841 })
1842 }
1843
1844 switch f := m.Thumb.(type) {
1845 case string, FileBytes, FileReader:
1846 files = append(files, RequestFile{
1847 Name: fmt.Sprintf("file-%d-thumb", idx),
1848 File: f,
1849 })
1850 }
1851 }
1852
1853 return files
1854}
1855
1856// prepareInputMediaForParams calls prepareInputMediaParam for each item
1857// provided and returns a new array with the correct params for a request.
1858//
1859// It is expected that files will get data from the associated function,
1860// prepareInputMediaForFiles.
1861func prepareInputMediaForParams(inputMedia []interface{}) []interface{} {
1862 newMedia := make([]interface{}, len(inputMedia))
1863 copy(newMedia, inputMedia)
1864
1865 for idx, media := range inputMedia {
1866 if param := prepareInputMediaParam(media, idx); param != nil {
1867 newMedia[idx] = param
1868 }
1869 }
1870
1871 return newMedia
1872}
1873
1874// prepareInputMediaForFiles calls prepareInputMediaFile for each item
1875// provided and returns a new array with the correct files for a request.
1876//
1877// It is expected that params will get data from the associated function,
1878// prepareInputMediaForParams.
1879func prepareInputMediaForFiles(inputMedia []interface{}) []RequestFile {
1880 files := []RequestFile{}
1881
1882 for idx, media := range inputMedia {
1883 if file := prepareInputMediaFile(media, idx); file != nil {
1884 files = append(files, file...)
1885 }
1886 }
1887
1888 return files
1889}