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// BanChatMemberConfig contains extra fields to kick user.
1298type BanChatMemberConfig struct {
1299 ChatMemberConfig
1300 UntilDate int64
1301 RevokeMessages bool
1302}
1303
1304func (config BanChatMemberConfig) method() string {
1305 return "banChatMember"
1306}
1307
1308func (config BanChatMemberConfig) 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// KickChatMemberConfig contains extra fields to ban user.
1320//
1321// This was renamed to BanChatMember in later versions of the Telegram Bot API.
1322type KickChatMemberConfig = BanChatMemberConfig
1323
1324// RestrictChatMemberConfig contains fields to restrict members of chat
1325type RestrictChatMemberConfig struct {
1326 ChatMemberConfig
1327 UntilDate int64
1328 Permissions *ChatPermissions
1329}
1330
1331func (config RestrictChatMemberConfig) method() string {
1332 return "restrictChatMember"
1333}
1334
1335func (config RestrictChatMemberConfig) params() (Params, error) {
1336 params := make(Params)
1337
1338 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername)
1339 params.AddNonZero64("user_id", config.UserID)
1340
1341 err := params.AddInterface("permissions", config.Permissions)
1342 params.AddNonZero64("until_date", config.UntilDate)
1343
1344 return params, err
1345}
1346
1347// PromoteChatMemberConfig contains fields to promote members of chat
1348type PromoteChatMemberConfig struct {
1349 ChatMemberConfig
1350 IsAnonymous bool
1351 CanManageChat bool
1352 CanChangeInfo bool
1353 CanPostMessages bool
1354 CanEditMessages bool
1355 CanDeleteMessages bool
1356 CanManageVoiceChats bool
1357 CanInviteUsers bool
1358 CanRestrictMembers bool
1359 CanPinMessages bool
1360 CanPromoteMembers bool
1361}
1362
1363func (config PromoteChatMemberConfig) method() string {
1364 return "promoteChatMember"
1365}
1366
1367func (config PromoteChatMemberConfig) params() (Params, error) {
1368 params := make(Params)
1369
1370 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername)
1371 params.AddNonZero64("user_id", config.UserID)
1372
1373 params.AddBool("is_anonymous", config.IsAnonymous)
1374 params.AddBool("can_manage_chat", config.CanManageChat)
1375 params.AddBool("can_change_info", config.CanChangeInfo)
1376 params.AddBool("can_post_messages", config.CanPostMessages)
1377 params.AddBool("can_edit_messages", config.CanEditMessages)
1378 params.AddBool("can_delete_messages", config.CanDeleteMessages)
1379 params.AddBool("can_manage_voice_chats", config.CanManageVoiceChats)
1380 params.AddBool("can_invite_users", config.CanInviteUsers)
1381 params.AddBool("can_restrict_members", config.CanRestrictMembers)
1382 params.AddBool("can_pin_messages", config.CanPinMessages)
1383 params.AddBool("can_promote_members", config.CanPromoteMembers)
1384
1385 return params, nil
1386}
1387
1388// SetChatAdministratorCustomTitle sets the title of an administrative user
1389// promoted by the bot for a chat.
1390type SetChatAdministratorCustomTitle struct {
1391 ChatMemberConfig
1392 CustomTitle string
1393}
1394
1395func (SetChatAdministratorCustomTitle) method() string {
1396 return "setChatAdministratorCustomTitle"
1397}
1398
1399func (config SetChatAdministratorCustomTitle) params() (Params, error) {
1400 params := make(Params)
1401
1402 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername)
1403 params.AddNonZero64("user_id", config.UserID)
1404 params.AddNonEmpty("custom_title", config.CustomTitle)
1405
1406 return params, nil
1407}
1408
1409// ChatConfig contains information about getting information on a chat.
1410type ChatConfig struct {
1411 ChatID int64
1412 SuperGroupUsername string
1413}
1414
1415func (config ChatConfig) params() (Params, error) {
1416 params := make(Params)
1417
1418 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1419
1420 return params, nil
1421}
1422
1423// ChatInfoConfig contains information about getting chat information.
1424type ChatInfoConfig struct {
1425 ChatConfig
1426}
1427
1428func (ChatInfoConfig) method() string {
1429 return "getChat"
1430}
1431
1432// ChatMemberCountConfig contains information about getting the number of users in a chat.
1433type ChatMemberCountConfig struct {
1434 ChatConfig
1435}
1436
1437func (ChatMemberCountConfig) method() string {
1438 return "getChatMembersCount"
1439}
1440
1441// ChatAdministratorsConfig contains information about getting chat administrators.
1442type ChatAdministratorsConfig struct {
1443 ChatConfig
1444}
1445
1446func (ChatAdministratorsConfig) method() string {
1447 return "getChatAdministrators"
1448}
1449
1450// SetChatPermissionsConfig allows you to set default permissions for the
1451// members in a group. The bot must be an administrator and have rights to
1452// restrict members.
1453type SetChatPermissionsConfig struct {
1454 ChatConfig
1455 Permissions *ChatPermissions
1456}
1457
1458func (SetChatPermissionsConfig) method() string {
1459 return "setChatPermissions"
1460}
1461
1462func (config SetChatPermissionsConfig) params() (Params, error) {
1463 params := make(Params)
1464
1465 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1466 err := params.AddInterface("permissions", config.Permissions)
1467
1468 return params, err
1469}
1470
1471// ChatInviteLinkConfig contains information about getting a chat link.
1472//
1473// Note that generating a new link will revoke any previous links.
1474type ChatInviteLinkConfig struct {
1475 ChatConfig
1476}
1477
1478func (ChatInviteLinkConfig) method() string {
1479 return "exportChatInviteLink"
1480}
1481
1482func (config ChatInviteLinkConfig) params() (Params, error) {
1483 params := make(Params)
1484
1485 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1486
1487 return params, nil
1488}
1489
1490// CreateChatInviteLinkConfig allows you to create an additional invite link for
1491// a chat. The bot must be an administrator in the chat for this to work and
1492// must have the appropriate admin rights. The link can be revoked using the
1493// RevokeChatInviteLinkConfig.
1494type CreateChatInviteLinkConfig struct {
1495 ChatConfig
1496 Name string
1497 ExpireDate int
1498 MemberLimit int
1499 CreatesJoinRequest bool
1500}
1501
1502func (CreateChatInviteLinkConfig) method() string {
1503 return "createChatInviteLink"
1504}
1505
1506func (config CreateChatInviteLinkConfig) params() (Params, error) {
1507 params := make(Params)
1508
1509 params.AddNonEmpty("name", config.Name)
1510 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1511 params.AddNonZero("expire_date", config.ExpireDate)
1512 params.AddNonZero("member_limit", config.MemberLimit)
1513 params.AddBool("creates_join_request", config.CreatesJoinRequest)
1514
1515 return params, nil
1516}
1517
1518// EditChatInviteLinkConfig allows you to edit a non-primary invite link created
1519// by the bot. The bot must be an administrator in the chat for this to work and
1520// must have the appropriate admin rights.
1521type EditChatInviteLinkConfig struct {
1522 ChatConfig
1523 InviteLink string
1524 Name string
1525 ExpireDate int
1526 MemberLimit int
1527 CreatesJoinRequest bool
1528}
1529
1530func (EditChatInviteLinkConfig) method() string {
1531 return "editChatInviteLink"
1532}
1533
1534func (config EditChatInviteLinkConfig) params() (Params, error) {
1535 params := make(Params)
1536
1537 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1538 params.AddNonEmpty("name", config.Name)
1539 params["invite_link"] = config.InviteLink
1540 params.AddNonZero("expire_date", config.ExpireDate)
1541 params.AddNonZero("member_limit", config.MemberLimit)
1542 params.AddBool("creates_join_request", config.CreatesJoinRequest)
1543
1544 return params, nil
1545}
1546
1547// RevokeChatInviteLinkConfig allows you to revoke an invite link created by the
1548// bot. If the primary link is revoked, a new link is automatically generated.
1549// The bot must be an administrator in the chat for this to work and must have
1550// the appropriate admin rights.
1551type RevokeChatInviteLinkConfig struct {
1552 ChatConfig
1553 InviteLink string
1554}
1555
1556func (RevokeChatInviteLinkConfig) method() string {
1557 return "revokeChatInviteLink"
1558}
1559
1560func (config RevokeChatInviteLinkConfig) params() (Params, error) {
1561 params := make(Params)
1562
1563 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1564 params["invite_link"] = config.InviteLink
1565
1566 return params, nil
1567}
1568
1569// ApproveChatJoinRequestConfig allows you to approve a chat join request.
1570type ApproveChatJoinRequestConfig struct {
1571 ChatConfig
1572 UserID int64
1573}
1574
1575func (ApproveChatJoinRequestConfig) method() string {
1576 return "approveChatJoinRequest"
1577}
1578
1579func (config ApproveChatJoinRequestConfig) params() (Params, error) {
1580 params := make(Params)
1581
1582 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1583 params.AddNonZero("user_id", int(config.UserID))
1584
1585 return params, nil
1586}
1587
1588// DeclineChatJoinRequest allows you to decline a chat join request.
1589type DeclineChatJoinRequest struct {
1590 ChatConfig
1591 UserID int64
1592}
1593
1594func (DeclineChatJoinRequest) method() string {
1595 return "declineChatJoinRequest"
1596}
1597
1598func (config DeclineChatJoinRequest) params() (Params, error) {
1599 params := make(Params)
1600
1601 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1602 params.AddNonZero("user_id", int(config.UserID))
1603
1604 return params, nil
1605}
1606
1607// LeaveChatConfig allows you to leave a chat.
1608type LeaveChatConfig struct {
1609 ChatID int64
1610 ChannelUsername string
1611}
1612
1613func (config LeaveChatConfig) method() string {
1614 return "leaveChat"
1615}
1616
1617func (config LeaveChatConfig) params() (Params, error) {
1618 params := make(Params)
1619
1620 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1621
1622 return params, nil
1623}
1624
1625// ChatConfigWithUser contains information about a chat and a user.
1626type ChatConfigWithUser struct {
1627 ChatID int64
1628 SuperGroupUsername string
1629 UserID int64
1630}
1631
1632func (config ChatConfigWithUser) params() (Params, error) {
1633 params := make(Params)
1634
1635 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1636 params.AddNonZero64("user_id", config.UserID)
1637
1638 return params, nil
1639}
1640
1641// GetChatMemberConfig is information about getting a specific member in a chat.
1642type GetChatMemberConfig struct {
1643 ChatConfigWithUser
1644}
1645
1646func (GetChatMemberConfig) method() string {
1647 return "getChatMember"
1648}
1649
1650// InvoiceConfig contains information for sendInvoice request.
1651type InvoiceConfig struct {
1652 BaseChat
1653 Title string // required
1654 Description string // required
1655 Payload string // required
1656 ProviderToken string // required
1657 Currency string // required
1658 Prices []LabeledPrice // required
1659 MaxTipAmount int
1660 SuggestedTipAmounts []int
1661 StartParameter string
1662 ProviderData string
1663 PhotoURL string
1664 PhotoSize int
1665 PhotoWidth int
1666 PhotoHeight int
1667 NeedName bool
1668 NeedPhoneNumber bool
1669 NeedEmail bool
1670 NeedShippingAddress bool
1671 SendPhoneNumberToProvider bool
1672 SendEmailToProvider bool
1673 IsFlexible bool
1674}
1675
1676func (config InvoiceConfig) params() (Params, error) {
1677 params, err := config.BaseChat.params()
1678 if err != nil {
1679 return params, err
1680 }
1681
1682 params["title"] = config.Title
1683 params["description"] = config.Description
1684 params["payload"] = config.Payload
1685 params["provider_token"] = config.ProviderToken
1686 params["currency"] = config.Currency
1687 if err = params.AddInterface("prices", config.Prices); err != nil {
1688 return params, err
1689 }
1690
1691 params.AddNonZero("max_tip_amount", config.MaxTipAmount)
1692 err = params.AddInterface("suggested_tip_amounts", config.SuggestedTipAmounts)
1693 params.AddNonEmpty("start_parameter", config.StartParameter)
1694 params.AddNonEmpty("provider_data", config.ProviderData)
1695 params.AddNonEmpty("photo_url", config.PhotoURL)
1696 params.AddNonZero("photo_size", config.PhotoSize)
1697 params.AddNonZero("photo_width", config.PhotoWidth)
1698 params.AddNonZero("photo_height", config.PhotoHeight)
1699 params.AddBool("need_name", config.NeedName)
1700 params.AddBool("need_phone_number", config.NeedPhoneNumber)
1701 params.AddBool("need_email", config.NeedEmail)
1702 params.AddBool("need_shipping_address", config.NeedShippingAddress)
1703 params.AddBool("is_flexible", config.IsFlexible)
1704 params.AddBool("send_phone_number_to_provider", config.SendPhoneNumberToProvider)
1705 params.AddBool("send_email_to_provider", config.SendEmailToProvider)
1706
1707 return params, err
1708}
1709
1710func (config InvoiceConfig) method() string {
1711 return "sendInvoice"
1712}
1713
1714// ShippingConfig contains information for answerShippingQuery request.
1715type ShippingConfig struct {
1716 ShippingQueryID string // required
1717 OK bool // required
1718 ShippingOptions []ShippingOption
1719 ErrorMessage string
1720}
1721
1722func (config ShippingConfig) method() string {
1723 return "answerShippingQuery"
1724}
1725
1726func (config ShippingConfig) params() (Params, error) {
1727 params := make(Params)
1728
1729 params["shipping_query_id"] = config.ShippingQueryID
1730 params.AddBool("ok", config.OK)
1731 err := params.AddInterface("shipping_options", config.ShippingOptions)
1732 params.AddNonEmpty("error_message", config.ErrorMessage)
1733
1734 return params, err
1735}
1736
1737// PreCheckoutConfig conatins information for answerPreCheckoutQuery request.
1738type PreCheckoutConfig struct {
1739 PreCheckoutQueryID string // required
1740 OK bool // required
1741 ErrorMessage string
1742}
1743
1744func (config PreCheckoutConfig) method() string {
1745 return "answerPreCheckoutQuery"
1746}
1747
1748func (config PreCheckoutConfig) params() (Params, error) {
1749 params := make(Params)
1750
1751 params["pre_checkout_query_id"] = config.PreCheckoutQueryID
1752 params.AddBool("ok", config.OK)
1753 params.AddNonEmpty("error_message", config.ErrorMessage)
1754
1755 return params, nil
1756}
1757
1758// DeleteMessageConfig contains information of a message in a chat to delete.
1759type DeleteMessageConfig struct {
1760 ChannelUsername string
1761 ChatID int64
1762 MessageID int
1763}
1764
1765func (config DeleteMessageConfig) method() string {
1766 return "deleteMessage"
1767}
1768
1769func (config DeleteMessageConfig) params() (Params, error) {
1770 params := make(Params)
1771
1772 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1773 params.AddNonZero("message_id", config.MessageID)
1774
1775 return params, nil
1776}
1777
1778// PinChatMessageConfig contains information of a message in a chat to pin.
1779type PinChatMessageConfig struct {
1780 ChatID int64
1781 ChannelUsername string
1782 MessageID int
1783 DisableNotification bool
1784}
1785
1786func (config PinChatMessageConfig) method() string {
1787 return "pinChatMessage"
1788}
1789
1790func (config PinChatMessageConfig) params() (Params, error) {
1791 params := make(Params)
1792
1793 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1794 params.AddNonZero("message_id", config.MessageID)
1795 params.AddBool("disable_notification", config.DisableNotification)
1796
1797 return params, nil
1798}
1799
1800// UnpinChatMessageConfig contains information of a chat message to unpin.
1801//
1802// If MessageID is not specified, it will unpin the most recent pin.
1803type UnpinChatMessageConfig struct {
1804 ChatID int64
1805 ChannelUsername string
1806 MessageID int
1807}
1808
1809func (config UnpinChatMessageConfig) method() string {
1810 return "unpinChatMessage"
1811}
1812
1813func (config UnpinChatMessageConfig) params() (Params, error) {
1814 params := make(Params)
1815
1816 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1817 params.AddNonZero("message_id", config.MessageID)
1818
1819 return params, nil
1820}
1821
1822// UnpinAllChatMessagesConfig contains information of all messages to unpin in
1823// a chat.
1824type UnpinAllChatMessagesConfig struct {
1825 ChatID int64
1826 ChannelUsername string
1827}
1828
1829func (config UnpinAllChatMessagesConfig) method() string {
1830 return "unpinAllChatMessages"
1831}
1832
1833func (config UnpinAllChatMessagesConfig) params() (Params, error) {
1834 params := make(Params)
1835
1836 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1837
1838 return params, nil
1839}
1840
1841// SetChatPhotoConfig allows you to set a group, supergroup, or channel's photo.
1842type SetChatPhotoConfig struct {
1843 BaseFile
1844}
1845
1846func (config SetChatPhotoConfig) method() string {
1847 return "setChatPhoto"
1848}
1849
1850func (config SetChatPhotoConfig) files() []RequestFile {
1851 return []RequestFile{{
1852 Name: "photo",
1853 Data: config.File,
1854 }}
1855}
1856
1857// DeleteChatPhotoConfig allows you to delete a group, supergroup, or channel's photo.
1858type DeleteChatPhotoConfig struct {
1859 ChatID int64
1860 ChannelUsername string
1861}
1862
1863func (config DeleteChatPhotoConfig) method() string {
1864 return "deleteChatPhoto"
1865}
1866
1867func (config DeleteChatPhotoConfig) params() (Params, error) {
1868 params := make(Params)
1869
1870 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1871
1872 return params, nil
1873}
1874
1875// SetChatTitleConfig allows you to set the title of something other than a private chat.
1876type SetChatTitleConfig struct {
1877 ChatID int64
1878 ChannelUsername string
1879
1880 Title string
1881}
1882
1883func (config SetChatTitleConfig) method() string {
1884 return "setChatTitle"
1885}
1886
1887func (config SetChatTitleConfig) params() (Params, error) {
1888 params := make(Params)
1889
1890 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1891 params["title"] = config.Title
1892
1893 return params, nil
1894}
1895
1896// SetChatDescriptionConfig allows you to set the description of a supergroup or channel.
1897type SetChatDescriptionConfig struct {
1898 ChatID int64
1899 ChannelUsername string
1900
1901 Description string
1902}
1903
1904func (config SetChatDescriptionConfig) method() string {
1905 return "setChatDescription"
1906}
1907
1908func (config SetChatDescriptionConfig) params() (Params, error) {
1909 params := make(Params)
1910
1911 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1912 params["description"] = config.Description
1913
1914 return params, nil
1915}
1916
1917// GetStickerSetConfig allows you to get the stickers in a set.
1918type GetStickerSetConfig struct {
1919 Name string
1920}
1921
1922func (config GetStickerSetConfig) method() string {
1923 return "getStickerSet"
1924}
1925
1926func (config GetStickerSetConfig) params() (Params, error) {
1927 params := make(Params)
1928
1929 params["name"] = config.Name
1930
1931 return params, nil
1932}
1933
1934// UploadStickerConfig allows you to upload a sticker for use in a set later.
1935type UploadStickerConfig struct {
1936 UserID int64
1937 PNGSticker RequestFileData
1938}
1939
1940func (config UploadStickerConfig) method() string {
1941 return "uploadStickerFile"
1942}
1943
1944func (config UploadStickerConfig) params() (Params, error) {
1945 params := make(Params)
1946
1947 params.AddNonZero64("user_id", config.UserID)
1948
1949 return params, nil
1950}
1951
1952func (config UploadStickerConfig) files() []RequestFile {
1953 return []RequestFile{{
1954 Name: "png_sticker",
1955 Data: config.PNGSticker,
1956 }}
1957}
1958
1959// NewStickerSetConfig allows creating a new sticker set.
1960//
1961// You must set either PNGSticker or TGSSticker.
1962type NewStickerSetConfig struct {
1963 UserID int64
1964 Name string
1965 Title string
1966 PNGSticker RequestFileData
1967 TGSSticker RequestFileData
1968 Emojis string
1969 ContainsMasks bool
1970 MaskPosition *MaskPosition
1971}
1972
1973func (config NewStickerSetConfig) method() string {
1974 return "createNewStickerSet"
1975}
1976
1977func (config NewStickerSetConfig) params() (Params, error) {
1978 params := make(Params)
1979
1980 params.AddNonZero64("user_id", config.UserID)
1981 params["name"] = config.Name
1982 params["title"] = config.Title
1983
1984 params["emojis"] = config.Emojis
1985
1986 params.AddBool("contains_masks", config.ContainsMasks)
1987
1988 err := params.AddInterface("mask_position", config.MaskPosition)
1989
1990 return params, err
1991}
1992
1993func (config NewStickerSetConfig) files() []RequestFile {
1994 if config.PNGSticker != nil {
1995 return []RequestFile{{
1996 Name: "png_sticker",
1997 Data: config.PNGSticker,
1998 }}
1999 }
2000
2001 return []RequestFile{{
2002 Name: "tgs_sticker",
2003 Data: config.TGSSticker,
2004 }}
2005}
2006
2007// AddStickerConfig allows you to add a sticker to a set.
2008type AddStickerConfig struct {
2009 UserID int64
2010 Name string
2011 PNGSticker RequestFileData
2012 TGSSticker RequestFileData
2013 Emojis string
2014 MaskPosition *MaskPosition
2015}
2016
2017func (config AddStickerConfig) method() string {
2018 return "addStickerToSet"
2019}
2020
2021func (config AddStickerConfig) params() (Params, error) {
2022 params := make(Params)
2023
2024 params.AddNonZero64("user_id", config.UserID)
2025 params["name"] = config.Name
2026 params["emojis"] = config.Emojis
2027
2028 err := params.AddInterface("mask_position", config.MaskPosition)
2029
2030 return params, err
2031}
2032
2033func (config AddStickerConfig) files() []RequestFile {
2034 if config.PNGSticker != nil {
2035 return []RequestFile{{
2036 Name: "png_sticker",
2037 Data: config.PNGSticker,
2038 }}
2039 }
2040
2041 return []RequestFile{{
2042 Name: "tgs_sticker",
2043 Data: config.TGSSticker,
2044 }}
2045
2046}
2047
2048// SetStickerPositionConfig allows you to change the position of a sticker in a set.
2049type SetStickerPositionConfig struct {
2050 Sticker string
2051 Position int
2052}
2053
2054func (config SetStickerPositionConfig) method() string {
2055 return "setStickerPositionInSet"
2056}
2057
2058func (config SetStickerPositionConfig) params() (Params, error) {
2059 params := make(Params)
2060
2061 params["sticker"] = config.Sticker
2062 params.AddNonZero("position", config.Position)
2063
2064 return params, nil
2065}
2066
2067// DeleteStickerConfig allows you to delete a sticker from a set.
2068type DeleteStickerConfig struct {
2069 Sticker string
2070}
2071
2072func (config DeleteStickerConfig) method() string {
2073 return "deleteStickerFromSet"
2074}
2075
2076func (config DeleteStickerConfig) params() (Params, error) {
2077 params := make(Params)
2078
2079 params["sticker"] = config.Sticker
2080
2081 return params, nil
2082}
2083
2084// SetStickerSetThumbConfig allows you to set the thumbnail for a sticker set.
2085type SetStickerSetThumbConfig struct {
2086 Name string
2087 UserID int64
2088 Thumb RequestFileData
2089}
2090
2091func (config SetStickerSetThumbConfig) method() string {
2092 return "setStickerSetThumb"
2093}
2094
2095func (config SetStickerSetThumbConfig) params() (Params, error) {
2096 params := make(Params)
2097
2098 params["name"] = config.Name
2099 params.AddNonZero64("user_id", config.UserID)
2100
2101 return params, nil
2102}
2103
2104func (config SetStickerSetThumbConfig) files() []RequestFile {
2105 return []RequestFile{{
2106 Name: "thumb",
2107 Data: config.Thumb,
2108 }}
2109}
2110
2111// SetChatStickerSetConfig allows you to set the sticker set for a supergroup.
2112type SetChatStickerSetConfig struct {
2113 ChatID int64
2114 SuperGroupUsername string
2115
2116 StickerSetName string
2117}
2118
2119func (config SetChatStickerSetConfig) method() string {
2120 return "setChatStickerSet"
2121}
2122
2123func (config SetChatStickerSetConfig) params() (Params, error) {
2124 params := make(Params)
2125
2126 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
2127 params["sticker_set_name"] = config.StickerSetName
2128
2129 return params, nil
2130}
2131
2132// DeleteChatStickerSetConfig allows you to remove a supergroup's sticker set.
2133type DeleteChatStickerSetConfig struct {
2134 ChatID int64
2135 SuperGroupUsername string
2136}
2137
2138func (config DeleteChatStickerSetConfig) method() string {
2139 return "deleteChatStickerSet"
2140}
2141
2142func (config DeleteChatStickerSetConfig) params() (Params, error) {
2143 params := make(Params)
2144
2145 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
2146
2147 return params, nil
2148}
2149
2150// MediaGroupConfig allows you to send a group of media.
2151//
2152// Media consist of InputMedia items (InputMediaPhoto, InputMediaVideo).
2153type MediaGroupConfig struct {
2154 ChatID int64
2155 ChannelUsername string
2156
2157 Media []interface{}
2158 DisableNotification bool
2159 ReplyToMessageID int
2160}
2161
2162func (config MediaGroupConfig) method() string {
2163 return "sendMediaGroup"
2164}
2165
2166func (config MediaGroupConfig) params() (Params, error) {
2167 params := make(Params)
2168
2169 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
2170 params.AddBool("disable_notification", config.DisableNotification)
2171 params.AddNonZero("reply_to_message_id", config.ReplyToMessageID)
2172
2173 err := params.AddInterface("media", prepareInputMediaForParams(config.Media))
2174
2175 return params, err
2176}
2177
2178func (config MediaGroupConfig) files() []RequestFile {
2179 return prepareInputMediaForFiles(config.Media)
2180}
2181
2182// DiceConfig contains information about a sendDice request.
2183type DiceConfig struct {
2184 BaseChat
2185 // Emoji on which the dice throw animation is based.
2186 // Currently, must be one of 🎲, 🎯, 🏀, ⚽, 🎳, or 🎰.
2187 // Dice can have values 1-6 for 🎲, 🎯, and 🎳, values 1-5 for 🏀 and ⚽,
2188 // and values 1-64 for 🎰.
2189 // Defaults to “🎲”
2190 Emoji string
2191}
2192
2193func (config DiceConfig) method() string {
2194 return "sendDice"
2195}
2196
2197func (config DiceConfig) params() (Params, error) {
2198 params, err := config.BaseChat.params()
2199 if err != nil {
2200 return params, err
2201 }
2202
2203 params.AddNonEmpty("emoji", config.Emoji)
2204
2205 return params, err
2206}
2207
2208// GetMyCommandsConfig gets a list of the currently registered commands.
2209type GetMyCommandsConfig struct {
2210 Scope *BotCommandScope
2211 LanguageCode string
2212}
2213
2214func (config GetMyCommandsConfig) method() string {
2215 return "getMyCommands"
2216}
2217
2218func (config GetMyCommandsConfig) params() (Params, error) {
2219 params := make(Params)
2220
2221 err := params.AddInterface("scope", config.Scope)
2222 params.AddNonEmpty("language_code", config.LanguageCode)
2223
2224 return params, err
2225}
2226
2227// SetMyCommandsConfig sets a list of commands the bot understands.
2228type SetMyCommandsConfig struct {
2229 Commands []BotCommand
2230 Scope *BotCommandScope
2231 LanguageCode string
2232}
2233
2234func (config SetMyCommandsConfig) method() string {
2235 return "setMyCommands"
2236}
2237
2238func (config SetMyCommandsConfig) params() (Params, error) {
2239 params := make(Params)
2240
2241 if err := params.AddInterface("commands", config.Commands); err != nil {
2242 return params, err
2243 }
2244 err := params.AddInterface("scope", config.Scope)
2245 params.AddNonEmpty("language_code", config.LanguageCode)
2246
2247 return params, err
2248}
2249
2250type DeleteMyCommandsConfig struct {
2251 Scope *BotCommandScope
2252 LanguageCode string
2253}
2254
2255func (config DeleteMyCommandsConfig) method() string {
2256 return "deleteMyCommands"
2257}
2258
2259func (config DeleteMyCommandsConfig) params() (Params, error) {
2260 params := make(Params)
2261
2262 err := params.AddInterface("scope", config.Scope)
2263 params.AddNonEmpty("language_code", config.LanguageCode)
2264
2265 return params, err
2266}
2267
2268// prepareInputMediaParam evaluates a single InputMedia and determines if it
2269// needs to be modified for a successful upload. If it returns nil, then the
2270// value does not need to be included in the params. Otherwise, it will return
2271// the same type as was originally provided.
2272//
2273// The idx is used to calculate the file field name. If you only have a single
2274// file, 0 may be used. It is formatted into "attach://file-%d" for the primary
2275// media and "attach://file-%d-thumb" for thumbnails.
2276//
2277// It is expected to be used in conjunction with prepareInputMediaFile.
2278func prepareInputMediaParam(inputMedia interface{}, idx int) interface{} {
2279 switch m := inputMedia.(type) {
2280 case InputMediaPhoto:
2281 if m.Media.NeedsUpload() {
2282 m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
2283 }
2284
2285 return m
2286 case InputMediaVideo:
2287 if m.Media.NeedsUpload() {
2288 m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
2289 }
2290
2291 if m.Thumb != nil && m.Thumb.NeedsUpload() {
2292 m.Thumb = fileAttach(fmt.Sprintf("attach://file-%d-thumb", idx))
2293 }
2294
2295 return m
2296 case InputMediaAudio:
2297 if m.Media.NeedsUpload() {
2298 m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
2299 }
2300
2301 if m.Thumb != nil && m.Thumb.NeedsUpload() {
2302 m.Thumb = fileAttach(fmt.Sprintf("attach://file-%d-thumb", idx))
2303 }
2304
2305 return m
2306 case InputMediaDocument:
2307 if m.Media.NeedsUpload() {
2308 m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
2309 }
2310
2311 if m.Thumb != nil && m.Thumb.NeedsUpload() {
2312 m.Thumb = fileAttach(fmt.Sprintf("attach://file-%d-thumb", idx))
2313 }
2314
2315 return m
2316 }
2317
2318 return nil
2319}
2320
2321// prepareInputMediaFile generates an array of RequestFile to provide for
2322// Fileable's files method. It returns an array as a single InputMedia may have
2323// multiple files, for the primary media and a thumbnail.
2324//
2325// The idx parameter is used to generate file field names. It uses the names
2326// "file-%d" for the main file and "file-%d-thumb" for the thumbnail.
2327//
2328// It is expected to be used in conjunction with prepareInputMediaParam.
2329func prepareInputMediaFile(inputMedia interface{}, idx int) []RequestFile {
2330 files := []RequestFile{}
2331
2332 switch m := inputMedia.(type) {
2333 case InputMediaPhoto:
2334 if m.Media.NeedsUpload() {
2335 files = append(files, RequestFile{
2336 Name: fmt.Sprintf("file-%d", idx),
2337 Data: m.Media,
2338 })
2339 }
2340 case InputMediaVideo:
2341 if m.Media.NeedsUpload() {
2342 files = append(files, RequestFile{
2343 Name: fmt.Sprintf("file-%d", idx),
2344 Data: m.Media,
2345 })
2346 }
2347
2348 if m.Thumb != nil && m.Thumb.NeedsUpload() {
2349 files = append(files, RequestFile{
2350 Name: fmt.Sprintf("file-%d", idx),
2351 Data: m.Thumb,
2352 })
2353 }
2354 case InputMediaDocument:
2355 if m.Media.NeedsUpload() {
2356 files = append(files, RequestFile{
2357 Name: fmt.Sprintf("file-%d", idx),
2358 Data: m.Media,
2359 })
2360 }
2361
2362 if m.Thumb != nil && m.Thumb.NeedsUpload() {
2363 files = append(files, RequestFile{
2364 Name: fmt.Sprintf("file-%d", idx),
2365 Data: m.Thumb,
2366 })
2367 }
2368 case InputMediaAudio:
2369 if m.Media.NeedsUpload() {
2370 files = append(files, RequestFile{
2371 Name: fmt.Sprintf("file-%d", idx),
2372 Data: m.Media,
2373 })
2374 }
2375
2376 if m.Thumb != nil && m.Thumb.NeedsUpload() {
2377 files = append(files, RequestFile{
2378 Name: fmt.Sprintf("file-%d", idx),
2379 Data: m.Thumb,
2380 })
2381 }
2382 }
2383
2384 return files
2385}
2386
2387// prepareInputMediaForParams calls prepareInputMediaParam for each item
2388// provided and returns a new array with the correct params for a request.
2389//
2390// It is expected that files will get data from the associated function,
2391// prepareInputMediaForFiles.
2392func prepareInputMediaForParams(inputMedia []interface{}) []interface{} {
2393 newMedia := make([]interface{}, len(inputMedia))
2394 copy(newMedia, inputMedia)
2395
2396 for idx, media := range inputMedia {
2397 if param := prepareInputMediaParam(media, idx); param != nil {
2398 newMedia[idx] = param
2399 }
2400 }
2401
2402 return newMedia
2403}
2404
2405// prepareInputMediaForFiles calls prepareInputMediaFile for each item
2406// provided and returns a new array with the correct files for a request.
2407//
2408// It is expected that params will get data from the associated function,
2409// prepareInputMediaForParams.
2410func prepareInputMediaForFiles(inputMedia []interface{}) []RequestFile {
2411 files := []RequestFile{}
2412
2413 for idx, media := range inputMedia {
2414 if file := prepareInputMediaFile(media, idx); file != nil {
2415 files = append(files, file...)
2416 }
2417 }
2418
2419 return files
2420}