configs.go (63985B)
1 package tgbotapi 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "net/url" 8 "os" 9 "strconv" 10 ) 11 12 // Telegram constants 13 const ( 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 22 const ( 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 37 const ( 38 // ErrAPIForbidden happens when a token is bad 39 ErrAPIForbidden = "forbidden" 40 ) 41 42 // Constant values for ParseMode in MessageConfig 43 const ( 44 ModeMarkdown = "Markdown" 45 ModeMarkdownV2 = "MarkdownV2" 46 ModeHTML = "HTML" 47 ) 48 49 // Constant values for update types 50 const ( 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 98 const ( 99 ErrBadURL = "bad or empty url" 100 ) 101 102 // Chattable is any config type that can be sent. 103 type 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. 109 type Fileable interface { 110 Chattable 111 files() []RequestFile 112 } 113 114 // RequestFile represents a file associated with a field name. 115 type 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. 123 type 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. 137 type FileBytes struct { 138 Name string 139 Bytes []byte 140 } 141 142 func (fb FileBytes) NeedsUpload() bool { 143 return true 144 } 145 146 func (fb FileBytes) UploadData() (string, io.Reader, error) { 147 return fb.Name, bytes.NewReader(fb.Bytes), nil 148 } 149 150 func (fb FileBytes) SendData() string { 151 panic("FileBytes must be uploaded") 152 } 153 154 // FileReader contains information about a reader to upload as a File. 155 type FileReader struct { 156 Name string 157 Reader io.Reader 158 } 159 160 func (fr FileReader) NeedsUpload() bool { 161 return true 162 } 163 164 func (fr FileReader) UploadData() (string, io.Reader, error) { 165 return fr.Name, fr.Reader, nil 166 } 167 168 func (fr FileReader) SendData() string { 169 panic("FileReader must be uploaded") 170 } 171 172 // FilePath is a path to a local file. 173 type FilePath string 174 175 func (fp FilePath) NeedsUpload() bool { 176 return true 177 } 178 179 func (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 189 func (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. 194 type FileURL string 195 196 func (fu FileURL) NeedsUpload() bool { 197 return false 198 } 199 200 func (fu FileURL) UploadData() (string, io.Reader, error) { 201 panic("FileURL cannot be uploaded") 202 } 203 204 func (fu FileURL) SendData() string { 205 return string(fu) 206 } 207 208 // FileID is an ID of a file already uploaded to Telegram. 209 type FileID string 210 211 func (fi FileID) NeedsUpload() bool { 212 return false 213 } 214 215 func (fi FileID) UploadData() (string, io.Reader, error) { 216 panic("FileID cannot be uploaded") 217 } 218 219 func (fi FileID) SendData() string { 220 return string(fi) 221 } 222 223 // fileAttach is an internal file type used for processed media groups. 224 type fileAttach string 225 226 func (fa fileAttach) NeedsUpload() bool { 227 return false 228 } 229 230 func (fa fileAttach) UploadData() (string, io.Reader, error) { 231 panic("fileAttach cannot be uploaded") 232 } 233 234 func (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. 241 type LogOutConfig struct{} 242 243 func (LogOutConfig) method() string { 244 return "logOut" 245 } 246 247 func (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. 255 type CloseConfig struct{} 256 257 func (CloseConfig) method() string { 258 return "close" 259 } 260 261 func (CloseConfig) params() (Params, error) { 262 return nil, nil 263 } 264 265 // BaseChat is base type for all chat config types. 266 type BaseChat struct { 267 ChatID int64 // required 268 ChannelUsername string 269 ReplyToMessageID int 270 ReplyMarkup interface{} 271 DisableNotification bool 272 AllowSendingWithoutReply bool 273 } 274 275 func (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. 289 type BaseFile struct { 290 BaseChat 291 File RequestFileData 292 } 293 294 func (file BaseFile) params() (Params, error) { 295 return file.BaseChat.params() 296 } 297 298 // BaseEdit is base type of all chat edits. 299 type BaseEdit struct { 300 ChatID int64 301 ChannelUsername string 302 MessageID int 303 InlineMessageID string 304 ReplyMarkup *InlineKeyboardMarkup 305 } 306 307 func (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. 323 type MessageConfig struct { 324 BaseChat 325 Text string 326 ParseMode string 327 Entities []MessageEntity 328 DisableWebPagePreview bool 329 } 330 331 func (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 345 func (config MessageConfig) method() string { 346 return "sendMessage" 347 } 348 349 // ForwardConfig contains information about a ForwardMessage request. 350 type ForwardConfig struct { 351 BaseChat 352 FromChatID int64 // required 353 FromChannelUsername string 354 MessageID int // required 355 } 356 357 func (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 369 func (config ForwardConfig) method() string { 370 return "forwardMessage" 371 } 372 373 // CopyMessageConfig contains information about a copyMessage request. 374 type CopyMessageConfig struct { 375 BaseChat 376 FromChatID int64 377 FromChannelUsername string 378 MessageID int 379 Caption string 380 ParseMode string 381 CaptionEntities []MessageEntity 382 } 383 384 func (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 399 func (config CopyMessageConfig) method() string { 400 return "copyMessage" 401 } 402 403 // PhotoConfig contains information about a SendPhoto request. 404 type PhotoConfig struct { 405 BaseFile 406 Thumb RequestFileData 407 Caption string 408 ParseMode string 409 CaptionEntities []MessageEntity 410 } 411 412 func (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 425 func (config PhotoConfig) method() string { 426 return "sendPhoto" 427 } 428 429 func (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. 446 type 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 457 func (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 473 func (config AudioConfig) method() string { 474 return "sendAudio" 475 } 476 477 func (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. 494 type DocumentConfig struct { 495 BaseFile 496 Thumb RequestFileData 497 Caption string 498 ParseMode string 499 CaptionEntities []MessageEntity 500 DisableContentTypeDetection bool 501 } 502 503 func (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 513 func (config DocumentConfig) method() string { 514 return "sendDocument" 515 } 516 517 func (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. 534 type StickerConfig struct { 535 BaseFile 536 } 537 538 func (config StickerConfig) params() (Params, error) { 539 return config.BaseChat.params() 540 } 541 542 func (config StickerConfig) method() string { 543 return "sendSticker" 544 } 545 546 func (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. 554 type VideoConfig struct { 555 BaseFile 556 Thumb RequestFileData 557 Duration int 558 Caption string 559 ParseMode string 560 CaptionEntities []MessageEntity 561 SupportsStreaming bool 562 } 563 564 func (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 579 func (config VideoConfig) method() string { 580 return "sendVideo" 581 } 582 583 func (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. 600 type AnimationConfig struct { 601 BaseFile 602 Duration int 603 Thumb RequestFileData 604 Caption string 605 ParseMode string 606 CaptionEntities []MessageEntity 607 } 608 609 func (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 623 func (config AnimationConfig) method() string { 624 return "sendAnimation" 625 } 626 627 func (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. 644 type VideoNoteConfig struct { 645 BaseFile 646 Thumb RequestFileData 647 Duration int 648 Length int 649 } 650 651 func (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 660 func (config VideoNoteConfig) method() string { 661 return "sendVideoNote" 662 } 663 664 func (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. 681 type VoiceConfig struct { 682 BaseFile 683 Thumb RequestFileData 684 Caption string 685 ParseMode string 686 CaptionEntities []MessageEntity 687 Duration int 688 } 689 690 func (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 704 func (config VoiceConfig) method() string { 705 return "sendVoice" 706 } 707 708 func (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. 725 type 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 735 func (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 748 func (config LocationConfig) method() string { 749 return "sendLocation" 750 } 751 752 // EditMessageLiveLocationConfig allows you to update a live location. 753 type 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 762 func (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 774 func (config EditMessageLiveLocationConfig) method() string { 775 return "editMessageLiveLocation" 776 } 777 778 // StopMessageLiveLocationConfig stops updating a live location. 779 type StopMessageLiveLocationConfig struct { 780 BaseEdit 781 } 782 783 func (config StopMessageLiveLocationConfig) params() (Params, error) { 784 return config.BaseEdit.params() 785 } 786 787 func (config StopMessageLiveLocationConfig) method() string { 788 return "stopMessageLiveLocation" 789 } 790 791 // VenueConfig contains information about a SendVenue request. 792 type 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 804 func (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 819 func (config VenueConfig) method() string { 820 return "sendVenue" 821 } 822 823 // ContactConfig allows you to send a contact. 824 type ContactConfig struct { 825 BaseChat 826 PhoneNumber string 827 FirstName string 828 LastName string 829 VCard string 830 } 831 832 func (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 844 func (config ContactConfig) method() string { 845 return "sendContact" 846 } 847 848 // SendPollConfig allows you to send a poll. 849 type 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 865 func (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 889 func (SendPollConfig) method() string { 890 return "sendPoll" 891 } 892 893 // GameConfig allows you to send a game. 894 type GameConfig struct { 895 BaseChat 896 GameShortName string 897 } 898 899 func (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 907 func (config GameConfig) method() string { 908 return "sendGame" 909 } 910 911 // SetGameScoreConfig allows you to update the game score in a chat. 912 type 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 923 func (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 940 func (config SetGameScoreConfig) method() string { 941 return "setGameScore" 942 } 943 944 // GetGameHighScoresConfig allows you to fetch the high scores for a game. 945 type GetGameHighScoresConfig struct { 946 UserID int64 947 ChatID int64 948 ChannelUsername string 949 MessageID int 950 InlineMessageID string 951 } 952 953 func (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 968 func (config GetGameHighScoresConfig) method() string { 969 return "getGameHighScores" 970 } 971 972 // ChatActionConfig contains information about a SendChatAction request. 973 type ChatActionConfig struct { 974 BaseChat 975 Action string // required 976 } 977 978 func (config ChatActionConfig) params() (Params, error) { 979 params, err := config.BaseChat.params() 980 981 params["action"] = config.Action 982 983 return params, err 984 } 985 986 func (config ChatActionConfig) method() string { 987 return "sendChatAction" 988 } 989 990 // EditMessageTextConfig allows you to modify the text in a message. 991 type EditMessageTextConfig struct { 992 BaseEdit 993 Text string 994 ParseMode string 995 Entities []MessageEntity 996 DisableWebPagePreview bool 997 } 998 999 func (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 1013 func (config EditMessageTextConfig) method() string { 1014 return "editMessageText" 1015 } 1016 1017 // EditMessageCaptionConfig allows you to modify the caption of a message. 1018 type EditMessageCaptionConfig struct { 1019 BaseEdit 1020 Caption string 1021 ParseMode string 1022 CaptionEntities []MessageEntity 1023 } 1024 1025 func (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 1038 func (config EditMessageCaptionConfig) method() string { 1039 return "editMessageCaption" 1040 } 1041 1042 // EditMessageMediaConfig allows you to make an editMessageMedia request. 1043 type EditMessageMediaConfig struct { 1044 BaseEdit 1045 1046 Media interface{} 1047 } 1048 1049 func (EditMessageMediaConfig) method() string { 1050 return "editMessageMedia" 1051 } 1052 1053 func (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 1064 func (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. 1070 type EditMessageReplyMarkupConfig struct { 1071 BaseEdit 1072 } 1073 1074 func (config EditMessageReplyMarkupConfig) params() (Params, error) { 1075 return config.BaseEdit.params() 1076 } 1077 1078 func (config EditMessageReplyMarkupConfig) method() string { 1079 return "editMessageReplyMarkup" 1080 } 1081 1082 // StopPollConfig allows you to stop a poll sent by the bot. 1083 type StopPollConfig struct { 1084 BaseEdit 1085 } 1086 1087 func (config StopPollConfig) params() (Params, error) { 1088 return config.BaseEdit.params() 1089 } 1090 1091 func (StopPollConfig) method() string { 1092 return "stopPoll" 1093 } 1094 1095 // UserProfilePhotosConfig contains information about a 1096 // GetUserProfilePhotos request. 1097 type UserProfilePhotosConfig struct { 1098 UserID int64 1099 Offset int 1100 Limit int 1101 } 1102 1103 func (UserProfilePhotosConfig) method() string { 1104 return "getUserProfilePhotos" 1105 } 1106 1107 func (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. 1118 type FileConfig struct { 1119 FileID string 1120 } 1121 1122 func (FileConfig) method() string { 1123 return "getFile" 1124 } 1125 1126 func (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. 1135 type UpdateConfig struct { 1136 Offset int 1137 Limit int 1138 Timeout int 1139 AllowedUpdates []string 1140 } 1141 1142 func (UpdateConfig) method() string { 1143 return "getUpdates" 1144 } 1145 1146 func (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. 1158 type WebhookConfig struct { 1159 URL *url.URL 1160 Certificate RequestFileData 1161 IPAddress string 1162 MaxConnections int 1163 AllowedUpdates []string 1164 DropPendingUpdates bool 1165 } 1166 1167 func (config WebhookConfig) method() string { 1168 return "setWebhook" 1169 } 1170 1171 func (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 1186 func (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. 1198 type DeleteWebhookConfig struct { 1199 DropPendingUpdates bool 1200 } 1201 1202 func (config DeleteWebhookConfig) method() string { 1203 return "deleteWebhook" 1204 } 1205 1206 func (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. 1215 type 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 1225 func (config InlineConfig) method() string { 1226 return "answerInlineQuery" 1227 } 1228 1229 func (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. 1244 type 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 1252 func (config CallbackConfig) method() string { 1253 return "answerCallbackQuery" 1254 } 1255 1256 func (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. 1270 type ChatMemberConfig struct { 1271 ChatID int64 1272 SuperGroupUsername string 1273 ChannelUsername string 1274 UserID int64 1275 } 1276 1277 // UnbanChatMemberConfig allows you to unban a user. 1278 type UnbanChatMemberConfig struct { 1279 ChatMemberConfig 1280 OnlyIfBanned bool 1281 } 1282 1283 func (config UnbanChatMemberConfig) method() string { 1284 return "unbanChatMember" 1285 } 1286 1287 func (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. 1298 type BanChatMemberConfig struct { 1299 ChatMemberConfig 1300 UntilDate int64 1301 RevokeMessages bool 1302 } 1303 1304 func (config BanChatMemberConfig) method() string { 1305 return "banChatMember" 1306 } 1307 1308 func (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. 1322 type KickChatMemberConfig = BanChatMemberConfig 1323 1324 // RestrictChatMemberConfig contains fields to restrict members of chat 1325 type RestrictChatMemberConfig struct { 1326 ChatMemberConfig 1327 UntilDate int64 1328 Permissions *ChatPermissions 1329 } 1330 1331 func (config RestrictChatMemberConfig) method() string { 1332 return "restrictChatMember" 1333 } 1334 1335 func (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 1348 type 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 1363 func (config PromoteChatMemberConfig) method() string { 1364 return "promoteChatMember" 1365 } 1366 1367 func (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. 1390 type SetChatAdministratorCustomTitle struct { 1391 ChatMemberConfig 1392 CustomTitle string 1393 } 1394 1395 func (SetChatAdministratorCustomTitle) method() string { 1396 return "setChatAdministratorCustomTitle" 1397 } 1398 1399 func (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 // BanChatSenderChatConfig bans a channel chat in a supergroup or a channel. The 1410 // owner of the chat will not be able to send messages and join live streams on 1411 // behalf of the chat, unless it is unbanned first. The bot must be an 1412 // administrator in the supergroup or channel for this to work and must have the 1413 // appropriate administrator rights. 1414 type BanChatSenderChatConfig struct { 1415 ChatID int64 1416 ChannelUsername string 1417 SenderChatID int64 1418 UntilDate int 1419 } 1420 1421 func (config BanChatSenderChatConfig) method() string { 1422 return "banChatSenderChat" 1423 } 1424 1425 func (config BanChatSenderChatConfig) params() (Params, error) { 1426 params := make(Params) 1427 1428 _ = params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername) 1429 params.AddNonZero64("sender_chat_id", config.SenderChatID) 1430 params.AddNonZero("until_date", config.UntilDate) 1431 1432 return params, nil 1433 } 1434 1435 // UnbanChatSenderChatConfig unbans a previously banned channel chat in a 1436 // supergroup or channel. The bot must be an administrator for this to work and 1437 // must have the appropriate administrator rights. 1438 type UnbanChatSenderChatConfig struct { 1439 ChatID int64 1440 ChannelUsername string 1441 SenderChatID int64 1442 } 1443 1444 func (config UnbanChatSenderChatConfig) method() string { 1445 return "unbanChatSenderChat" 1446 } 1447 1448 func (config UnbanChatSenderChatConfig) params() (Params, error) { 1449 params := make(Params) 1450 1451 _ = params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername) 1452 params.AddNonZero64("sender_chat_id", config.SenderChatID) 1453 1454 return params, nil 1455 } 1456 1457 // ChatConfig contains information about getting information on a chat. 1458 type ChatConfig struct { 1459 ChatID int64 1460 SuperGroupUsername string 1461 } 1462 1463 func (config ChatConfig) params() (Params, error) { 1464 params := make(Params) 1465 1466 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername) 1467 1468 return params, nil 1469 } 1470 1471 // ChatInfoConfig contains information about getting chat information. 1472 type ChatInfoConfig struct { 1473 ChatConfig 1474 } 1475 1476 func (ChatInfoConfig) method() string { 1477 return "getChat" 1478 } 1479 1480 // ChatMemberCountConfig contains information about getting the number of users in a chat. 1481 type ChatMemberCountConfig struct { 1482 ChatConfig 1483 } 1484 1485 func (ChatMemberCountConfig) method() string { 1486 return "getChatMembersCount" 1487 } 1488 1489 // ChatAdministratorsConfig contains information about getting chat administrators. 1490 type ChatAdministratorsConfig struct { 1491 ChatConfig 1492 } 1493 1494 func (ChatAdministratorsConfig) method() string { 1495 return "getChatAdministrators" 1496 } 1497 1498 // SetChatPermissionsConfig allows you to set default permissions for the 1499 // members in a group. The bot must be an administrator and have rights to 1500 // restrict members. 1501 type SetChatPermissionsConfig struct { 1502 ChatConfig 1503 Permissions *ChatPermissions 1504 } 1505 1506 func (SetChatPermissionsConfig) method() string { 1507 return "setChatPermissions" 1508 } 1509 1510 func (config SetChatPermissionsConfig) params() (Params, error) { 1511 params := make(Params) 1512 1513 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername) 1514 err := params.AddInterface("permissions", config.Permissions) 1515 1516 return params, err 1517 } 1518 1519 // ChatInviteLinkConfig contains information about getting a chat link. 1520 // 1521 // Note that generating a new link will revoke any previous links. 1522 type ChatInviteLinkConfig struct { 1523 ChatConfig 1524 } 1525 1526 func (ChatInviteLinkConfig) method() string { 1527 return "exportChatInviteLink" 1528 } 1529 1530 func (config ChatInviteLinkConfig) params() (Params, error) { 1531 params := make(Params) 1532 1533 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername) 1534 1535 return params, nil 1536 } 1537 1538 // CreateChatInviteLinkConfig allows you to create an additional invite link for 1539 // a chat. The bot must be an administrator in the chat for this to work and 1540 // must have the appropriate admin rights. The link can be revoked using the 1541 // RevokeChatInviteLinkConfig. 1542 type CreateChatInviteLinkConfig struct { 1543 ChatConfig 1544 Name string 1545 ExpireDate int 1546 MemberLimit int 1547 CreatesJoinRequest bool 1548 } 1549 1550 func (CreateChatInviteLinkConfig) method() string { 1551 return "createChatInviteLink" 1552 } 1553 1554 func (config CreateChatInviteLinkConfig) params() (Params, error) { 1555 params := make(Params) 1556 1557 params.AddNonEmpty("name", config.Name) 1558 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername) 1559 params.AddNonZero("expire_date", config.ExpireDate) 1560 params.AddNonZero("member_limit", config.MemberLimit) 1561 params.AddBool("creates_join_request", config.CreatesJoinRequest) 1562 1563 return params, nil 1564 } 1565 1566 // EditChatInviteLinkConfig allows you to edit a non-primary invite link created 1567 // by the bot. The bot must be an administrator in the chat for this to work and 1568 // must have the appropriate admin rights. 1569 type EditChatInviteLinkConfig struct { 1570 ChatConfig 1571 InviteLink string 1572 Name string 1573 ExpireDate int 1574 MemberLimit int 1575 CreatesJoinRequest bool 1576 } 1577 1578 func (EditChatInviteLinkConfig) method() string { 1579 return "editChatInviteLink" 1580 } 1581 1582 func (config EditChatInviteLinkConfig) params() (Params, error) { 1583 params := make(Params) 1584 1585 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername) 1586 params.AddNonEmpty("name", config.Name) 1587 params["invite_link"] = config.InviteLink 1588 params.AddNonZero("expire_date", config.ExpireDate) 1589 params.AddNonZero("member_limit", config.MemberLimit) 1590 params.AddBool("creates_join_request", config.CreatesJoinRequest) 1591 1592 return params, nil 1593 } 1594 1595 // RevokeChatInviteLinkConfig allows you to revoke an invite link created by the 1596 // bot. If the primary link is revoked, a new link is automatically generated. 1597 // The bot must be an administrator in the chat for this to work and must have 1598 // the appropriate admin rights. 1599 type RevokeChatInviteLinkConfig struct { 1600 ChatConfig 1601 InviteLink string 1602 } 1603 1604 func (RevokeChatInviteLinkConfig) method() string { 1605 return "revokeChatInviteLink" 1606 } 1607 1608 func (config RevokeChatInviteLinkConfig) params() (Params, error) { 1609 params := make(Params) 1610 1611 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername) 1612 params["invite_link"] = config.InviteLink 1613 1614 return params, nil 1615 } 1616 1617 // ApproveChatJoinRequestConfig allows you to approve a chat join request. 1618 type ApproveChatJoinRequestConfig struct { 1619 ChatConfig 1620 UserID int64 1621 } 1622 1623 func (ApproveChatJoinRequestConfig) method() string { 1624 return "approveChatJoinRequest" 1625 } 1626 1627 func (config ApproveChatJoinRequestConfig) params() (Params, error) { 1628 params := make(Params) 1629 1630 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername) 1631 params.AddNonZero("user_id", int(config.UserID)) 1632 1633 return params, nil 1634 } 1635 1636 // DeclineChatJoinRequest allows you to decline a chat join request. 1637 type DeclineChatJoinRequest struct { 1638 ChatConfig 1639 UserID int64 1640 } 1641 1642 func (DeclineChatJoinRequest) method() string { 1643 return "declineChatJoinRequest" 1644 } 1645 1646 func (config DeclineChatJoinRequest) params() (Params, error) { 1647 params := make(Params) 1648 1649 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername) 1650 params.AddNonZero("user_id", int(config.UserID)) 1651 1652 return params, nil 1653 } 1654 1655 // LeaveChatConfig allows you to leave a chat. 1656 type LeaveChatConfig struct { 1657 ChatID int64 1658 ChannelUsername string 1659 } 1660 1661 func (config LeaveChatConfig) method() string { 1662 return "leaveChat" 1663 } 1664 1665 func (config LeaveChatConfig) params() (Params, error) { 1666 params := make(Params) 1667 1668 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername) 1669 1670 return params, nil 1671 } 1672 1673 // ChatConfigWithUser contains information about a chat and a user. 1674 type ChatConfigWithUser struct { 1675 ChatID int64 1676 SuperGroupUsername string 1677 UserID int64 1678 } 1679 1680 func (config ChatConfigWithUser) params() (Params, error) { 1681 params := make(Params) 1682 1683 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername) 1684 params.AddNonZero64("user_id", config.UserID) 1685 1686 return params, nil 1687 } 1688 1689 // GetChatMemberConfig is information about getting a specific member in a chat. 1690 type GetChatMemberConfig struct { 1691 ChatConfigWithUser 1692 } 1693 1694 func (GetChatMemberConfig) method() string { 1695 return "getChatMember" 1696 } 1697 1698 // InvoiceConfig contains information for sendInvoice request. 1699 type InvoiceConfig struct { 1700 BaseChat 1701 Title string // required 1702 Description string // required 1703 Payload string // required 1704 ProviderToken string // required 1705 Currency string // required 1706 Prices []LabeledPrice // required 1707 MaxTipAmount int 1708 SuggestedTipAmounts []int 1709 StartParameter string 1710 ProviderData string 1711 PhotoURL string 1712 PhotoSize int 1713 PhotoWidth int 1714 PhotoHeight int 1715 NeedName bool 1716 NeedPhoneNumber bool 1717 NeedEmail bool 1718 NeedShippingAddress bool 1719 SendPhoneNumberToProvider bool 1720 SendEmailToProvider bool 1721 IsFlexible bool 1722 } 1723 1724 func (config InvoiceConfig) params() (Params, error) { 1725 params, err := config.BaseChat.params() 1726 if err != nil { 1727 return params, err 1728 } 1729 1730 params["title"] = config.Title 1731 params["description"] = config.Description 1732 params["payload"] = config.Payload 1733 params["provider_token"] = config.ProviderToken 1734 params["currency"] = config.Currency 1735 if err = params.AddInterface("prices", config.Prices); err != nil { 1736 return params, err 1737 } 1738 1739 params.AddNonZero("max_tip_amount", config.MaxTipAmount) 1740 err = params.AddInterface("suggested_tip_amounts", config.SuggestedTipAmounts) 1741 params.AddNonEmpty("start_parameter", config.StartParameter) 1742 params.AddNonEmpty("provider_data", config.ProviderData) 1743 params.AddNonEmpty("photo_url", config.PhotoURL) 1744 params.AddNonZero("photo_size", config.PhotoSize) 1745 params.AddNonZero("photo_width", config.PhotoWidth) 1746 params.AddNonZero("photo_height", config.PhotoHeight) 1747 params.AddBool("need_name", config.NeedName) 1748 params.AddBool("need_phone_number", config.NeedPhoneNumber) 1749 params.AddBool("need_email", config.NeedEmail) 1750 params.AddBool("need_shipping_address", config.NeedShippingAddress) 1751 params.AddBool("is_flexible", config.IsFlexible) 1752 params.AddBool("send_phone_number_to_provider", config.SendPhoneNumberToProvider) 1753 params.AddBool("send_email_to_provider", config.SendEmailToProvider) 1754 1755 return params, err 1756 } 1757 1758 func (config InvoiceConfig) method() string { 1759 return "sendInvoice" 1760 } 1761 1762 // ShippingConfig contains information for answerShippingQuery request. 1763 type ShippingConfig struct { 1764 ShippingQueryID string // required 1765 OK bool // required 1766 ShippingOptions []ShippingOption 1767 ErrorMessage string 1768 } 1769 1770 func (config ShippingConfig) method() string { 1771 return "answerShippingQuery" 1772 } 1773 1774 func (config ShippingConfig) params() (Params, error) { 1775 params := make(Params) 1776 1777 params["shipping_query_id"] = config.ShippingQueryID 1778 params.AddBool("ok", config.OK) 1779 err := params.AddInterface("shipping_options", config.ShippingOptions) 1780 params.AddNonEmpty("error_message", config.ErrorMessage) 1781 1782 return params, err 1783 } 1784 1785 // PreCheckoutConfig conatins information for answerPreCheckoutQuery request. 1786 type PreCheckoutConfig struct { 1787 PreCheckoutQueryID string // required 1788 OK bool // required 1789 ErrorMessage string 1790 } 1791 1792 func (config PreCheckoutConfig) method() string { 1793 return "answerPreCheckoutQuery" 1794 } 1795 1796 func (config PreCheckoutConfig) params() (Params, error) { 1797 params := make(Params) 1798 1799 params["pre_checkout_query_id"] = config.PreCheckoutQueryID 1800 params.AddBool("ok", config.OK) 1801 params.AddNonEmpty("error_message", config.ErrorMessage) 1802 1803 return params, nil 1804 } 1805 1806 // DeleteMessageConfig contains information of a message in a chat to delete. 1807 type DeleteMessageConfig struct { 1808 ChannelUsername string 1809 ChatID int64 1810 MessageID int 1811 } 1812 1813 func (config DeleteMessageConfig) method() string { 1814 return "deleteMessage" 1815 } 1816 1817 func (config DeleteMessageConfig) params() (Params, error) { 1818 params := make(Params) 1819 1820 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername) 1821 params.AddNonZero("message_id", config.MessageID) 1822 1823 return params, nil 1824 } 1825 1826 // PinChatMessageConfig contains information of a message in a chat to pin. 1827 type PinChatMessageConfig struct { 1828 ChatID int64 1829 ChannelUsername string 1830 MessageID int 1831 DisableNotification bool 1832 } 1833 1834 func (config PinChatMessageConfig) method() string { 1835 return "pinChatMessage" 1836 } 1837 1838 func (config PinChatMessageConfig) params() (Params, error) { 1839 params := make(Params) 1840 1841 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername) 1842 params.AddNonZero("message_id", config.MessageID) 1843 params.AddBool("disable_notification", config.DisableNotification) 1844 1845 return params, nil 1846 } 1847 1848 // UnpinChatMessageConfig contains information of a chat message to unpin. 1849 // 1850 // If MessageID is not specified, it will unpin the most recent pin. 1851 type UnpinChatMessageConfig struct { 1852 ChatID int64 1853 ChannelUsername string 1854 MessageID int 1855 } 1856 1857 func (config UnpinChatMessageConfig) method() string { 1858 return "unpinChatMessage" 1859 } 1860 1861 func (config UnpinChatMessageConfig) params() (Params, error) { 1862 params := make(Params) 1863 1864 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername) 1865 params.AddNonZero("message_id", config.MessageID) 1866 1867 return params, nil 1868 } 1869 1870 // UnpinAllChatMessagesConfig contains information of all messages to unpin in 1871 // a chat. 1872 type UnpinAllChatMessagesConfig struct { 1873 ChatID int64 1874 ChannelUsername string 1875 } 1876 1877 func (config UnpinAllChatMessagesConfig) method() string { 1878 return "unpinAllChatMessages" 1879 } 1880 1881 func (config UnpinAllChatMessagesConfig) params() (Params, error) { 1882 params := make(Params) 1883 1884 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername) 1885 1886 return params, nil 1887 } 1888 1889 // SetChatPhotoConfig allows you to set a group, supergroup, or channel's photo. 1890 type SetChatPhotoConfig struct { 1891 BaseFile 1892 } 1893 1894 func (config SetChatPhotoConfig) method() string { 1895 return "setChatPhoto" 1896 } 1897 1898 func (config SetChatPhotoConfig) files() []RequestFile { 1899 return []RequestFile{{ 1900 Name: "photo", 1901 Data: config.File, 1902 }} 1903 } 1904 1905 // DeleteChatPhotoConfig allows you to delete a group, supergroup, or channel's photo. 1906 type DeleteChatPhotoConfig struct { 1907 ChatID int64 1908 ChannelUsername string 1909 } 1910 1911 func (config DeleteChatPhotoConfig) method() string { 1912 return "deleteChatPhoto" 1913 } 1914 1915 func (config DeleteChatPhotoConfig) params() (Params, error) { 1916 params := make(Params) 1917 1918 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername) 1919 1920 return params, nil 1921 } 1922 1923 // SetChatTitleConfig allows you to set the title of something other than a private chat. 1924 type SetChatTitleConfig struct { 1925 ChatID int64 1926 ChannelUsername string 1927 1928 Title string 1929 } 1930 1931 func (config SetChatTitleConfig) method() string { 1932 return "setChatTitle" 1933 } 1934 1935 func (config SetChatTitleConfig) params() (Params, error) { 1936 params := make(Params) 1937 1938 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername) 1939 params["title"] = config.Title 1940 1941 return params, nil 1942 } 1943 1944 // SetChatDescriptionConfig allows you to set the description of a supergroup or channel. 1945 type SetChatDescriptionConfig struct { 1946 ChatID int64 1947 ChannelUsername string 1948 1949 Description string 1950 } 1951 1952 func (config SetChatDescriptionConfig) method() string { 1953 return "setChatDescription" 1954 } 1955 1956 func (config SetChatDescriptionConfig) params() (Params, error) { 1957 params := make(Params) 1958 1959 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername) 1960 params["description"] = config.Description 1961 1962 return params, nil 1963 } 1964 1965 // GetStickerSetConfig allows you to get the stickers in a set. 1966 type GetStickerSetConfig struct { 1967 Name string 1968 } 1969 1970 func (config GetStickerSetConfig) method() string { 1971 return "getStickerSet" 1972 } 1973 1974 func (config GetStickerSetConfig) params() (Params, error) { 1975 params := make(Params) 1976 1977 params["name"] = config.Name 1978 1979 return params, nil 1980 } 1981 1982 // UploadStickerConfig allows you to upload a sticker for use in a set later. 1983 type UploadStickerConfig struct { 1984 UserID int64 1985 PNGSticker RequestFileData 1986 } 1987 1988 func (config UploadStickerConfig) method() string { 1989 return "uploadStickerFile" 1990 } 1991 1992 func (config UploadStickerConfig) params() (Params, error) { 1993 params := make(Params) 1994 1995 params.AddNonZero64("user_id", config.UserID) 1996 1997 return params, nil 1998 } 1999 2000 func (config UploadStickerConfig) files() []RequestFile { 2001 return []RequestFile{{ 2002 Name: "png_sticker", 2003 Data: config.PNGSticker, 2004 }} 2005 } 2006 2007 // NewStickerSetConfig allows creating a new sticker set. 2008 // 2009 // You must set either PNGSticker or TGSSticker. 2010 type NewStickerSetConfig struct { 2011 UserID int64 2012 Name string 2013 Title string 2014 PNGSticker RequestFileData 2015 TGSSticker RequestFileData 2016 Emojis string 2017 ContainsMasks bool 2018 MaskPosition *MaskPosition 2019 } 2020 2021 func (config NewStickerSetConfig) method() string { 2022 return "createNewStickerSet" 2023 } 2024 2025 func (config NewStickerSetConfig) params() (Params, error) { 2026 params := make(Params) 2027 2028 params.AddNonZero64("user_id", config.UserID) 2029 params["name"] = config.Name 2030 params["title"] = config.Title 2031 2032 params["emojis"] = config.Emojis 2033 2034 params.AddBool("contains_masks", config.ContainsMasks) 2035 2036 err := params.AddInterface("mask_position", config.MaskPosition) 2037 2038 return params, err 2039 } 2040 2041 func (config NewStickerSetConfig) files() []RequestFile { 2042 if config.PNGSticker != nil { 2043 return []RequestFile{{ 2044 Name: "png_sticker", 2045 Data: config.PNGSticker, 2046 }} 2047 } 2048 2049 return []RequestFile{{ 2050 Name: "tgs_sticker", 2051 Data: config.TGSSticker, 2052 }} 2053 } 2054 2055 // AddStickerConfig allows you to add a sticker to a set. 2056 type AddStickerConfig struct { 2057 UserID int64 2058 Name string 2059 PNGSticker RequestFileData 2060 TGSSticker RequestFileData 2061 Emojis string 2062 MaskPosition *MaskPosition 2063 } 2064 2065 func (config AddStickerConfig) method() string { 2066 return "addStickerToSet" 2067 } 2068 2069 func (config AddStickerConfig) params() (Params, error) { 2070 params := make(Params) 2071 2072 params.AddNonZero64("user_id", config.UserID) 2073 params["name"] = config.Name 2074 params["emojis"] = config.Emojis 2075 2076 err := params.AddInterface("mask_position", config.MaskPosition) 2077 2078 return params, err 2079 } 2080 2081 func (config AddStickerConfig) files() []RequestFile { 2082 if config.PNGSticker != nil { 2083 return []RequestFile{{ 2084 Name: "png_sticker", 2085 Data: config.PNGSticker, 2086 }} 2087 } 2088 2089 return []RequestFile{{ 2090 Name: "tgs_sticker", 2091 Data: config.TGSSticker, 2092 }} 2093 2094 } 2095 2096 // SetStickerPositionConfig allows you to change the position of a sticker in a set. 2097 type SetStickerPositionConfig struct { 2098 Sticker string 2099 Position int 2100 } 2101 2102 func (config SetStickerPositionConfig) method() string { 2103 return "setStickerPositionInSet" 2104 } 2105 2106 func (config SetStickerPositionConfig) params() (Params, error) { 2107 params := make(Params) 2108 2109 params["sticker"] = config.Sticker 2110 params.AddNonZero("position", config.Position) 2111 2112 return params, nil 2113 } 2114 2115 // DeleteStickerConfig allows you to delete a sticker from a set. 2116 type DeleteStickerConfig struct { 2117 Sticker string 2118 } 2119 2120 func (config DeleteStickerConfig) method() string { 2121 return "deleteStickerFromSet" 2122 } 2123 2124 func (config DeleteStickerConfig) params() (Params, error) { 2125 params := make(Params) 2126 2127 params["sticker"] = config.Sticker 2128 2129 return params, nil 2130 } 2131 2132 // SetStickerSetThumbConfig allows you to set the thumbnail for a sticker set. 2133 type SetStickerSetThumbConfig struct { 2134 Name string 2135 UserID int64 2136 Thumb RequestFileData 2137 } 2138 2139 func (config SetStickerSetThumbConfig) method() string { 2140 return "setStickerSetThumb" 2141 } 2142 2143 func (config SetStickerSetThumbConfig) params() (Params, error) { 2144 params := make(Params) 2145 2146 params["name"] = config.Name 2147 params.AddNonZero64("user_id", config.UserID) 2148 2149 return params, nil 2150 } 2151 2152 func (config SetStickerSetThumbConfig) files() []RequestFile { 2153 return []RequestFile{{ 2154 Name: "thumb", 2155 Data: config.Thumb, 2156 }} 2157 } 2158 2159 // SetChatStickerSetConfig allows you to set the sticker set for a supergroup. 2160 type SetChatStickerSetConfig struct { 2161 ChatID int64 2162 SuperGroupUsername string 2163 2164 StickerSetName string 2165 } 2166 2167 func (config SetChatStickerSetConfig) method() string { 2168 return "setChatStickerSet" 2169 } 2170 2171 func (config SetChatStickerSetConfig) params() (Params, error) { 2172 params := make(Params) 2173 2174 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername) 2175 params["sticker_set_name"] = config.StickerSetName 2176 2177 return params, nil 2178 } 2179 2180 // DeleteChatStickerSetConfig allows you to remove a supergroup's sticker set. 2181 type DeleteChatStickerSetConfig struct { 2182 ChatID int64 2183 SuperGroupUsername string 2184 } 2185 2186 func (config DeleteChatStickerSetConfig) method() string { 2187 return "deleteChatStickerSet" 2188 } 2189 2190 func (config DeleteChatStickerSetConfig) params() (Params, error) { 2191 params := make(Params) 2192 2193 params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername) 2194 2195 return params, nil 2196 } 2197 2198 // MediaGroupConfig allows you to send a group of media. 2199 // 2200 // Media consist of InputMedia items (InputMediaPhoto, InputMediaVideo). 2201 type MediaGroupConfig struct { 2202 ChatID int64 2203 ChannelUsername string 2204 2205 Media []interface{} 2206 DisableNotification bool 2207 ReplyToMessageID int 2208 } 2209 2210 func (config MediaGroupConfig) method() string { 2211 return "sendMediaGroup" 2212 } 2213 2214 func (config MediaGroupConfig) params() (Params, error) { 2215 params := make(Params) 2216 2217 params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername) 2218 params.AddBool("disable_notification", config.DisableNotification) 2219 params.AddNonZero("reply_to_message_id", config.ReplyToMessageID) 2220 2221 err := params.AddInterface("media", prepareInputMediaForParams(config.Media)) 2222 2223 return params, err 2224 } 2225 2226 func (config MediaGroupConfig) files() []RequestFile { 2227 return prepareInputMediaForFiles(config.Media) 2228 } 2229 2230 // DiceConfig contains information about a sendDice request. 2231 type DiceConfig struct { 2232 BaseChat 2233 // Emoji on which the dice throw animation is based. 2234 // Currently, must be one of 🎲, 🎯, 🏀, ⚽, 🎳, or 🎰. 2235 // Dice can have values 1-6 for 🎲, 🎯, and 🎳, values 1-5 for 🏀 and ⚽, 2236 // and values 1-64 for 🎰. 2237 // Defaults to “🎲” 2238 Emoji string 2239 } 2240 2241 func (config DiceConfig) method() string { 2242 return "sendDice" 2243 } 2244 2245 func (config DiceConfig) params() (Params, error) { 2246 params, err := config.BaseChat.params() 2247 if err != nil { 2248 return params, err 2249 } 2250 2251 params.AddNonEmpty("emoji", config.Emoji) 2252 2253 return params, err 2254 } 2255 2256 // GetMyCommandsConfig gets a list of the currently registered commands. 2257 type GetMyCommandsConfig struct { 2258 Scope *BotCommandScope 2259 LanguageCode string 2260 } 2261 2262 func (config GetMyCommandsConfig) method() string { 2263 return "getMyCommands" 2264 } 2265 2266 func (config GetMyCommandsConfig) params() (Params, error) { 2267 params := make(Params) 2268 2269 err := params.AddInterface("scope", config.Scope) 2270 params.AddNonEmpty("language_code", config.LanguageCode) 2271 2272 return params, err 2273 } 2274 2275 // SetMyCommandsConfig sets a list of commands the bot understands. 2276 type SetMyCommandsConfig struct { 2277 Commands []BotCommand 2278 Scope *BotCommandScope 2279 LanguageCode string 2280 } 2281 2282 func (config SetMyCommandsConfig) method() string { 2283 return "setMyCommands" 2284 } 2285 2286 func (config SetMyCommandsConfig) params() (Params, error) { 2287 params := make(Params) 2288 2289 if err := params.AddInterface("commands", config.Commands); err != nil { 2290 return params, err 2291 } 2292 err := params.AddInterface("scope", config.Scope) 2293 params.AddNonEmpty("language_code", config.LanguageCode) 2294 2295 return params, err 2296 } 2297 2298 type DeleteMyCommandsConfig struct { 2299 Scope *BotCommandScope 2300 LanguageCode string 2301 } 2302 2303 func (config DeleteMyCommandsConfig) method() string { 2304 return "deleteMyCommands" 2305 } 2306 2307 func (config DeleteMyCommandsConfig) params() (Params, error) { 2308 params := make(Params) 2309 2310 err := params.AddInterface("scope", config.Scope) 2311 params.AddNonEmpty("language_code", config.LanguageCode) 2312 2313 return params, err 2314 } 2315 2316 // prepareInputMediaParam evaluates a single InputMedia and determines if it 2317 // needs to be modified for a successful upload. If it returns nil, then the 2318 // value does not need to be included in the params. Otherwise, it will return 2319 // the same type as was originally provided. 2320 // 2321 // The idx is used to calculate the file field name. If you only have a single 2322 // file, 0 may be used. It is formatted into "attach://file-%d" for the primary 2323 // media and "attach://file-%d-thumb" for thumbnails. 2324 // 2325 // It is expected to be used in conjunction with prepareInputMediaFile. 2326 func prepareInputMediaParam(inputMedia interface{}, idx int) interface{} { 2327 switch m := inputMedia.(type) { 2328 case InputMediaPhoto: 2329 if m.Media.NeedsUpload() { 2330 m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx)) 2331 } 2332 2333 return m 2334 case InputMediaVideo: 2335 if m.Media.NeedsUpload() { 2336 m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx)) 2337 } 2338 2339 if m.Thumb != nil && m.Thumb.NeedsUpload() { 2340 m.Thumb = fileAttach(fmt.Sprintf("attach://file-%d-thumb", idx)) 2341 } 2342 2343 return m 2344 case InputMediaAudio: 2345 if m.Media.NeedsUpload() { 2346 m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx)) 2347 } 2348 2349 if m.Thumb != nil && m.Thumb.NeedsUpload() { 2350 m.Thumb = fileAttach(fmt.Sprintf("attach://file-%d-thumb", idx)) 2351 } 2352 2353 return m 2354 case InputMediaDocument: 2355 if m.Media.NeedsUpload() { 2356 m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx)) 2357 } 2358 2359 if m.Thumb != nil && m.Thumb.NeedsUpload() { 2360 m.Thumb = fileAttach(fmt.Sprintf("attach://file-%d-thumb", idx)) 2361 } 2362 2363 return m 2364 } 2365 2366 return nil 2367 } 2368 2369 // prepareInputMediaFile generates an array of RequestFile to provide for 2370 // Fileable's files method. It returns an array as a single InputMedia may have 2371 // multiple files, for the primary media and a thumbnail. 2372 // 2373 // The idx parameter is used to generate file field names. It uses the names 2374 // "file-%d" for the main file and "file-%d-thumb" for the thumbnail. 2375 // 2376 // It is expected to be used in conjunction with prepareInputMediaParam. 2377 func prepareInputMediaFile(inputMedia interface{}, idx int) []RequestFile { 2378 files := []RequestFile{} 2379 2380 switch m := inputMedia.(type) { 2381 case InputMediaPhoto: 2382 if m.Media.NeedsUpload() { 2383 files = append(files, RequestFile{ 2384 Name: fmt.Sprintf("file-%d", idx), 2385 Data: m.Media, 2386 }) 2387 } 2388 case InputMediaVideo: 2389 if m.Media.NeedsUpload() { 2390 files = append(files, RequestFile{ 2391 Name: fmt.Sprintf("file-%d", idx), 2392 Data: m.Media, 2393 }) 2394 } 2395 2396 if m.Thumb != nil && m.Thumb.NeedsUpload() { 2397 files = append(files, RequestFile{ 2398 Name: fmt.Sprintf("file-%d", idx), 2399 Data: m.Thumb, 2400 }) 2401 } 2402 case InputMediaDocument: 2403 if m.Media.NeedsUpload() { 2404 files = append(files, RequestFile{ 2405 Name: fmt.Sprintf("file-%d", idx), 2406 Data: m.Media, 2407 }) 2408 } 2409 2410 if m.Thumb != nil && m.Thumb.NeedsUpload() { 2411 files = append(files, RequestFile{ 2412 Name: fmt.Sprintf("file-%d", idx), 2413 Data: m.Thumb, 2414 }) 2415 } 2416 case InputMediaAudio: 2417 if m.Media.NeedsUpload() { 2418 files = append(files, RequestFile{ 2419 Name: fmt.Sprintf("file-%d", idx), 2420 Data: m.Media, 2421 }) 2422 } 2423 2424 if m.Thumb != nil && m.Thumb.NeedsUpload() { 2425 files = append(files, RequestFile{ 2426 Name: fmt.Sprintf("file-%d", idx), 2427 Data: m.Thumb, 2428 }) 2429 } 2430 } 2431 2432 return files 2433 } 2434 2435 // prepareInputMediaForParams calls prepareInputMediaParam for each item 2436 // provided and returns a new array with the correct params for a request. 2437 // 2438 // It is expected that files will get data from the associated function, 2439 // prepareInputMediaForFiles. 2440 func prepareInputMediaForParams(inputMedia []interface{}) []interface{} { 2441 newMedia := make([]interface{}, len(inputMedia)) 2442 copy(newMedia, inputMedia) 2443 2444 for idx, media := range inputMedia { 2445 if param := prepareInputMediaParam(media, idx); param != nil { 2446 newMedia[idx] = param 2447 } 2448 } 2449 2450 return newMedia 2451 } 2452 2453 // prepareInputMediaForFiles calls prepareInputMediaFile for each item 2454 // provided and returns a new array with the correct files for a request. 2455 // 2456 // It is expected that params will get data from the associated function, 2457 // prepareInputMediaForParams. 2458 func prepareInputMediaForFiles(inputMedia []interface{}) []RequestFile { 2459 files := []RequestFile{} 2460 2461 for idx, media := range inputMedia { 2462 if file := prepareInputMediaFile(media, idx); file != nil { 2463 files = append(files, file...) 2464 } 2465 } 2466 2467 return files 2468 }