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