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