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