configs.go (view raw)
1package tgbotapi
2
3import (
4 "bytes"
5 "fmt"
6 "io"
7 "net/url"
8 "os"
9 "strconv"
10)
11
12// Telegram constants
13const (
14 // APIEndpoint is the endpoint for all API methods,
15 // with formatting for Sprintf.
16 APIEndpoint = "https://api.telegram.org/bot%s/%s"
17 // FileEndpoint is the endpoint for downloading a file from Telegram.
18 FileEndpoint = "https://api.telegram.org/file/bot%s/%s"
19)
20
21// Constant values for ChatActions
22const (
23 ChatTyping = "typing"
24 ChatUploadPhoto = "upload_photo"
25 ChatRecordVideo = "record_video"
26 ChatUploadVideo = "upload_video"
27 ChatRecordVoice = "record_voice"
28 ChatUploadVoice = "upload_voice"
29 ChatUploadDocument = "upload_document"
30 ChatChooseSticker = "choose_sticker"
31 ChatFindLocation = "find_location"
32 ChatRecordVideoNote = "record_video_note"
33 ChatUploadVideoNote = "upload_video_note"
34)
35
36// API errors
37const (
38 // ErrAPIForbidden happens when a token is bad
39 ErrAPIForbidden = "forbidden"
40)
41
42// Constant values for ParseMode in MessageConfig
43const (
44 ModeMarkdown = "Markdown"
45 ModeMarkdownV2 = "MarkdownV2"
46 ModeHTML = "HTML"
47)
48
49// Constant values for update types
50const (
51 // UpdateTypeMessage is new incoming message of any kind — text, photo, sticker, etc.
52 UpdateTypeMessage = "message"
53
54 // UpdateTypeEditedMessage is new version of a message that is known to the bot and was edited
55 UpdateTypeEditedMessage = "edited_message"
56
57 // UpdateTypeChannelPost is new incoming channel post of any kind — text, photo, sticker, etc.
58 UpdateTypeChannelPost = "channel_post"
59
60 // UpdateTypeEditedChannelPost is new version of a channel post that is known to the bot and was edited
61 UpdateTypeEditedChannelPost = "edited_channel_post"
62
63 // UpdateTypeInlineQuery is new incoming inline query
64 UpdateTypeInlineQuery = "inline_query"
65
66 // UpdateTypeChosenInlineResult i the result of an inline query that was chosen by a user and sent to their
67 // chat partner. Please see the documentation on the feedback collecting for
68 // details on how to enable these updates for your bot.
69 UpdateTypeChosenInlineResult = "chosen_inline_result"
70
71 // UpdateTypeCallbackQuery is new incoming callback query
72 UpdateTypeCallbackQuery = "callback_query"
73
74 // UpdateTypeShippingQuery is new incoming shipping query. Only for invoices with flexible price
75 UpdateTypeShippingQuery = "shipping_query"
76
77 // UpdateTypePreCheckoutQuery is new incoming pre-checkout query. Contains full information about checkout
78 UpdateTypePreCheckoutQuery = "pre_checkout_query"
79
80 // UpdateTypePoll is new poll state. Bots receive only updates about stopped polls and polls
81 // which are sent by the bot
82 UpdateTypePoll = "poll"
83
84 // UpdateTypePollAnswer is when user changed their answer in a non-anonymous poll. Bots receive new votes
85 // only in polls that were sent by the bot itself.
86 UpdateTypePollAnswer = "poll_answer"
87
88 // UpdateTypeMyChatMember is when the bot's chat member status was updated in a chat. For private chats, this
89 // update is received only when the bot is blocked or unblocked by the user.
90 UpdateTypeMyChatMember = "my_chat_member"
91
92 // UpdateTypeChatMember is when the bot must be an administrator in the chat and must explicitly specify
93 // this update in the list of allowed_updates to receive these updates.
94 UpdateTypeChatMember = "chat_member"
95)
96
97// Library errors
98const (
99 ErrBadURL = "bad or empty url"
100)
101
102// Chattable is any config type that can be sent.
103type Chattable interface {
104 params() (Params, error)
105 method() string
106}
107
108// Fileable is any config type that can be sent that includes a file.
109type Fileable interface {
110 Chattable
111 files() []RequestFile
112}
113
114// RequestFile represents a file associated with a field name.
115type RequestFile struct {
116 // The file field name.
117 Name string
118 // The file data to include.
119 Data RequestFileData
120}
121
122// RequestFileData represents the data to be used for a file.
123type RequestFileData interface {
124 // NeedsUpload shows if the file needs to be uploaded.
125 NeedsUpload() bool
126
127 // UploadData gets the file name and an `io.Reader` for the file to be uploaded. This
128 // must only be called when the file needs to be uploaded.
129 UploadData() (string, io.Reader, error)
130 // SendData gets the file data to send when a file does not need to be uploaded. This
131 // must only be called when the file does not need to be uploaded.
132 SendData() string
133}
134
135// FileBytes contains information about a set of bytes to upload
136// as a File.
137type FileBytes struct {
138 Name string
139 Bytes []byte
140}
141
142func (fb FileBytes) NeedsUpload() bool {
143 return true
144}
145
146func (fb FileBytes) UploadData() (string, io.Reader, error) {
147 return fb.Name, bytes.NewReader(fb.Bytes), nil
148}
149
150func (fb FileBytes) SendData() string {
151 panic("FileBytes must be uploaded")
152}
153
154// FileReader contains information about a reader to upload as a File.
155type FileReader struct {
156 Name string
157 Reader io.Reader
158}
159
160func (fr FileReader) NeedsUpload() bool {
161 return true
162}
163
164func (fr FileReader) UploadData() (string, io.Reader, error) {
165 return fr.Name, fr.Reader, nil
166}
167
168func (fr FileReader) SendData() string {
169 panic("FileReader must be uploaded")
170}
171
172// FilePath is a path to a local file.
173type FilePath string
174
175func (fp FilePath) NeedsUpload() bool {
176 return true
177}
178
179func (fp FilePath) UploadData() (string, io.Reader, error) {
180 fileHandle, err := os.Open(string(fp))
181 if err != nil {
182 return "", nil, err
183 }
184
185 name := fileHandle.Name()
186 return name, fileHandle, err
187}
188
189func (fp FilePath) SendData() string {
190 panic("FilePath must be uploaded")
191}
192
193// FileURL is a URL to use as a file for a request.
194type FileURL string
195
196func (fu FileURL) NeedsUpload() bool {
197 return false
198}
199
200func (fu FileURL) UploadData() (string, io.Reader, error) {
201 panic("FileURL cannot be uploaded")
202}
203
204func (fu FileURL) SendData() string {
205 return string(fu)
206}
207
208// FileID is an ID of a file already uploaded to Telegram.
209type FileID string
210
211func (fi FileID) NeedsUpload() bool {
212 return false
213}
214
215func (fi FileID) UploadData() (string, io.Reader, error) {
216 panic("FileID cannot be uploaded")
217}
218
219func (fi FileID) SendData() string {
220 return string(fi)
221}
222
223// fileAttach is an internal file type used for processed media groups.
224type fileAttach string
225
226func (fa fileAttach) NeedsUpload() bool {
227 return false
228}
229
230func (fa fileAttach) UploadData() (string, io.Reader, error) {
231 panic("fileAttach cannot be uploaded")
232}
233
234func (fa fileAttach) SendData() string {
235 return string(fa)
236}
237
238// LogOutConfig is a request to log out of the cloud Bot API server.
239//
240// Note that you may not log back in for at least 10 minutes.
241type LogOutConfig struct{}
242
243func (LogOutConfig) method() string {
244 return "logOut"
245}
246
247func (LogOutConfig) params() (Params, error) {
248 return nil, nil
249}
250
251// CloseConfig is a request to close the bot instance on a local server.
252//
253// Note that you may not close an instance for the first 10 minutes after the
254// bot has started.
255type CloseConfig struct{}
256
257func (CloseConfig) method() string {
258 return "close"
259}
260
261func (CloseConfig) params() (Params, error) {
262 return nil, nil
263}
264
265// BaseChat is base type for all chat config types.
266type BaseChat struct {
267 ChatID int64 // required
268 ChannelUsername string
269 ProtectContent bool
270 ReplyToMessageID int
271 ReplyMarkup interface{}
272 DisableNotification bool
273 AllowSendingWithoutReply bool
274}
275
276func (chat *BaseChat) params() (Params, error) {
277 params := make(Params)
278
279 params.AddFirstValid("chat_id", chat.ChatID, chat.ChannelUsername)
280 params.AddNonZero("reply_to_message_id", chat.ReplyToMessageID)
281 params.AddBool("disable_notification", chat.DisableNotification)
282 params.AddBool("allow_sending_without_reply", chat.AllowSendingWithoutReply)
283 params.AddBool("protect_content", chat.ProtectContent)
284
285 err := params.AddInterface("reply_markup", chat.ReplyMarkup)
286
287 return params, err
288}
289
290// BaseFile is a base type for all file config types.
291type BaseFile struct {
292 BaseChat
293 File RequestFileData
294}
295
296func (file BaseFile) params() (Params, error) {
297 return file.BaseChat.params()
298}
299
300// BaseEdit is base type of all chat edits.
301type BaseEdit struct {
302 ChatID int64
303 ChannelUsername string
304 MessageID int
305 InlineMessageID string
306 ReplyMarkup *InlineKeyboardMarkup
307}
308
309func (edit BaseEdit) params() (Params, error) {
310 params := make(Params)
311
312 if edit.InlineMessageID != "" {
313 params["inline_message_id"] = edit.InlineMessageID
314 } else {
315 params.AddFirstValid("chat_id", edit.ChatID, edit.ChannelUsername)
316 params.AddNonZero("message_id", edit.MessageID)
317 }
318
319 err := params.AddInterface("reply_markup", edit.ReplyMarkup)
320
321 return params, err
322}
323
324// MessageConfig contains information about a SendMessage request.
325type MessageConfig struct {
326 BaseChat
327 Text string
328 ParseMode string
329 Entities []MessageEntity
330 DisableWebPagePreview bool
331}
332
333func (config MessageConfig) params() (Params, error) {
334 params, err := config.BaseChat.params()
335 if err != nil {
336 return params, err
337 }
338
339 params.AddNonEmpty("text", config.Text)
340 params.AddBool("disable_web_page_preview", config.DisableWebPagePreview)
341 params.AddNonEmpty("parse_mode", config.ParseMode)
342 err = params.AddInterface("entities", config.Entities)
343
344 return params, err
345}
346
347func (config MessageConfig) method() string {
348 return "sendMessage"
349}
350
351// ForwardConfig contains information about a ForwardMessage request.
352type ForwardConfig struct {
353 BaseChat
354 FromChatID int64 // required
355 FromChannelUsername string
356 MessageID int // required
357}
358
359func (config ForwardConfig) params() (Params, error) {
360 params, err := config.BaseChat.params()
361 if err != nil {
362 return params, err
363 }
364
365 params.AddNonZero64("from_chat_id", config.FromChatID)
366 params.AddNonZero("message_id", config.MessageID)
367
368 return params, nil
369}
370
371func (config ForwardConfig) method() string {
372 return "forwardMessage"
373}
374
375// CopyMessageConfig contains information about a copyMessage request.
376type CopyMessageConfig struct {
377 BaseChat
378 FromChatID int64
379 FromChannelUsername string
380 MessageID int
381 Caption string
382 ParseMode string
383 CaptionEntities []MessageEntity
384}
385
386func (config CopyMessageConfig) params() (Params, error) {
387 params, err := config.BaseChat.params()
388 if err != nil {
389 return params, err
390 }
391
392 params.AddFirstValid("from_chat_id", config.FromChatID, config.FromChannelUsername)
393 params.AddNonZero("message_id", config.MessageID)
394 params.AddNonEmpty("caption", config.Caption)
395 params.AddNonEmpty("parse_mode", config.ParseMode)
396 err = params.AddInterface("caption_entities", config.CaptionEntities)
397
398 return params, err
399}
400
401func (config CopyMessageConfig) method() string {
402 return "copyMessage"
403}
404
405// PhotoConfig contains information about a SendPhoto request.
406type PhotoConfig struct {
407 BaseFile
408 Thumb RequestFileData
409 Caption string
410 ParseMode string
411 CaptionEntities []MessageEntity
412}
413
414func (config PhotoConfig) params() (Params, error) {
415 params, err := config.BaseFile.params()
416 if err != nil {
417 return params, err
418 }
419
420 params.AddNonEmpty("caption", config.Caption)
421 params.AddNonEmpty("parse_mode", config.ParseMode)
422 err = params.AddInterface("caption_entities", config.CaptionEntities)
423
424 return params, err
425}
426
427func (config PhotoConfig) method() string {
428 return "sendPhoto"
429}
430
431func (config PhotoConfig) files() []RequestFile {
432 files := []RequestFile{{
433 Name: "photo",
434 Data: config.File,
435 }}
436
437 if config.Thumb != nil {
438 files = append(files, RequestFile{
439 Name: "thumb",
440 Data: config.Thumb,
441 })
442 }
443
444 return files
445}
446
447// AudioConfig contains information about a SendAudio request.
448type AudioConfig struct {
449 BaseFile
450 Thumb RequestFileData
451 Caption string
452 ParseMode string
453 CaptionEntities []MessageEntity
454 Duration int
455 Performer string
456 Title string
457}
458
459func (config AudioConfig) params() (Params, error) {
460 params, err := config.BaseChat.params()
461 if err != nil {
462 return params, err
463 }
464
465 params.AddNonZero("duration", config.Duration)
466 params.AddNonEmpty("performer", config.Performer)
467 params.AddNonEmpty("title", config.Title)
468 params.AddNonEmpty("caption", config.Caption)
469 params.AddNonEmpty("parse_mode", config.ParseMode)
470 err = params.AddInterface("caption_entities", config.CaptionEntities)
471
472 return params, err
473}
474
475func (config AudioConfig) method() string {
476 return "sendAudio"
477}
478
479func (config AudioConfig) files() []RequestFile {
480 files := []RequestFile{{
481 Name: "audio",
482 Data: config.File,
483 }}
484
485 if config.Thumb != nil {
486 files = append(files, RequestFile{
487 Name: "thumb",
488 Data: config.Thumb,
489 })
490 }
491
492 return files
493}
494
495// DocumentConfig contains information about a SendDocument request.
496type DocumentConfig struct {
497 BaseFile
498 Thumb RequestFileData
499 Caption string
500 ParseMode string
501 CaptionEntities []MessageEntity
502 DisableContentTypeDetection bool
503}
504
505func (config DocumentConfig) params() (Params, error) {
506 params, err := config.BaseFile.params()
507
508 params.AddNonEmpty("caption", config.Caption)
509 params.AddNonEmpty("parse_mode", config.ParseMode)
510 params.AddBool("disable_content_type_detection", config.DisableContentTypeDetection)
511
512 return params, err
513}
514
515func (config DocumentConfig) method() string {
516 return "sendDocument"
517}
518
519func (config DocumentConfig) files() []RequestFile {
520 files := []RequestFile{{
521 Name: "document",
522 Data: config.File,
523 }}
524
525 if config.Thumb != nil {
526 files = append(files, RequestFile{
527 Name: "thumb",
528 Data: config.Thumb,
529 })
530 }
531
532 return files
533}
534
535// StickerConfig contains information about a SendSticker request.
536type StickerConfig struct {
537 BaseFile
538}
539
540func (config StickerConfig) params() (Params, error) {
541 return config.BaseChat.params()
542}
543
544func (config StickerConfig) method() string {
545 return "sendSticker"
546}
547
548func (config StickerConfig) files() []RequestFile {
549 return []RequestFile{{
550 Name: "sticker",
551 Data: config.File,
552 }}
553}
554
555// VideoConfig contains information about a SendVideo request.
556type VideoConfig struct {
557 BaseFile
558 Thumb RequestFileData
559 Duration int
560 Caption string
561 ParseMode string
562 CaptionEntities []MessageEntity
563 SupportsStreaming bool
564}
565
566func (config VideoConfig) params() (Params, error) {
567 params, err := config.BaseChat.params()
568 if err != nil {
569 return params, err
570 }
571
572 params.AddNonZero("duration", config.Duration)
573 params.AddNonEmpty("caption", config.Caption)
574 params.AddNonEmpty("parse_mode", config.ParseMode)
575 params.AddBool("supports_streaming", config.SupportsStreaming)
576 err = params.AddInterface("caption_entities", config.CaptionEntities)
577
578 return params, err
579}
580
581func (config VideoConfig) method() string {
582 return "sendVideo"
583}
584
585func (config VideoConfig) files() []RequestFile {
586 files := []RequestFile{{
587 Name: "video",
588 Data: config.File,
589 }}
590
591 if config.Thumb != nil {
592 files = append(files, RequestFile{
593 Name: "thumb",
594 Data: config.Thumb,
595 })
596 }
597
598 return files
599}
600
601// AnimationConfig contains information about a SendAnimation request.
602type AnimationConfig struct {
603 BaseFile
604 Duration int
605 Thumb RequestFileData
606 Caption string
607 ParseMode string
608 CaptionEntities []MessageEntity
609}
610
611func (config AnimationConfig) params() (Params, error) {
612 params, err := config.BaseChat.params()
613 if err != nil {
614 return params, err
615 }
616
617 params.AddNonZero("duration", config.Duration)
618 params.AddNonEmpty("caption", config.Caption)
619 params.AddNonEmpty("parse_mode", config.ParseMode)
620 err = params.AddInterface("caption_entities", config.CaptionEntities)
621
622 return params, err
623}
624
625func (config AnimationConfig) method() string {
626 return "sendAnimation"
627}
628
629func (config AnimationConfig) files() []RequestFile {
630 files := []RequestFile{{
631 Name: "animation",
632 Data: config.File,
633 }}
634
635 if config.Thumb != nil {
636 files = append(files, RequestFile{
637 Name: "thumb",
638 Data: config.Thumb,
639 })
640 }
641
642 return files
643}
644
645// VideoNoteConfig contains information about a SendVideoNote request.
646type VideoNoteConfig struct {
647 BaseFile
648 Thumb RequestFileData
649 Duration int
650 Length int
651}
652
653func (config VideoNoteConfig) params() (Params, error) {
654 params, err := config.BaseChat.params()
655
656 params.AddNonZero("duration", config.Duration)
657 params.AddNonZero("length", config.Length)
658
659 return params, err
660}
661
662func (config VideoNoteConfig) method() string {
663 return "sendVideoNote"
664}
665
666func (config VideoNoteConfig) files() []RequestFile {
667 files := []RequestFile{{
668 Name: "video_note",
669 Data: config.File,
670 }}
671
672 if config.Thumb != nil {
673 files = append(files, RequestFile{
674 Name: "thumb",
675 Data: config.Thumb,
676 })
677 }
678
679 return files
680}
681
682// VoiceConfig contains information about a SendVoice request.
683type VoiceConfig struct {
684 BaseFile
685 Thumb RequestFileData
686 Caption string
687 ParseMode string
688 CaptionEntities []MessageEntity
689 Duration int
690}
691
692func (config VoiceConfig) params() (Params, error) {
693 params, err := config.BaseChat.params()
694 if err != nil {
695 return params, err
696 }
697
698 params.AddNonZero("duration", config.Duration)
699 params.AddNonEmpty("caption", config.Caption)
700 params.AddNonEmpty("parse_mode", config.ParseMode)
701 err = params.AddInterface("caption_entities", config.CaptionEntities)
702
703 return params, err
704}
705
706func (config VoiceConfig) method() string {
707 return "sendVoice"
708}
709
710func (config VoiceConfig) files() []RequestFile {
711 files := []RequestFile{{
712 Name: "voice",
713 Data: config.File,
714 }}
715
716 if config.Thumb != nil {
717 files = append(files, RequestFile{
718 Name: "thumb",
719 Data: config.Thumb,
720 })
721 }
722
723 return files
724}
725
726// LocationConfig contains information about a SendLocation request.
727type LocationConfig struct {
728 BaseChat
729 Latitude float64 // required
730 Longitude float64 // required
731 HorizontalAccuracy float64 // optional
732 LivePeriod int // optional
733 Heading int // optional
734 ProximityAlertRadius int // optional
735}
736
737func (config LocationConfig) params() (Params, error) {
738 params, err := config.BaseChat.params()
739
740 params.AddNonZeroFloat("latitude", config.Latitude)
741 params.AddNonZeroFloat("longitude", config.Longitude)
742 params.AddNonZeroFloat("horizontal_accuracy", config.HorizontalAccuracy)
743 params.AddNonZero("live_period", config.LivePeriod)
744 params.AddNonZero("heading", config.Heading)
745 params.AddNonZero("proximity_alert_radius", config.ProximityAlertRadius)
746
747 return params, err
748}
749
750func (config LocationConfig) method() string {
751 return "sendLocation"
752}
753
754// EditMessageLiveLocationConfig allows you to update a live location.
755type EditMessageLiveLocationConfig struct {
756 BaseEdit
757 Latitude float64 // required
758 Longitude float64 // required
759 HorizontalAccuracy float64 // optional
760 Heading int // optional
761 ProximityAlertRadius int // optional
762}
763
764func (config EditMessageLiveLocationConfig) params() (Params, error) {
765 params, err := config.BaseEdit.params()
766
767 params.AddNonZeroFloat("latitude", config.Latitude)
768 params.AddNonZeroFloat("longitude", config.Longitude)
769 params.AddNonZeroFloat("horizontal_accuracy", config.HorizontalAccuracy)
770 params.AddNonZero("heading", config.Heading)
771 params.AddNonZero("proximity_alert_radius", config.ProximityAlertRadius)
772
773 return params, err
774}
775
776func (config EditMessageLiveLocationConfig) method() string {
777 return "editMessageLiveLocation"
778}
779
780// StopMessageLiveLocationConfig stops updating a live location.
781type StopMessageLiveLocationConfig struct {
782 BaseEdit
783}
784
785func (config StopMessageLiveLocationConfig) params() (Params, error) {
786 return config.BaseEdit.params()
787}
788
789func (config StopMessageLiveLocationConfig) method() string {
790 return "stopMessageLiveLocation"
791}
792
793// VenueConfig contains information about a SendVenue request.
794type VenueConfig struct {
795 BaseChat
796 Latitude float64 // required
797 Longitude float64 // required
798 Title string // required
799 Address string // required
800 FoursquareID string
801 FoursquareType string
802 GooglePlaceID string
803 GooglePlaceType string
804}
805
806func (config VenueConfig) params() (Params, error) {
807 params, err := config.BaseChat.params()
808
809 params.AddNonZeroFloat("latitude", config.Latitude)
810 params.AddNonZeroFloat("longitude", config.Longitude)
811 params["title"] = config.Title
812 params["address"] = config.Address
813 params.AddNonEmpty("foursquare_id", config.FoursquareID)
814 params.AddNonEmpty("foursquare_type", config.FoursquareType)
815 params.AddNonEmpty("google_place_id", config.GooglePlaceID)
816 params.AddNonEmpty("google_place_type", config.GooglePlaceType)
817
818 return params, err
819}
820
821func (config VenueConfig) method() string {
822 return "sendVenue"
823}
824
825// ContactConfig allows you to send a contact.
826type ContactConfig struct {
827 BaseChat
828 PhoneNumber string
829 FirstName string
830 LastName string
831 VCard string
832}
833
834func (config ContactConfig) params() (Params, error) {
835 params, err := config.BaseChat.params()
836
837 params["phone_number"] = config.PhoneNumber
838 params["first_name"] = config.FirstName
839
840 params.AddNonEmpty("last_name", config.LastName)
841 params.AddNonEmpty("vcard", config.VCard)
842
843 return params, err
844}
845
846func (config ContactConfig) method() string {
847 return "sendContact"
848}
849
850// SendPollConfig allows you to send a poll.
851type SendPollConfig struct {
852 BaseChat
853 Question string
854 Options []string
855 IsAnonymous bool
856 Type string
857 AllowsMultipleAnswers bool
858 CorrectOptionID int64
859 Explanation string
860 ExplanationParseMode string
861 ExplanationEntities []MessageEntity
862 OpenPeriod int
863 CloseDate int
864 IsClosed bool
865}
866
867func (config SendPollConfig) params() (Params, error) {
868 params, err := config.BaseChat.params()
869 if err != nil {
870 return params, err
871 }
872
873 params["question"] = config.Question
874 if err = params.AddInterface("options", config.Options); err != nil {
875 return params, err
876 }
877 params["is_anonymous"] = strconv.FormatBool(config.IsAnonymous)
878 params.AddNonEmpty("type", config.Type)
879 params["allows_multiple_answers"] = strconv.FormatBool(config.AllowsMultipleAnswers)
880 params["correct_option_id"] = strconv.FormatInt(config.CorrectOptionID, 10)
881 params.AddBool("is_closed", config.IsClosed)
882 params.AddNonEmpty("explanation", config.Explanation)
883 params.AddNonEmpty("explanation_parse_mode", config.ExplanationParseMode)
884 params.AddNonZero("open_period", config.OpenPeriod)
885 params.AddNonZero("close_date", config.CloseDate)
886 err = params.AddInterface("explanation_entities", config.ExplanationEntities)
887
888 return params, err
889}
890
891func (SendPollConfig) method() string {
892 return "sendPoll"
893}
894
895// GameConfig allows you to send a game.
896type GameConfig struct {
897 BaseChat
898 GameShortName string
899}
900
901func (config GameConfig) params() (Params, error) {
902 params, err := config.BaseChat.params()
903
904 params["game_short_name"] = config.GameShortName
905
906 return params, err
907}
908
909func (config GameConfig) method() string {
910 return "sendGame"
911}
912
913// SetGameScoreConfig allows you to update the game score in a chat.
914type SetGameScoreConfig struct {
915 UserID int64
916 Score int
917 Force bool
918 DisableEditMessage bool
919 ChatID int64
920 ChannelUsername string
921 MessageID int
922 InlineMessageID string
923}
924
925func (config SetGameScoreConfig) params() (Params, error) {
926 params := make(Params)
927
928 params.AddNonZero64("user_id", config.UserID)
929 params.AddNonZero("scrore", config.Score)
930 params.AddBool("disable_edit_message", config.DisableEditMessage)
931
932 if config.InlineMessageID != "" {
933 params["inline_message_id"] = config.InlineMessageID
934 } else {
935 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
936 params.AddNonZero("message_id", config.MessageID)
937 }
938
939 return params, nil
940}
941
942func (config SetGameScoreConfig) method() string {
943 return "setGameScore"
944}
945
946// GetGameHighScoresConfig allows you to fetch the high scores for a game.
947type GetGameHighScoresConfig struct {
948 UserID int64
949 ChatID int64
950 ChannelUsername string
951 MessageID int
952 InlineMessageID string
953}
954
955func (config GetGameHighScoresConfig) params() (Params, error) {
956 params := make(Params)
957
958 params.AddNonZero64("user_id", config.UserID)
959
960 if config.InlineMessageID != "" {
961 params["inline_message_id"] = config.InlineMessageID
962 } else {
963 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
964 params.AddNonZero("message_id", config.MessageID)
965 }
966
967 return params, nil
968}
969
970func (config GetGameHighScoresConfig) method() string {
971 return "getGameHighScores"
972}
973
974// ChatActionConfig contains information about a SendChatAction request.
975type ChatActionConfig struct {
976 BaseChat
977 Action string // required
978}
979
980func (config ChatActionConfig) params() (Params, error) {
981 params, err := config.BaseChat.params()
982
983 params["action"] = config.Action
984
985 return params, err
986}
987
988func (config ChatActionConfig) method() string {
989 return "sendChatAction"
990}
991
992// EditMessageTextConfig allows you to modify the text in a message.
993type EditMessageTextConfig struct {
994 BaseEdit
995 Text string
996 ParseMode string
997 Entities []MessageEntity
998 DisableWebPagePreview bool
999}
1000
1001func (config EditMessageTextConfig) params() (Params, error) {
1002 params, err := config.BaseEdit.params()
1003 if err != nil {
1004 return params, err
1005 }
1006
1007 params["text"] = config.Text
1008 params.AddNonEmpty("parse_mode", config.ParseMode)
1009 params.AddBool("disable_web_page_preview", config.DisableWebPagePreview)
1010 err = params.AddInterface("entities", config.Entities)
1011
1012 return params, err
1013}
1014
1015func (config EditMessageTextConfig) method() string {
1016 return "editMessageText"
1017}
1018
1019// EditMessageCaptionConfig allows you to modify the caption of a message.
1020type EditMessageCaptionConfig struct {
1021 BaseEdit
1022 Caption string
1023 ParseMode string
1024 CaptionEntities []MessageEntity
1025}
1026
1027func (config EditMessageCaptionConfig) params() (Params, error) {
1028 params, err := config.BaseEdit.params()
1029 if err != nil {
1030 return params, err
1031 }
1032
1033 params["caption"] = config.Caption
1034 params.AddNonEmpty("parse_mode", config.ParseMode)
1035 err = params.AddInterface("caption_entities", config.CaptionEntities)
1036
1037 return params, err
1038}
1039
1040func (config EditMessageCaptionConfig) method() string {
1041 return "editMessageCaption"
1042}
1043
1044// EditMessageMediaConfig allows you to make an editMessageMedia request.
1045type EditMessageMediaConfig struct {
1046 BaseEdit
1047
1048 Media interface{}
1049}
1050
1051func (EditMessageMediaConfig) method() string {
1052 return "editMessageMedia"
1053}
1054
1055func (config EditMessageMediaConfig) params() (Params, error) {
1056 params, err := config.BaseEdit.params()
1057 if err != nil {
1058 return params, err
1059 }
1060
1061 err = params.AddInterface("media", prepareInputMediaParam(config.Media, 0))
1062
1063 return params, err
1064}
1065
1066func (config EditMessageMediaConfig) files() []RequestFile {
1067 return prepareInputMediaFile(config.Media, 0)
1068}
1069
1070// EditMessageReplyMarkupConfig allows you to modify the reply markup
1071// of a message.
1072type EditMessageReplyMarkupConfig struct {
1073 BaseEdit
1074}
1075
1076func (config EditMessageReplyMarkupConfig) params() (Params, error) {
1077 return config.BaseEdit.params()
1078}
1079
1080func (config EditMessageReplyMarkupConfig) method() string {
1081 return "editMessageReplyMarkup"
1082}
1083
1084// StopPollConfig allows you to stop a poll sent by the bot.
1085type StopPollConfig struct {
1086 BaseEdit
1087}
1088
1089func (config StopPollConfig) params() (Params, error) {
1090 return config.BaseEdit.params()
1091}
1092
1093func (StopPollConfig) method() string {
1094 return "stopPoll"
1095}
1096
1097// UserProfilePhotosConfig contains information about a
1098// GetUserProfilePhotos request.
1099type UserProfilePhotosConfig struct {
1100 UserID int64
1101 Offset int
1102 Limit int
1103}
1104
1105func (UserProfilePhotosConfig) method() string {
1106 return "getUserProfilePhotos"
1107}
1108
1109func (config UserProfilePhotosConfig) params() (Params, error) {
1110 params := make(Params)
1111
1112 params.AddNonZero64("user_id", config.UserID)
1113 params.AddNonZero("offset", config.Offset)
1114 params.AddNonZero("limit", config.Limit)
1115
1116 return params, nil
1117}
1118
1119// FileConfig has information about a file hosted on Telegram.
1120type FileConfig struct {
1121 FileID string
1122}
1123
1124func (FileConfig) method() string {
1125 return "getFile"
1126}
1127
1128func (config FileConfig) params() (Params, error) {
1129 params := make(Params)
1130
1131 params["file_id"] = config.FileID
1132
1133 return params, nil
1134}
1135
1136// UpdateConfig contains information about a GetUpdates request.
1137type UpdateConfig struct {
1138 Offset int
1139 Limit int
1140 Timeout int
1141 AllowedUpdates []string
1142}
1143
1144func (UpdateConfig) method() string {
1145 return "getUpdates"
1146}
1147
1148func (config UpdateConfig) params() (Params, error) {
1149 params := make(Params)
1150
1151 params.AddNonZero("offset", config.Offset)
1152 params.AddNonZero("limit", config.Limit)
1153 params.AddNonZero("timeout", config.Timeout)
1154 params.AddInterface("allowed_updates", config.AllowedUpdates)
1155
1156 return params, nil
1157}
1158
1159// WebhookConfig contains information about a SetWebhook request.
1160type WebhookConfig struct {
1161 URL *url.URL
1162 Certificate RequestFileData
1163 IPAddress string
1164 MaxConnections int
1165 AllowedUpdates []string
1166 DropPendingUpdates bool
1167}
1168
1169func (config WebhookConfig) method() string {
1170 return "setWebhook"
1171}
1172
1173func (config WebhookConfig) params() (Params, error) {
1174 params := make(Params)
1175
1176 if config.URL != nil {
1177 params["url"] = config.URL.String()
1178 }
1179
1180 params.AddNonEmpty("ip_address", config.IPAddress)
1181 params.AddNonZero("max_connections", config.MaxConnections)
1182 err := params.AddInterface("allowed_updates", config.AllowedUpdates)
1183 params.AddBool("drop_pending_updates", config.DropPendingUpdates)
1184
1185 return params, err
1186}
1187
1188func (config WebhookConfig) files() []RequestFile {
1189 if config.Certificate != nil {
1190 return []RequestFile{{
1191 Name: "certificate",
1192 Data: config.Certificate,
1193 }}
1194 }
1195
1196 return nil
1197}
1198
1199// DeleteWebhookConfig is a helper to delete a webhook.
1200type DeleteWebhookConfig struct {
1201 DropPendingUpdates bool
1202}
1203
1204func (config DeleteWebhookConfig) method() string {
1205 return "deleteWebhook"
1206}
1207
1208func (config DeleteWebhookConfig) params() (Params, error) {
1209 params := make(Params)
1210
1211 params.AddBool("drop_pending_updates", config.DropPendingUpdates)
1212
1213 return params, nil
1214}
1215
1216// InlineConfig contains information on making an InlineQuery response.
1217type InlineConfig struct {
1218 InlineQueryID string `json:"inline_query_id"`
1219 Results []interface{} `json:"results"`
1220 CacheTime int `json:"cache_time"`
1221 IsPersonal bool `json:"is_personal"`
1222 NextOffset string `json:"next_offset"`
1223 SwitchPMText string `json:"switch_pm_text"`
1224 SwitchPMParameter string `json:"switch_pm_parameter"`
1225}
1226
1227func (config InlineConfig) method() string {
1228 return "answerInlineQuery"
1229}
1230
1231func (config InlineConfig) params() (Params, error) {
1232 params := make(Params)
1233
1234 params["inline_query_id"] = config.InlineQueryID
1235 params.AddNonZero("cache_time", config.CacheTime)
1236 params.AddBool("is_personal", config.IsPersonal)
1237 params.AddNonEmpty("next_offset", config.NextOffset)
1238 params.AddNonEmpty("switch_pm_text", config.SwitchPMText)
1239 params.AddNonEmpty("switch_pm_parameter", config.SwitchPMParameter)
1240 err := params.AddInterface("results", config.Results)
1241
1242 return params, err
1243}
1244
1245// AnswerWebAppQueryConfig is used to set the result of an interaction with a
1246// Web App and send a corresponding message on behalf of the user to the chat
1247// from which the query originated.
1248type AnswerWebAppQueryConfig struct {
1249 // WebAppQueryID is the unique identifier for the query to be answered.
1250 WebAppQueryID string `json:"web_app_query_id"`
1251 // Result is an InlineQueryResult object describing the message to be sent.
1252 Result interface{} `json:"result"`
1253}
1254
1255func (config AnswerWebAppQueryConfig) method() string {
1256 return "answerWebAppQuery"
1257}
1258
1259func (config AnswerWebAppQueryConfig) params() (Params, error) {
1260 params := make(Params)
1261
1262 params["web_app_query_id"] = config.WebAppQueryID
1263 err := params.AddInterface("result", config.Result)
1264
1265 return params, err
1266}
1267
1268// CallbackConfig contains information on making a CallbackQuery response.
1269type CallbackConfig struct {
1270 CallbackQueryID string `json:"callback_query_id"`
1271 Text string `json:"text"`
1272 ShowAlert bool `json:"show_alert"`
1273 URL string `json:"url"`
1274 CacheTime int `json:"cache_time"`
1275}
1276
1277func (config CallbackConfig) method() string {
1278 return "answerCallbackQuery"
1279}
1280
1281func (config CallbackConfig) params() (Params, error) {
1282 params := make(Params)
1283
1284 params["callback_query_id"] = config.CallbackQueryID
1285 params.AddNonEmpty("text", config.Text)
1286 params.AddBool("show_alert", config.ShowAlert)
1287 params.AddNonEmpty("url", config.URL)
1288 params.AddNonZero("cache_time", config.CacheTime)
1289
1290 return params, nil
1291}
1292
1293// ChatMemberConfig contains information about a user in a chat for use
1294// with administrative functions such as kicking or unbanning a user.
1295type ChatMemberConfig struct {
1296 ChatID int64
1297 SuperGroupUsername string
1298 ChannelUsername string
1299 UserID int64
1300}
1301
1302// UnbanChatMemberConfig allows you to unban a user.
1303type UnbanChatMemberConfig struct {
1304 ChatMemberConfig
1305 OnlyIfBanned bool
1306}
1307
1308func (config UnbanChatMemberConfig) method() string {
1309 return "unbanChatMember"
1310}
1311
1312func (config UnbanChatMemberConfig) params() (Params, error) {
1313 params := make(Params)
1314
1315 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername)
1316 params.AddNonZero64("user_id", config.UserID)
1317 params.AddBool("only_if_banned", config.OnlyIfBanned)
1318
1319 return params, nil
1320}
1321
1322// BanChatMemberConfig contains extra fields to kick user.
1323type BanChatMemberConfig struct {
1324 ChatMemberConfig
1325 UntilDate int64
1326 RevokeMessages bool
1327}
1328
1329func (config BanChatMemberConfig) method() string {
1330 return "banChatMember"
1331}
1332
1333func (config BanChatMemberConfig) params() (Params, error) {
1334 params := make(Params)
1335
1336 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1337 params.AddNonZero64("user_id", config.UserID)
1338 params.AddNonZero64("until_date", config.UntilDate)
1339 params.AddBool("revoke_messages", config.RevokeMessages)
1340
1341 return params, nil
1342}
1343
1344// KickChatMemberConfig contains extra fields to ban user.
1345//
1346// This was renamed to BanChatMember in later versions of the Telegram Bot API.
1347type KickChatMemberConfig = BanChatMemberConfig
1348
1349// RestrictChatMemberConfig contains fields to restrict members of chat
1350type RestrictChatMemberConfig struct {
1351 ChatMemberConfig
1352 UntilDate int64
1353 Permissions *ChatPermissions
1354}
1355
1356func (config RestrictChatMemberConfig) method() string {
1357 return "restrictChatMember"
1358}
1359
1360func (config RestrictChatMemberConfig) params() (Params, error) {
1361 params := make(Params)
1362
1363 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername)
1364 params.AddNonZero64("user_id", config.UserID)
1365
1366 err := params.AddInterface("permissions", config.Permissions)
1367 params.AddNonZero64("until_date", config.UntilDate)
1368
1369 return params, err
1370}
1371
1372// PromoteChatMemberConfig contains fields to promote members of chat
1373type PromoteChatMemberConfig struct {
1374 ChatMemberConfig
1375 IsAnonymous bool
1376 CanManageChat bool
1377 CanChangeInfo bool
1378 CanPostMessages bool
1379 CanEditMessages bool
1380 CanDeleteMessages bool
1381 CanManageVideoChats bool
1382 CanInviteUsers bool
1383 CanRestrictMembers bool
1384 CanPinMessages bool
1385 CanPromoteMembers bool
1386}
1387
1388func (config PromoteChatMemberConfig) method() string {
1389 return "promoteChatMember"
1390}
1391
1392func (config PromoteChatMemberConfig) params() (Params, error) {
1393 params := make(Params)
1394
1395 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername)
1396 params.AddNonZero64("user_id", config.UserID)
1397
1398 params.AddBool("is_anonymous", config.IsAnonymous)
1399 params.AddBool("can_manage_chat", config.CanManageChat)
1400 params.AddBool("can_change_info", config.CanChangeInfo)
1401 params.AddBool("can_post_messages", config.CanPostMessages)
1402 params.AddBool("can_edit_messages", config.CanEditMessages)
1403 params.AddBool("can_delete_messages", config.CanDeleteMessages)
1404 params.AddBool("can_manage_video_chats", config.CanManageVideoChats)
1405 params.AddBool("can_invite_users", config.CanInviteUsers)
1406 params.AddBool("can_restrict_members", config.CanRestrictMembers)
1407 params.AddBool("can_pin_messages", config.CanPinMessages)
1408 params.AddBool("can_promote_members", config.CanPromoteMembers)
1409
1410 return params, nil
1411}
1412
1413// SetChatAdministratorCustomTitle sets the title of an administrative user
1414// promoted by the bot for a chat.
1415type SetChatAdministratorCustomTitle struct {
1416 ChatMemberConfig
1417 CustomTitle string
1418}
1419
1420func (SetChatAdministratorCustomTitle) method() string {
1421 return "setChatAdministratorCustomTitle"
1422}
1423
1424func (config SetChatAdministratorCustomTitle) params() (Params, error) {
1425 params := make(Params)
1426
1427 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername)
1428 params.AddNonZero64("user_id", config.UserID)
1429 params.AddNonEmpty("custom_title", config.CustomTitle)
1430
1431 return params, nil
1432}
1433
1434// BanChatSenderChatConfig bans a channel chat in a supergroup or a channel. The
1435// owner of the chat will not be able to send messages and join live streams on
1436// behalf of the chat, unless it is unbanned first. The bot must be an
1437// administrator in the supergroup or channel for this to work and must have the
1438// appropriate administrator rights.
1439type BanChatSenderChatConfig struct {
1440 ChatID int64
1441 ChannelUsername string
1442 SenderChatID int64
1443 UntilDate int
1444}
1445
1446func (config BanChatSenderChatConfig) method() string {
1447 return "banChatSenderChat"
1448}
1449
1450func (config BanChatSenderChatConfig) params() (Params, error) {
1451 params := make(Params)
1452
1453 _ = params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1454 params.AddNonZero64("sender_chat_id", config.SenderChatID)
1455 params.AddNonZero("until_date", config.UntilDate)
1456
1457 return params, nil
1458}
1459
1460// UnbanChatSenderChatConfig unbans a previously banned channel chat in a
1461// supergroup or channel. The bot must be an administrator for this to work and
1462// must have the appropriate administrator rights.
1463type UnbanChatSenderChatConfig struct {
1464 ChatID int64
1465 ChannelUsername string
1466 SenderChatID int64
1467}
1468
1469func (config UnbanChatSenderChatConfig) method() string {
1470 return "unbanChatSenderChat"
1471}
1472
1473func (config UnbanChatSenderChatConfig) params() (Params, error) {
1474 params := make(Params)
1475
1476 _ = params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1477 params.AddNonZero64("sender_chat_id", config.SenderChatID)
1478
1479 return params, nil
1480}
1481
1482// ChatConfig contains information about getting information on a chat.
1483type ChatConfig struct {
1484 ChatID int64
1485 SuperGroupUsername string
1486}
1487
1488func (config ChatConfig) params() (Params, error) {
1489 params := make(Params)
1490
1491 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1492
1493 return params, nil
1494}
1495
1496// ChatInfoConfig contains information about getting chat information.
1497type ChatInfoConfig struct {
1498 ChatConfig
1499}
1500
1501func (ChatInfoConfig) method() string {
1502 return "getChat"
1503}
1504
1505// ChatMemberCountConfig contains information about getting the number of users in a chat.
1506type ChatMemberCountConfig struct {
1507 ChatConfig
1508}
1509
1510func (ChatMemberCountConfig) method() string {
1511 return "getChatMembersCount"
1512}
1513
1514// ChatAdministratorsConfig contains information about getting chat administrators.
1515type ChatAdministratorsConfig struct {
1516 ChatConfig
1517}
1518
1519func (ChatAdministratorsConfig) method() string {
1520 return "getChatAdministrators"
1521}
1522
1523// SetChatPermissionsConfig allows you to set default permissions for the
1524// members in a group. The bot must be an administrator and have rights to
1525// restrict members.
1526type SetChatPermissionsConfig struct {
1527 ChatConfig
1528 Permissions *ChatPermissions
1529}
1530
1531func (SetChatPermissionsConfig) method() string {
1532 return "setChatPermissions"
1533}
1534
1535func (config SetChatPermissionsConfig) params() (Params, error) {
1536 params := make(Params)
1537
1538 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1539 err := params.AddInterface("permissions", config.Permissions)
1540
1541 return params, err
1542}
1543
1544// ChatInviteLinkConfig contains information about getting a chat link.
1545//
1546// Note that generating a new link will revoke any previous links.
1547type ChatInviteLinkConfig struct {
1548 ChatConfig
1549}
1550
1551func (ChatInviteLinkConfig) method() string {
1552 return "exportChatInviteLink"
1553}
1554
1555func (config ChatInviteLinkConfig) params() (Params, error) {
1556 params := make(Params)
1557
1558 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1559
1560 return params, nil
1561}
1562
1563// CreateChatInviteLinkConfig allows you to create an additional invite link for
1564// a chat. The bot must be an administrator in the chat for this to work and
1565// must have the appropriate admin rights. The link can be revoked using the
1566// RevokeChatInviteLinkConfig.
1567type CreateChatInviteLinkConfig struct {
1568 ChatConfig
1569 Name string
1570 ExpireDate int
1571 MemberLimit int
1572 CreatesJoinRequest bool
1573}
1574
1575func (CreateChatInviteLinkConfig) method() string {
1576 return "createChatInviteLink"
1577}
1578
1579func (config CreateChatInviteLinkConfig) params() (Params, error) {
1580 params := make(Params)
1581
1582 params.AddNonEmpty("name", config.Name)
1583 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1584 params.AddNonZero("expire_date", config.ExpireDate)
1585 params.AddNonZero("member_limit", config.MemberLimit)
1586 params.AddBool("creates_join_request", config.CreatesJoinRequest)
1587
1588 return params, nil
1589}
1590
1591// EditChatInviteLinkConfig allows you to edit a non-primary invite link created
1592// by the bot. The bot must be an administrator in the chat for this to work and
1593// must have the appropriate admin rights.
1594type EditChatInviteLinkConfig struct {
1595 ChatConfig
1596 InviteLink string
1597 Name string
1598 ExpireDate int
1599 MemberLimit int
1600 CreatesJoinRequest bool
1601}
1602
1603func (EditChatInviteLinkConfig) method() string {
1604 return "editChatInviteLink"
1605}
1606
1607func (config EditChatInviteLinkConfig) params() (Params, error) {
1608 params := make(Params)
1609
1610 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1611 params.AddNonEmpty("name", config.Name)
1612 params["invite_link"] = config.InviteLink
1613 params.AddNonZero("expire_date", config.ExpireDate)
1614 params.AddNonZero("member_limit", config.MemberLimit)
1615 params.AddBool("creates_join_request", config.CreatesJoinRequest)
1616
1617 return params, nil
1618}
1619
1620// RevokeChatInviteLinkConfig allows you to revoke an invite link created by the
1621// bot. If the primary link is revoked, a new link is automatically generated.
1622// The bot must be an administrator in the chat for this to work and must have
1623// the appropriate admin rights.
1624type RevokeChatInviteLinkConfig struct {
1625 ChatConfig
1626 InviteLink string
1627}
1628
1629func (RevokeChatInviteLinkConfig) method() string {
1630 return "revokeChatInviteLink"
1631}
1632
1633func (config RevokeChatInviteLinkConfig) params() (Params, error) {
1634 params := make(Params)
1635
1636 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1637 params["invite_link"] = config.InviteLink
1638
1639 return params, nil
1640}
1641
1642// ApproveChatJoinRequestConfig allows you to approve a chat join request.
1643type ApproveChatJoinRequestConfig struct {
1644 ChatConfig
1645 UserID int64
1646}
1647
1648func (ApproveChatJoinRequestConfig) method() string {
1649 return "approveChatJoinRequest"
1650}
1651
1652func (config ApproveChatJoinRequestConfig) params() (Params, error) {
1653 params := make(Params)
1654
1655 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1656 params.AddNonZero("user_id", int(config.UserID))
1657
1658 return params, nil
1659}
1660
1661// DeclineChatJoinRequest allows you to decline a chat join request.
1662type DeclineChatJoinRequest struct {
1663 ChatConfig
1664 UserID int64
1665}
1666
1667func (DeclineChatJoinRequest) method() string {
1668 return "declineChatJoinRequest"
1669}
1670
1671func (config DeclineChatJoinRequest) params() (Params, error) {
1672 params := make(Params)
1673
1674 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1675 params.AddNonZero("user_id", int(config.UserID))
1676
1677 return params, nil
1678}
1679
1680// LeaveChatConfig allows you to leave a chat.
1681type LeaveChatConfig struct {
1682 ChatID int64
1683 ChannelUsername string
1684}
1685
1686func (config LeaveChatConfig) method() string {
1687 return "leaveChat"
1688}
1689
1690func (config LeaveChatConfig) params() (Params, error) {
1691 params := make(Params)
1692
1693 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1694
1695 return params, nil
1696}
1697
1698// ChatConfigWithUser contains information about a chat and a user.
1699type ChatConfigWithUser struct {
1700 ChatID int64
1701 SuperGroupUsername string
1702 UserID int64
1703}
1704
1705func (config ChatConfigWithUser) params() (Params, error) {
1706 params := make(Params)
1707
1708 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1709 params.AddNonZero64("user_id", config.UserID)
1710
1711 return params, nil
1712}
1713
1714// GetChatMemberConfig is information about getting a specific member in a chat.
1715type GetChatMemberConfig struct {
1716 ChatConfigWithUser
1717}
1718
1719func (GetChatMemberConfig) method() string {
1720 return "getChatMember"
1721}
1722
1723// InvoiceConfig contains information for sendInvoice request.
1724type InvoiceConfig struct {
1725 BaseChat
1726 Title string // required
1727 Description string // required
1728 Payload string // required
1729 ProviderToken string // required
1730 Currency string // required
1731 Prices []LabeledPrice // required
1732 MaxTipAmount int
1733 SuggestedTipAmounts []int
1734 StartParameter string
1735 ProviderData string
1736 PhotoURL string
1737 PhotoSize int
1738 PhotoWidth int
1739 PhotoHeight int
1740 NeedName bool
1741 NeedPhoneNumber bool
1742 NeedEmail bool
1743 NeedShippingAddress bool
1744 SendPhoneNumberToProvider bool
1745 SendEmailToProvider bool
1746 IsFlexible bool
1747}
1748
1749func (config InvoiceConfig) params() (Params, error) {
1750 params, err := config.BaseChat.params()
1751 if err != nil {
1752 return params, err
1753 }
1754
1755 params["title"] = config.Title
1756 params["description"] = config.Description
1757 params["payload"] = config.Payload
1758 params["provider_token"] = config.ProviderToken
1759 params["currency"] = config.Currency
1760 if err = params.AddInterface("prices", config.Prices); err != nil {
1761 return params, err
1762 }
1763
1764 params.AddNonZero("max_tip_amount", config.MaxTipAmount)
1765 err = params.AddInterface("suggested_tip_amounts", config.SuggestedTipAmounts)
1766 params.AddNonEmpty("start_parameter", config.StartParameter)
1767 params.AddNonEmpty("provider_data", config.ProviderData)
1768 params.AddNonEmpty("photo_url", config.PhotoURL)
1769 params.AddNonZero("photo_size", config.PhotoSize)
1770 params.AddNonZero("photo_width", config.PhotoWidth)
1771 params.AddNonZero("photo_height", config.PhotoHeight)
1772 params.AddBool("need_name", config.NeedName)
1773 params.AddBool("need_phone_number", config.NeedPhoneNumber)
1774 params.AddBool("need_email", config.NeedEmail)
1775 params.AddBool("need_shipping_address", config.NeedShippingAddress)
1776 params.AddBool("is_flexible", config.IsFlexible)
1777 params.AddBool("send_phone_number_to_provider", config.SendPhoneNumberToProvider)
1778 params.AddBool("send_email_to_provider", config.SendEmailToProvider)
1779
1780 return params, err
1781}
1782
1783func (config InvoiceConfig) method() string {
1784 return "sendInvoice"
1785}
1786
1787// ShippingConfig contains information for answerShippingQuery request.
1788type ShippingConfig struct {
1789 ShippingQueryID string // required
1790 OK bool // required
1791 ShippingOptions []ShippingOption
1792 ErrorMessage string
1793}
1794
1795func (config ShippingConfig) method() string {
1796 return "answerShippingQuery"
1797}
1798
1799func (config ShippingConfig) params() (Params, error) {
1800 params := make(Params)
1801
1802 params["shipping_query_id"] = config.ShippingQueryID
1803 params.AddBool("ok", config.OK)
1804 err := params.AddInterface("shipping_options", config.ShippingOptions)
1805 params.AddNonEmpty("error_message", config.ErrorMessage)
1806
1807 return params, err
1808}
1809
1810// PreCheckoutConfig contains information for answerPreCheckoutQuery request.
1811type PreCheckoutConfig struct {
1812 PreCheckoutQueryID string // required
1813 OK bool // required
1814 ErrorMessage string
1815}
1816
1817func (config PreCheckoutConfig) method() string {
1818 return "answerPreCheckoutQuery"
1819}
1820
1821func (config PreCheckoutConfig) params() (Params, error) {
1822 params := make(Params)
1823
1824 params["pre_checkout_query_id"] = config.PreCheckoutQueryID
1825 params.AddBool("ok", config.OK)
1826 params.AddNonEmpty("error_message", config.ErrorMessage)
1827
1828 return params, nil
1829}
1830
1831// DeleteMessageConfig contains information of a message in a chat to delete.
1832type DeleteMessageConfig struct {
1833 ChannelUsername string
1834 ChatID int64
1835 MessageID int
1836}
1837
1838func (config DeleteMessageConfig) method() string {
1839 return "deleteMessage"
1840}
1841
1842func (config DeleteMessageConfig) params() (Params, error) {
1843 params := make(Params)
1844
1845 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1846 params.AddNonZero("message_id", config.MessageID)
1847
1848 return params, nil
1849}
1850
1851// PinChatMessageConfig contains information of a message in a chat to pin.
1852type PinChatMessageConfig struct {
1853 ChatID int64
1854 ChannelUsername string
1855 MessageID int
1856 DisableNotification bool
1857}
1858
1859func (config PinChatMessageConfig) method() string {
1860 return "pinChatMessage"
1861}
1862
1863func (config PinChatMessageConfig) params() (Params, error) {
1864 params := make(Params)
1865
1866 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1867 params.AddNonZero("message_id", config.MessageID)
1868 params.AddBool("disable_notification", config.DisableNotification)
1869
1870 return params, nil
1871}
1872
1873// UnpinChatMessageConfig contains information of a chat message to unpin.
1874//
1875// If MessageID is not specified, it will unpin the most recent pin.
1876type UnpinChatMessageConfig struct {
1877 ChatID int64
1878 ChannelUsername string
1879 MessageID int
1880}
1881
1882func (config UnpinChatMessageConfig) method() string {
1883 return "unpinChatMessage"
1884}
1885
1886func (config UnpinChatMessageConfig) params() (Params, error) {
1887 params := make(Params)
1888
1889 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1890 params.AddNonZero("message_id", config.MessageID)
1891
1892 return params, nil
1893}
1894
1895// UnpinAllChatMessagesConfig contains information of all messages to unpin in
1896// a chat.
1897type UnpinAllChatMessagesConfig struct {
1898 ChatID int64
1899 ChannelUsername string
1900}
1901
1902func (config UnpinAllChatMessagesConfig) method() string {
1903 return "unpinAllChatMessages"
1904}
1905
1906func (config UnpinAllChatMessagesConfig) params() (Params, error) {
1907 params := make(Params)
1908
1909 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1910
1911 return params, nil
1912}
1913
1914// SetChatPhotoConfig allows you to set a group, supergroup, or channel's photo.
1915type SetChatPhotoConfig struct {
1916 BaseFile
1917}
1918
1919func (config SetChatPhotoConfig) method() string {
1920 return "setChatPhoto"
1921}
1922
1923func (config SetChatPhotoConfig) files() []RequestFile {
1924 return []RequestFile{{
1925 Name: "photo",
1926 Data: config.File,
1927 }}
1928}
1929
1930// DeleteChatPhotoConfig allows you to delete a group, supergroup, or channel's photo.
1931type DeleteChatPhotoConfig struct {
1932 ChatID int64
1933 ChannelUsername string
1934}
1935
1936func (config DeleteChatPhotoConfig) method() string {
1937 return "deleteChatPhoto"
1938}
1939
1940func (config DeleteChatPhotoConfig) params() (Params, error) {
1941 params := make(Params)
1942
1943 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1944
1945 return params, nil
1946}
1947
1948// SetChatTitleConfig allows you to set the title of something other than a private chat.
1949type SetChatTitleConfig struct {
1950 ChatID int64
1951 ChannelUsername string
1952
1953 Title string
1954}
1955
1956func (config SetChatTitleConfig) method() string {
1957 return "setChatTitle"
1958}
1959
1960func (config SetChatTitleConfig) params() (Params, error) {
1961 params := make(Params)
1962
1963 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1964 params["title"] = config.Title
1965
1966 return params, nil
1967}
1968
1969// SetChatDescriptionConfig allows you to set the description of a supergroup or channel.
1970type SetChatDescriptionConfig struct {
1971 ChatID int64
1972 ChannelUsername string
1973
1974 Description string
1975}
1976
1977func (config SetChatDescriptionConfig) method() string {
1978 return "setChatDescription"
1979}
1980
1981func (config SetChatDescriptionConfig) params() (Params, error) {
1982 params := make(Params)
1983
1984 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1985 params["description"] = config.Description
1986
1987 return params, nil
1988}
1989
1990// GetStickerSetConfig allows you to get the stickers in a set.
1991type GetStickerSetConfig struct {
1992 Name string
1993}
1994
1995func (config GetStickerSetConfig) method() string {
1996 return "getStickerSet"
1997}
1998
1999func (config GetStickerSetConfig) params() (Params, error) {
2000 params := make(Params)
2001
2002 params["name"] = config.Name
2003
2004 return params, nil
2005}
2006
2007// GetCustomEmojiStickersConfig get information about
2008// custom emoji stickers by their identifiers.
2009type GetCustomEmojiStickersConfig struct {
2010 CustomEmojiIDs []string
2011}
2012
2013func (config GetCustomEmojiStickersConfig) params() (Params, error) {
2014 params := make(Params)
2015
2016 params.AddInterface("custom_emoji_ids", config.CustomEmojiIDs)
2017
2018 return params, nil
2019}
2020
2021func (config GetCustomEmojiStickersConfig) method() string {
2022 return "getCustomEmojiStickers"
2023}
2024
2025// UploadStickerConfig allows you to upload a sticker for use in a set later.
2026type UploadStickerConfig struct {
2027 UserID int64
2028 PNGSticker RequestFileData
2029}
2030
2031func (config UploadStickerConfig) method() string {
2032 return "uploadStickerFile"
2033}
2034
2035func (config UploadStickerConfig) params() (Params, error) {
2036 params := make(Params)
2037
2038 params.AddNonZero64("user_id", config.UserID)
2039
2040 return params, nil
2041}
2042
2043func (config UploadStickerConfig) files() []RequestFile {
2044 return []RequestFile{{
2045 Name: "png_sticker",
2046 Data: config.PNGSticker,
2047 }}
2048}
2049
2050// NewStickerSetConfig allows creating a new sticker set.
2051//
2052// You must set either PNGSticker or TGSSticker.
2053type NewStickerSetConfig struct {
2054 UserID int64
2055 Name string
2056 Title string
2057 PNGSticker RequestFileData
2058 TGSSticker RequestFileData
2059 StickerType string
2060 Emojis string
2061 ContainsMasks bool // deprecated
2062 MaskPosition *MaskPosition
2063}
2064
2065func (config NewStickerSetConfig) method() string {
2066 return "createNewStickerSet"
2067}
2068
2069func (config NewStickerSetConfig) params() (Params, error) {
2070 params := make(Params)
2071
2072 params.AddNonZero64("user_id", config.UserID)
2073 params["name"] = config.Name
2074 params["title"] = config.Title
2075 params["emojis"] = config.Emojis
2076
2077 params.AddBool("contains_masks", config.ContainsMasks)
2078 params.AddNonEmpty("sticker_type", string(config.StickerType))
2079 err := params.AddInterface("mask_position", config.MaskPosition)
2080
2081 return params, err
2082}
2083
2084func (config NewStickerSetConfig) files() []RequestFile {
2085 if config.PNGSticker != nil {
2086 return []RequestFile{{
2087 Name: "png_sticker",
2088 Data: config.PNGSticker,
2089 }}
2090 }
2091
2092 return []RequestFile{{
2093 Name: "tgs_sticker",
2094 Data: config.TGSSticker,
2095 }}
2096}
2097
2098// AddStickerConfig allows you to add a sticker to a set.
2099type AddStickerConfig struct {
2100 UserID int64
2101 Name string
2102 PNGSticker RequestFileData
2103 TGSSticker RequestFileData
2104 Emojis string
2105 MaskPosition *MaskPosition
2106}
2107
2108func (config AddStickerConfig) method() string {
2109 return "addStickerToSet"
2110}
2111
2112func (config AddStickerConfig) params() (Params, error) {
2113 params := make(Params)
2114
2115 params.AddNonZero64("user_id", config.UserID)
2116 params["name"] = config.Name
2117 params["emojis"] = config.Emojis
2118
2119 err := params.AddInterface("mask_position", config.MaskPosition)
2120
2121 return params, err
2122}
2123
2124func (config AddStickerConfig) files() []RequestFile {
2125 if config.PNGSticker != nil {
2126 return []RequestFile{{
2127 Name: "png_sticker",
2128 Data: config.PNGSticker,
2129 }}
2130 }
2131
2132 return []RequestFile{{
2133 Name: "tgs_sticker",
2134 Data: config.TGSSticker,
2135 }}
2136
2137}
2138
2139// SetStickerPositionConfig allows you to change the position of a sticker in a set.
2140type SetStickerPositionConfig struct {
2141 Sticker string
2142 Position int
2143}
2144
2145func (config SetStickerPositionConfig) method() string {
2146 return "setStickerPositionInSet"
2147}
2148
2149func (config SetStickerPositionConfig) params() (Params, error) {
2150 params := make(Params)
2151
2152 params["sticker"] = config.Sticker
2153 params.AddNonZero("position", config.Position)
2154
2155 return params, nil
2156}
2157
2158// DeleteStickerConfig allows you to delete a sticker from a set.
2159type DeleteStickerConfig struct {
2160 Sticker string
2161}
2162
2163func (config DeleteStickerConfig) method() string {
2164 return "deleteStickerFromSet"
2165}
2166
2167func (config DeleteStickerConfig) params() (Params, error) {
2168 params := make(Params)
2169
2170 params["sticker"] = config.Sticker
2171
2172 return params, nil
2173}
2174
2175// SetStickerSetThumbConfig allows you to set the thumbnail for a sticker set.
2176type SetStickerSetThumbConfig struct {
2177 Name string
2178 UserID int64
2179 Thumb RequestFileData
2180}
2181
2182func (config SetStickerSetThumbConfig) method() string {
2183 return "setStickerSetThumb"
2184}
2185
2186func (config SetStickerSetThumbConfig) params() (Params, error) {
2187 params := make(Params)
2188
2189 params["name"] = config.Name
2190 params.AddNonZero64("user_id", config.UserID)
2191
2192 return params, nil
2193}
2194
2195func (config SetStickerSetThumbConfig) files() []RequestFile {
2196 return []RequestFile{{
2197 Name: "thumb",
2198 Data: config.Thumb,
2199 }}
2200}
2201
2202// SetChatStickerSetConfig allows you to set the sticker set for a supergroup.
2203type SetChatStickerSetConfig struct {
2204 ChatID int64
2205 SuperGroupUsername string
2206
2207 StickerSetName string
2208}
2209
2210func (config SetChatStickerSetConfig) method() string {
2211 return "setChatStickerSet"
2212}
2213
2214func (config SetChatStickerSetConfig) params() (Params, error) {
2215 params := make(Params)
2216
2217 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
2218 params["sticker_set_name"] = config.StickerSetName
2219
2220 return params, nil
2221}
2222
2223// DeleteChatStickerSetConfig allows you to remove a supergroup's sticker set.
2224type DeleteChatStickerSetConfig struct {
2225 ChatID int64
2226 SuperGroupUsername string
2227}
2228
2229func (config DeleteChatStickerSetConfig) method() string {
2230 return "deleteChatStickerSet"
2231}
2232
2233func (config DeleteChatStickerSetConfig) params() (Params, error) {
2234 params := make(Params)
2235
2236 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
2237
2238 return params, nil
2239}
2240
2241// MediaGroupConfig allows you to send a group of media.
2242//
2243// Media consist of InputMedia items (InputMediaPhoto, InputMediaVideo).
2244type MediaGroupConfig struct {
2245 ChatID int64
2246 ChannelUsername string
2247
2248 Media []interface{}
2249 DisableNotification bool
2250 ReplyToMessageID int
2251}
2252
2253func (config MediaGroupConfig) method() string {
2254 return "sendMediaGroup"
2255}
2256
2257func (config MediaGroupConfig) params() (Params, error) {
2258 params := make(Params)
2259
2260 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
2261 params.AddBool("disable_notification", config.DisableNotification)
2262 params.AddNonZero("reply_to_message_id", config.ReplyToMessageID)
2263
2264 err := params.AddInterface("media", prepareInputMediaForParams(config.Media))
2265
2266 return params, err
2267}
2268
2269func (config MediaGroupConfig) files() []RequestFile {
2270 return prepareInputMediaForFiles(config.Media)
2271}
2272
2273// DiceConfig contains information about a sendDice request.
2274type DiceConfig struct {
2275 BaseChat
2276 // Emoji on which the dice throw animation is based.
2277 // Currently, must be one of 🎲, 🎯, 🏀, ⚽, 🎳, or 🎰.
2278 // Dice can have values 1-6 for 🎲, 🎯, and 🎳, values 1-5 for 🏀 and ⚽,
2279 // and values 1-64 for 🎰.
2280 // Defaults to “🎲”
2281 Emoji string
2282}
2283
2284func (config DiceConfig) method() string {
2285 return "sendDice"
2286}
2287
2288func (config DiceConfig) params() (Params, error) {
2289 params, err := config.BaseChat.params()
2290 if err != nil {
2291 return params, err
2292 }
2293
2294 params.AddNonEmpty("emoji", config.Emoji)
2295
2296 return params, err
2297}
2298
2299// GetMyCommandsConfig gets a list of the currently registered commands.
2300type GetMyCommandsConfig struct {
2301 Scope *BotCommandScope
2302 LanguageCode string
2303}
2304
2305func (config GetMyCommandsConfig) method() string {
2306 return "getMyCommands"
2307}
2308
2309func (config GetMyCommandsConfig) params() (Params, error) {
2310 params := make(Params)
2311
2312 err := params.AddInterface("scope", config.Scope)
2313 params.AddNonEmpty("language_code", config.LanguageCode)
2314
2315 return params, err
2316}
2317
2318// SetMyCommandsConfig sets a list of commands the bot understands.
2319type SetMyCommandsConfig struct {
2320 Commands []BotCommand
2321 Scope *BotCommandScope
2322 LanguageCode string
2323}
2324
2325func (config SetMyCommandsConfig) method() string {
2326 return "setMyCommands"
2327}
2328
2329func (config SetMyCommandsConfig) params() (Params, error) {
2330 params := make(Params)
2331
2332 if err := params.AddInterface("commands", config.Commands); err != nil {
2333 return params, err
2334 }
2335 err := params.AddInterface("scope", config.Scope)
2336 params.AddNonEmpty("language_code", config.LanguageCode)
2337
2338 return params, err
2339}
2340
2341type DeleteMyCommandsConfig struct {
2342 Scope *BotCommandScope
2343 LanguageCode string
2344}
2345
2346func (config DeleteMyCommandsConfig) method() string {
2347 return "deleteMyCommands"
2348}
2349
2350func (config DeleteMyCommandsConfig) params() (Params, error) {
2351 params := make(Params)
2352
2353 err := params.AddInterface("scope", config.Scope)
2354 params.AddNonEmpty("language_code", config.LanguageCode)
2355
2356 return params, err
2357}
2358
2359// SetChatMenuButtonConfig changes the bot's menu button in a private chat,
2360// or the default menu button.
2361type SetChatMenuButtonConfig struct {
2362 ChatID int64
2363 ChannelUsername string
2364
2365 MenuButton *MenuButton
2366}
2367
2368func (config SetChatMenuButtonConfig) method() string {
2369 return "setChatMenuButton"
2370}
2371
2372func (config SetChatMenuButtonConfig) params() (Params, error) {
2373 params := make(Params)
2374
2375 if err := params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername); err != nil {
2376 return params, err
2377 }
2378 err := params.AddInterface("menu_button", config.MenuButton)
2379
2380 return params, err
2381}
2382
2383type GetChatMenuButtonConfig struct {
2384 ChatID int64
2385 ChannelUsername string
2386}
2387
2388func (config GetChatMenuButtonConfig) method() string {
2389 return "getChatMenuButton"
2390}
2391
2392func (config GetChatMenuButtonConfig) params() (Params, error) {
2393 params := make(Params)
2394
2395 err := params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
2396
2397 return params, err
2398}
2399
2400type SetMyDefaultAdministratorRightsConfig struct {
2401 Rights ChatAdministratorRights
2402 ForChannels bool
2403}
2404
2405func (config SetMyDefaultAdministratorRightsConfig) method() string {
2406 return "setMyDefaultAdministratorRights"
2407}
2408
2409func (config SetMyDefaultAdministratorRightsConfig) params() (Params, error) {
2410 params := make(Params)
2411
2412 err := params.AddInterface("rights", config.Rights)
2413 params.AddBool("for_channels", config.ForChannels)
2414
2415 return params, err
2416}
2417
2418type GetMyDefaultAdministratorRightsConfig struct {
2419 ForChannels bool
2420}
2421
2422func (config GetMyDefaultAdministratorRightsConfig) method() string {
2423 return "getMyDefaultAdministratorRights"
2424}
2425
2426func (config GetMyDefaultAdministratorRightsConfig) params() (Params, error) {
2427 params := make(Params)
2428
2429 params.AddBool("for_channels", config.ForChannels)
2430
2431 return params, nil
2432}
2433
2434// prepareInputMediaParam evaluates a single InputMedia and determines if it
2435// needs to be modified for a successful upload. If it returns nil, then the
2436// value does not need to be included in the params. Otherwise, it will return
2437// the same type as was originally provided.
2438//
2439// The idx is used to calculate the file field name. If you only have a single
2440// file, 0 may be used. It is formatted into "attach://file-%d" for the primary
2441// media and "attach://file-%d-thumb" for thumbnails.
2442//
2443// It is expected to be used in conjunction with prepareInputMediaFile.
2444func prepareInputMediaParam(inputMedia interface{}, idx int) interface{} {
2445 switch m := inputMedia.(type) {
2446 case InputMediaPhoto:
2447 if m.Media.NeedsUpload() {
2448 m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
2449 }
2450
2451 return m
2452 case InputMediaVideo:
2453 if m.Media.NeedsUpload() {
2454 m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
2455 }
2456
2457 if m.Thumb != nil && m.Thumb.NeedsUpload() {
2458 m.Thumb = fileAttach(fmt.Sprintf("attach://file-%d-thumb", idx))
2459 }
2460
2461 return m
2462 case InputMediaAudio:
2463 if m.Media.NeedsUpload() {
2464 m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
2465 }
2466
2467 if m.Thumb != nil && m.Thumb.NeedsUpload() {
2468 m.Thumb = fileAttach(fmt.Sprintf("attach://file-%d-thumb", idx))
2469 }
2470
2471 return m
2472 case InputMediaDocument:
2473 if m.Media.NeedsUpload() {
2474 m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
2475 }
2476
2477 if m.Thumb != nil && m.Thumb.NeedsUpload() {
2478 m.Thumb = fileAttach(fmt.Sprintf("attach://file-%d-thumb", idx))
2479 }
2480
2481 return m
2482 }
2483
2484 return nil
2485}
2486
2487// prepareInputMediaFile generates an array of RequestFile to provide for
2488// Fileable's files method. It returns an array as a single InputMedia may have
2489// multiple files, for the primary media and a thumbnail.
2490//
2491// The idx parameter is used to generate file field names. It uses the names
2492// "file-%d" for the main file and "file-%d-thumb" for the thumbnail.
2493//
2494// It is expected to be used in conjunction with prepareInputMediaParam.
2495func prepareInputMediaFile(inputMedia interface{}, idx int) []RequestFile {
2496 files := []RequestFile{}
2497
2498 switch m := inputMedia.(type) {
2499 case InputMediaPhoto:
2500 if m.Media.NeedsUpload() {
2501 files = append(files, RequestFile{
2502 Name: fmt.Sprintf("file-%d", idx),
2503 Data: m.Media,
2504 })
2505 }
2506 case InputMediaVideo:
2507 if m.Media.NeedsUpload() {
2508 files = append(files, RequestFile{
2509 Name: fmt.Sprintf("file-%d", idx),
2510 Data: m.Media,
2511 })
2512 }
2513
2514 if m.Thumb != nil && m.Thumb.NeedsUpload() {
2515 files = append(files, RequestFile{
2516 Name: fmt.Sprintf("file-%d", idx),
2517 Data: m.Thumb,
2518 })
2519 }
2520 case InputMediaDocument:
2521 if m.Media.NeedsUpload() {
2522 files = append(files, RequestFile{
2523 Name: fmt.Sprintf("file-%d", idx),
2524 Data: m.Media,
2525 })
2526 }
2527
2528 if m.Thumb != nil && m.Thumb.NeedsUpload() {
2529 files = append(files, RequestFile{
2530 Name: fmt.Sprintf("file-%d", idx),
2531 Data: m.Thumb,
2532 })
2533 }
2534 case InputMediaAudio:
2535 if m.Media.NeedsUpload() {
2536 files = append(files, RequestFile{
2537 Name: fmt.Sprintf("file-%d", idx),
2538 Data: m.Media,
2539 })
2540 }
2541
2542 if m.Thumb != nil && m.Thumb.NeedsUpload() {
2543 files = append(files, RequestFile{
2544 Name: fmt.Sprintf("file-%d", idx),
2545 Data: m.Thumb,
2546 })
2547 }
2548 }
2549
2550 return files
2551}
2552
2553// prepareInputMediaForParams calls prepareInputMediaParam for each item
2554// provided and returns a new array with the correct params for a request.
2555//
2556// It is expected that files will get data from the associated function,
2557// prepareInputMediaForFiles.
2558func prepareInputMediaForParams(inputMedia []interface{}) []interface{} {
2559 newMedia := make([]interface{}, len(inputMedia))
2560 copy(newMedia, inputMedia)
2561
2562 for idx, media := range inputMedia {
2563 if param := prepareInputMediaParam(media, idx); param != nil {
2564 newMedia[idx] = param
2565 }
2566 }
2567
2568 return newMedia
2569}
2570
2571// prepareInputMediaForFiles calls prepareInputMediaFile for each item
2572// provided and returns a new array with the correct files for a request.
2573//
2574// It is expected that params will get data from the associated function,
2575// prepareInputMediaForParams.
2576func prepareInputMediaForFiles(inputMedia []interface{}) []RequestFile {
2577 files := []RequestFile{}
2578
2579 for idx, media := range inputMedia {
2580 if file := prepareInputMediaFile(media, idx); file != nil {
2581 files = append(files, file...)
2582 }
2583 }
2584
2585 return files
2586}