all repos — telegram-bot-api @ bot-api-7.4

Golang bindings for the Telegram Bot API

configs.go (view raw)

   1package tgbotapi
   2
   3import (
   4	"bytes"
   5	"fmt"
   6	"io"
   7	"net/url"
   8	"os"
   9	"strconv"
  10)
  11
  12// Telegram constants
  13const (
  14	// APIEndpoint is the endpoint for all API methods,
  15	// with formatting for Sprintf.
  16	APIEndpoint = "https://api.telegram.org/bot%s/%s"
  17	// FileEndpoint is the endpoint for downloading a file from Telegram.
  18	FileEndpoint = "https://api.telegram.org/file/bot%s/%s"
  19)
  20
  21// Constant values for ChatActions
  22const (
  23	ChatTyping          = "typing"
  24	ChatUploadPhoto     = "upload_photo"
  25	ChatRecordVideo     = "record_video"
  26	ChatUploadVideo     = "upload_video"
  27	ChatRecordVoice     = "record_voice"
  28	ChatUploadVoice     = "upload_voice"
  29	ChatUploadDocument  = "upload_document"
  30	ChatChooseSticker   = "choose_sticker"
  31	ChatFindLocation    = "find_location"
  32	ChatRecordVideoNote = "record_video_note"
  33	ChatUploadVideoNote = "upload_video_note"
  34)
  35
  36// API errors
  37const (
  38	// ErrAPIForbidden happens when a token is bad
  39	ErrAPIForbidden = "forbidden"
  40)
  41
  42// Constant values for ParseMode in MessageConfig
  43const (
  44	ModeMarkdown   = "Markdown"
  45	ModeMarkdownV2 = "MarkdownV2"
  46	ModeHTML       = "HTML"
  47)
  48
  49// Constant values for update types
  50const (
  51	// UpdateTypeMessage is new incoming message of any kind — text, photo, sticker, etc.
  52	UpdateTypeMessage = "message"
  53
  54	// UpdateTypeEditedMessage is new version of a message that is known to the bot and was edited
  55	UpdateTypeEditedMessage = "edited_message"
  56
  57	// UpdateTypeChannelPost is new incoming channel post of any kind — text, photo, sticker, etc.
  58	UpdateTypeChannelPost = "channel_post"
  59
  60	// UpdateTypeEditedChannelPost is new version of a channel post that is known to the bot and was edited
  61	UpdateTypeEditedChannelPost = "edited_channel_post"
  62
  63	// UpdateTypeBusinessConnection is the bot was connected to or disconnected from a business account,
  64	// or a user edited an existing connection with the bot
  65	UpdateTypeBusinessConnection = "business_connection"
  66
  67	// UpdateTypeBusinessMessage is a new non-service message from a connected business account
  68	UpdateTypeBusinessMessage = "business_message"
  69
  70	// UpdateTypeEditedBusinessMessage is a new version of a message from a connected business account
  71	UpdateTypeEditedBusinessMessage = "edited_business_message"
  72
  73	// UpdateTypeDeletedBusinessMessages are the messages were deleted from a connected business account
  74	UpdateTypeDeletedBusinessMessages = "deleted_business_messages"
  75
  76	// UpdateTypeMessageReactionis is a reaction to a message was changed by a user
  77	UpdateTypeMessageReaction = "message_reaction"
  78
  79	// UpdateTypeMessageReactionCount are reactions to a message with anonymous reactions were changed
  80	UpdateTypeMessageReactionCount = "message_reaction_count"
  81
  82	// UpdateTypeInlineQuery is new incoming inline query
  83	UpdateTypeInlineQuery = "inline_query"
  84
  85	// UpdateTypeChosenInlineResult i the result of an inline query that was chosen by a user and sent to their
  86	// chat partner. Please see the documentation on the feedback collecting for
  87	// details on how to enable these updates for your bot.
  88	UpdateTypeChosenInlineResult = "chosen_inline_result"
  89
  90	// UpdateTypeCallbackQuery is new incoming callback query
  91	UpdateTypeCallbackQuery = "callback_query"
  92
  93	// UpdateTypeShippingQuery is new incoming shipping query. Only for invoices with flexible price
  94	UpdateTypeShippingQuery = "shipping_query"
  95
  96	// UpdateTypePreCheckoutQuery is new incoming pre-checkout query. Contains full information about checkout
  97	UpdateTypePreCheckoutQuery = "pre_checkout_query"
  98
  99	// UpdateTypePoll is new poll state. Bots receive only updates about stopped polls and polls
 100	// which are sent by the bot
 101	UpdateTypePoll = "poll"
 102
 103	// UpdateTypePollAnswer is when user changed their answer in a non-anonymous poll. Bots receive new votes
 104	// only in polls that were sent by the bot itself.
 105	UpdateTypePollAnswer = "poll_answer"
 106
 107	// UpdateTypeMyChatMember is when the bot's chat member status was updated in a chat. For private chats, this
 108	// update is received only when the bot is blocked or unblocked by the user.
 109	UpdateTypeMyChatMember = "my_chat_member"
 110
 111	// UpdateTypeChatMember is when the bot must be an administrator in the chat and must explicitly specify
 112	// this update in the list of allowed_updates to receive these updates.
 113	UpdateTypeChatMember = "chat_member"
 114
 115	// UpdateTypeChatJoinRequest is request to join the chat has been sent.
 116	// The bot must have the can_invite_users administrator right in the chat to receive these updates.
 117	UpdateTypeChatJoinRequest = "chat_join_request"
 118
 119	// UpdateTypeChatBoost is chat boost was added or changed.
 120	// The bot must be an administrator in the chat to receive these updates.
 121	UpdateTypeChatBoost = "chat_boost"
 122
 123	// UpdateTypeRemovedChatBoost is boost was removed from a chat.
 124	// The bot must be an administrator in the chat to receive these updates.
 125	UpdateTypeRemovedChatBoost = "removed_chat_boost"
 126)
 127
 128// Library errors
 129const (
 130	ErrBadURL = "bad or empty url"
 131)
 132
 133// Chattable is any config type that can be sent.
 134type Chattable interface {
 135	params() (Params, error)
 136	method() string
 137}
 138
 139// Fileable is any config type that can be sent that includes a file.
 140type Fileable interface {
 141	Chattable
 142	files() []RequestFile
 143}
 144
 145// RequestFile represents a file associated with a field name.
 146type RequestFile struct {
 147	// The file field name.
 148	Name string
 149	// The file data to include.
 150	Data RequestFileData
 151}
 152
 153// RequestFileData represents the data to be used for a file.
 154type RequestFileData interface {
 155	// NeedsUpload shows if the file needs to be uploaded.
 156	NeedsUpload() bool
 157
 158	// UploadData gets the file name and an `io.Reader` for the file to be uploaded. This
 159	// must only be called when the file needs to be uploaded.
 160	UploadData() (string, io.Reader, error)
 161	// SendData gets the file data to send when a file does not need to be uploaded. This
 162	// must only be called when the file does not need to be uploaded.
 163	SendData() string
 164}
 165
 166// FileBytes contains information about a set of bytes to upload
 167// as a File.
 168type FileBytes struct {
 169	Name  string
 170	Bytes []byte
 171}
 172
 173func (fb FileBytes) NeedsUpload() bool {
 174	return true
 175}
 176
 177func (fb FileBytes) UploadData() (string, io.Reader, error) {
 178	return fb.Name, bytes.NewReader(fb.Bytes), nil
 179}
 180
 181func (fb FileBytes) SendData() string {
 182	panic("FileBytes must be uploaded")
 183}
 184
 185// FileReader contains information about a reader to upload as a File.
 186type FileReader struct {
 187	Name   string
 188	Reader io.Reader
 189}
 190
 191func (fr FileReader) NeedsUpload() bool {
 192	return true
 193}
 194
 195func (fr FileReader) UploadData() (string, io.Reader, error) {
 196	return fr.Name, fr.Reader, nil
 197}
 198
 199func (fr FileReader) SendData() string {
 200	panic("FileReader must be uploaded")
 201}
 202
 203// FilePath is a path to a local file.
 204type FilePath string
 205
 206func (fp FilePath) NeedsUpload() bool {
 207	return true
 208}
 209
 210func (fp FilePath) UploadData() (string, io.Reader, error) {
 211	fileHandle, err := os.Open(string(fp))
 212	if err != nil {
 213		return "", nil, err
 214	}
 215
 216	name := fileHandle.Name()
 217	return name, fileHandle, err
 218}
 219
 220func (fp FilePath) SendData() string {
 221	panic("FilePath must be uploaded")
 222}
 223
 224// FileURL is a URL to use as a file for a request.
 225type FileURL string
 226
 227func (fu FileURL) NeedsUpload() bool {
 228	return false
 229}
 230
 231func (fu FileURL) UploadData() (string, io.Reader, error) {
 232	panic("FileURL cannot be uploaded")
 233}
 234
 235func (fu FileURL) SendData() string {
 236	return string(fu)
 237}
 238
 239// FileID is an ID of a file already uploaded to Telegram.
 240type FileID string
 241
 242func (fi FileID) NeedsUpload() bool {
 243	return false
 244}
 245
 246func (fi FileID) UploadData() (string, io.Reader, error) {
 247	panic("FileID cannot be uploaded")
 248}
 249
 250func (fi FileID) SendData() string {
 251	return string(fi)
 252}
 253
 254// fileAttach is an internal file type used for processed media groups.
 255type fileAttach string
 256
 257func (fa fileAttach) NeedsUpload() bool {
 258	return false
 259}
 260
 261func (fa fileAttach) UploadData() (string, io.Reader, error) {
 262	panic("fileAttach cannot be uploaded")
 263}
 264
 265func (fa fileAttach) SendData() string {
 266	return string(fa)
 267}
 268
 269// LogOutConfig is a request to log out of the cloud Bot API server.
 270//
 271// Note that you may not log back in for at least 10 minutes.
 272type LogOutConfig struct{}
 273
 274func (LogOutConfig) method() string {
 275	return "logOut"
 276}
 277
 278func (LogOutConfig) params() (Params, error) {
 279	return nil, nil
 280}
 281
 282// CloseConfig is a request to close the bot instance on a local server.
 283//
 284// Note that you may not close an instance for the first 10 minutes after the
 285// bot has started.
 286type CloseConfig struct{}
 287
 288func (CloseConfig) method() string {
 289	return "close"
 290}
 291
 292func (CloseConfig) params() (Params, error) {
 293	return nil, nil
 294}
 295
 296// MessageConfig contains information about a SendMessage request.
 297type MessageConfig struct {
 298	BaseChat
 299	Text               string
 300	ParseMode          string
 301	Entities           []MessageEntity
 302	LinkPreviewOptions LinkPreviewOptions
 303}
 304
 305func (config MessageConfig) params() (Params, error) {
 306	params, err := config.BaseChat.params()
 307	if err != nil {
 308		return params, err
 309	}
 310
 311	params.AddNonEmpty("text", config.Text)
 312	params.AddNonEmpty("parse_mode", config.ParseMode)
 313	err = params.AddInterface("entities", config.Entities)
 314	if err != nil {
 315		return params, err
 316	}
 317	err = params.AddInterface("link_preview_options", config.LinkPreviewOptions)
 318
 319	return params, err
 320}
 321
 322func (config MessageConfig) method() string {
 323	return "sendMessage"
 324}
 325
 326// ForwardConfig contains information about a ForwardMessage request.
 327type ForwardConfig struct {
 328	BaseChat
 329	FromChat  ChatConfig
 330	MessageID int // required
 331}
 332
 333func (config ForwardConfig) params() (Params, error) {
 334	params, err := config.BaseChat.params()
 335	if err != nil {
 336		return params, err
 337	}
 338	p1, err := config.FromChat.paramsWithKey("from_chat_id")
 339	if err != nil {
 340		return params, err
 341	}
 342	params.Merge(p1)
 343	params.AddNonZero("message_id", config.MessageID)
 344
 345	return params, nil
 346}
 347
 348func (config ForwardConfig) method() string {
 349	return "forwardMessage"
 350}
 351
 352// ForwardMessagesConfig contains information about a ForwardMessages request.
 353type ForwardMessagesConfig struct {
 354	BaseChat
 355	FromChat   ChatConfig
 356	MessageIDs []int // required
 357}
 358
 359func (config ForwardMessagesConfig) params() (Params, error) {
 360	params, err := config.BaseChat.params()
 361	if err != nil {
 362		return params, err
 363	}
 364
 365	p1, err := config.FromChat.paramsWithKey("from_chat_id")
 366	if err != nil {
 367		return params, err
 368	}
 369	params.Merge(p1)
 370	err = params.AddInterface("message_ids", config.MessageIDs)
 371
 372	return params, err
 373}
 374
 375func (config ForwardMessagesConfig) method() string {
 376	return "forwardMessages"
 377}
 378
 379// CopyMessageConfig contains information about a copyMessage request.
 380type CopyMessageConfig struct {
 381	BaseChat
 382	FromChat              ChatConfig
 383	MessageID             int
 384	Caption               string
 385	ParseMode             string
 386	CaptionEntities       []MessageEntity
 387	ShowCaptionAboveMedia bool
 388}
 389
 390func (config CopyMessageConfig) params() (Params, error) {
 391	params, err := config.BaseChat.params()
 392	if err != nil {
 393		return params, err
 394	}
 395
 396	p1, err := config.FromChat.paramsWithKey("from_chat_id")
 397	if err != nil {
 398		return params, err
 399	}
 400	params.Merge(p1)
 401	params.AddNonZero("message_id", config.MessageID)
 402	params.AddNonEmpty("caption", config.Caption)
 403	params.AddNonEmpty("parse_mode", config.ParseMode)
 404	params.AddBool("show_caption_above_media", config.ShowCaptionAboveMedia)
 405	err = params.AddInterface("caption_entities", config.CaptionEntities)
 406
 407	return params, err
 408}
 409
 410func (config CopyMessageConfig) method() string {
 411	return "copyMessage"
 412}
 413
 414// CopyMessagesConfig contains information about a copyMessages request.
 415type CopyMessagesConfig struct {
 416	BaseChat
 417	FromChat      ChatConfig
 418	MessageIDs    []int
 419	RemoveCaption bool
 420}
 421
 422func (config CopyMessagesConfig) params() (Params, error) {
 423	params, err := config.BaseChat.params()
 424	if err != nil {
 425		return params, err
 426	}
 427
 428	p1, err := config.FromChat.paramsWithKey("from_chat_id")
 429	if err != nil {
 430		return params, err
 431	}
 432	params.Merge(p1)
 433	params.AddBool("remove_caption", config.RemoveCaption)
 434	err = params.AddInterface("message_ids", config.MessageIDs)
 435
 436	return params, err
 437}
 438
 439func (config CopyMessagesConfig) method() string {
 440	return "copyMessages"
 441}
 442
 443// PhotoConfig contains information about a SendPhoto request.
 444type PhotoConfig struct {
 445	BaseFile
 446	BaseSpoiler
 447	Thumb                 RequestFileData
 448	Caption               string
 449	ParseMode             string
 450	CaptionEntities       []MessageEntity
 451	ShowCaptionAboveMedia bool
 452}
 453
 454func (config PhotoConfig) params() (Params, error) {
 455	params, err := config.BaseFile.params()
 456	if err != nil {
 457		return params, err
 458	}
 459
 460	params.AddNonEmpty("caption", config.Caption)
 461	params.AddNonEmpty("parse_mode", config.ParseMode)
 462	params.AddBool("show_caption_above_media", config.ShowCaptionAboveMedia)
 463	err = params.AddInterface("caption_entities", config.CaptionEntities)
 464	if err != nil {
 465		return params, err
 466	}
 467
 468	p1, err := config.BaseSpoiler.params()
 469	if err != nil {
 470		return params, err
 471	}
 472	params.Merge(p1)
 473
 474	return params, err
 475}
 476
 477func (config PhotoConfig) method() string {
 478	return "sendPhoto"
 479}
 480
 481func (config PhotoConfig) files() []RequestFile {
 482	files := []RequestFile{{
 483		Name: "photo",
 484		Data: config.File,
 485	}}
 486
 487	if config.Thumb != nil {
 488		files = append(files, RequestFile{
 489			Name: "thumbnail",
 490			Data: config.Thumb,
 491		})
 492	}
 493
 494	return files
 495}
 496
 497// AudioConfig contains information about a SendAudio request.
 498type AudioConfig struct {
 499	BaseFile
 500	Thumb           RequestFileData
 501	Caption         string
 502	ParseMode       string
 503	CaptionEntities []MessageEntity
 504	Duration        int
 505	Performer       string
 506	Title           string
 507}
 508
 509func (config AudioConfig) params() (Params, error) {
 510	params, err := config.BaseChat.params()
 511	if err != nil {
 512		return params, err
 513	}
 514
 515	params.AddNonZero("duration", config.Duration)
 516	params.AddNonEmpty("performer", config.Performer)
 517	params.AddNonEmpty("title", config.Title)
 518	params.AddNonEmpty("caption", config.Caption)
 519	params.AddNonEmpty("parse_mode", config.ParseMode)
 520	err = params.AddInterface("caption_entities", config.CaptionEntities)
 521
 522	return params, err
 523}
 524
 525func (config AudioConfig) method() string {
 526	return "sendAudio"
 527}
 528
 529func (config AudioConfig) files() []RequestFile {
 530	files := []RequestFile{{
 531		Name: "audio",
 532		Data: config.File,
 533	}}
 534
 535	if config.Thumb != nil {
 536		files = append(files, RequestFile{
 537			Name: "thumbnail",
 538			Data: config.Thumb,
 539		})
 540	}
 541
 542	return files
 543}
 544
 545// DocumentConfig contains information about a SendDocument request.
 546type DocumentConfig struct {
 547	BaseFile
 548	Thumb                       RequestFileData
 549	Caption                     string
 550	ParseMode                   string
 551	CaptionEntities             []MessageEntity
 552	DisableContentTypeDetection bool
 553}
 554
 555func (config DocumentConfig) params() (Params, error) {
 556	params, err := config.BaseFile.params()
 557
 558	params.AddNonEmpty("caption", config.Caption)
 559	params.AddNonEmpty("parse_mode", config.ParseMode)
 560	params.AddBool("disable_content_type_detection", config.DisableContentTypeDetection)
 561
 562	return params, err
 563}
 564
 565func (config DocumentConfig) method() string {
 566	return "sendDocument"
 567}
 568
 569func (config DocumentConfig) files() []RequestFile {
 570	files := []RequestFile{{
 571		Name: "document",
 572		Data: config.File,
 573	}}
 574
 575	if config.Thumb != nil {
 576		files = append(files, RequestFile{
 577			Name: "thumbnail",
 578			Data: config.Thumb,
 579		})
 580	}
 581
 582	return files
 583}
 584
 585// StickerConfig contains information about a SendSticker request.
 586type StickerConfig struct {
 587	//Emoji associated with the sticker; only for just uploaded stickers
 588	Emoji string
 589	BaseFile
 590}
 591
 592func (config StickerConfig) params() (Params, error) {
 593	params, err := config.BaseChat.params()
 594	if err != nil {
 595		return params, err
 596	}
 597	params.AddNonEmpty("emoji", config.Emoji)
 598	return params, err
 599}
 600
 601func (config StickerConfig) method() string {
 602	return "sendSticker"
 603}
 604
 605func (config StickerConfig) files() []RequestFile {
 606	return []RequestFile{{
 607		Name: "sticker",
 608		Data: config.File,
 609	}}
 610}
 611
 612// VideoConfig contains information about a SendVideo request.
 613type VideoConfig struct {
 614	BaseFile
 615	BaseSpoiler
 616	Thumb                 RequestFileData
 617	Duration              int
 618	Caption               string
 619	ParseMode             string
 620	CaptionEntities       []MessageEntity
 621	ShowCaptionAboveMedia bool
 622	SupportsStreaming     bool
 623}
 624
 625func (config VideoConfig) params() (Params, error) {
 626	params, err := config.BaseChat.params()
 627	if err != nil {
 628		return params, err
 629	}
 630
 631	params.AddNonZero("duration", config.Duration)
 632	params.AddNonEmpty("caption", config.Caption)
 633	params.AddNonEmpty("parse_mode", config.ParseMode)
 634	params.AddBool("supports_streaming", config.SupportsStreaming)
 635	params.AddBool("show_caption_above_media", config.ShowCaptionAboveMedia)
 636	err = params.AddInterface("caption_entities", config.CaptionEntities)
 637	if err != nil {
 638		return params, err
 639	}
 640
 641	p1, err := config.BaseSpoiler.params()
 642	if err != nil {
 643		return params, err
 644	}
 645	params.Merge(p1)
 646
 647	return params, err
 648}
 649
 650func (config VideoConfig) method() string {
 651	return "sendVideo"
 652}
 653
 654func (config VideoConfig) files() []RequestFile {
 655	files := []RequestFile{{
 656		Name: "video",
 657		Data: config.File,
 658	}}
 659
 660	if config.Thumb != nil {
 661		files = append(files, RequestFile{
 662			Name: "thumbnail",
 663			Data: config.Thumb,
 664		})
 665	}
 666
 667	return files
 668}
 669
 670// AnimationConfig contains information about a SendAnimation request.
 671type AnimationConfig struct {
 672	BaseFile
 673	BaseSpoiler
 674	Duration              int
 675	Thumb                 RequestFileData
 676	Caption               string
 677	ParseMode             string
 678	CaptionEntities       []MessageEntity
 679	ShowCaptionAboveMedia bool
 680}
 681
 682func (config AnimationConfig) params() (Params, error) {
 683	params, err := config.BaseChat.params()
 684	if err != nil {
 685		return params, err
 686	}
 687
 688	params.AddNonZero("duration", config.Duration)
 689	params.AddNonEmpty("caption", config.Caption)
 690	params.AddNonEmpty("parse_mode", config.ParseMode)
 691	params.AddBool("show_caption_above_media", config.ShowCaptionAboveMedia)
 692	err = params.AddInterface("caption_entities", config.CaptionEntities)
 693	if err != nil {
 694		return params, err
 695	}
 696
 697	p1, err := config.BaseSpoiler.params()
 698	if err != nil {
 699		return params, err
 700	}
 701	params.Merge(p1)
 702
 703	return params, err
 704}
 705
 706func (config AnimationConfig) method() string {
 707	return "sendAnimation"
 708}
 709
 710func (config AnimationConfig) files() []RequestFile {
 711	files := []RequestFile{{
 712		Name: "animation",
 713		Data: config.File,
 714	}}
 715
 716	if config.Thumb != nil {
 717		files = append(files, RequestFile{
 718			Name: "thumbnail",
 719			Data: config.Thumb,
 720		})
 721	}
 722
 723	return files
 724}
 725
 726// VideoNoteConfig contains information about a SendVideoNote request.
 727type VideoNoteConfig struct {
 728	BaseFile
 729	Thumb    RequestFileData
 730	Duration int
 731	Length   int
 732}
 733
 734func (config VideoNoteConfig) params() (Params, error) {
 735	params, err := config.BaseChat.params()
 736
 737	params.AddNonZero("duration", config.Duration)
 738	params.AddNonZero("length", config.Length)
 739
 740	return params, err
 741}
 742
 743func (config VideoNoteConfig) method() string {
 744	return "sendVideoNote"
 745}
 746
 747func (config VideoNoteConfig) files() []RequestFile {
 748	files := []RequestFile{{
 749		Name: "video_note",
 750		Data: config.File,
 751	}}
 752
 753	if config.Thumb != nil {
 754		files = append(files, RequestFile{
 755			Name: "thumbnail",
 756			Data: config.Thumb,
 757		})
 758	}
 759
 760	return files
 761}
 762
 763// VoiceConfig contains information about a SendVoice request.
 764type VoiceConfig struct {
 765	BaseFile
 766	Thumb           RequestFileData
 767	Caption         string
 768	ParseMode       string
 769	CaptionEntities []MessageEntity
 770	Duration        int
 771}
 772
 773func (config VoiceConfig) params() (Params, error) {
 774	params, err := config.BaseChat.params()
 775	if err != nil {
 776		return params, err
 777	}
 778
 779	params.AddNonZero("duration", config.Duration)
 780	params.AddNonEmpty("caption", config.Caption)
 781	params.AddNonEmpty("parse_mode", config.ParseMode)
 782	err = params.AddInterface("caption_entities", config.CaptionEntities)
 783
 784	return params, err
 785}
 786
 787func (config VoiceConfig) method() string {
 788	return "sendVoice"
 789}
 790
 791func (config VoiceConfig) files() []RequestFile {
 792	files := []RequestFile{{
 793		Name: "voice",
 794		Data: config.File,
 795	}}
 796
 797	if config.Thumb != nil {
 798		files = append(files, RequestFile{
 799			Name: "thumbnail",
 800			Data: config.Thumb,
 801		})
 802	}
 803
 804	return files
 805}
 806
 807// LocationConfig contains information about a SendLocation request.
 808type LocationConfig struct {
 809	BaseChat
 810	Latitude             float64 // required
 811	Longitude            float64 // required
 812	HorizontalAccuracy   float64 // optional
 813	LivePeriod           int     // optional
 814	Heading              int     // optional
 815	ProximityAlertRadius int     // optional
 816}
 817
 818func (config LocationConfig) params() (Params, error) {
 819	params, err := config.BaseChat.params()
 820
 821	params.AddNonZeroFloat("latitude", config.Latitude)
 822	params.AddNonZeroFloat("longitude", config.Longitude)
 823	params.AddNonZeroFloat("horizontal_accuracy", config.HorizontalAccuracy)
 824	params.AddNonZero("live_period", config.LivePeriod)
 825	params.AddNonZero("heading", config.Heading)
 826	params.AddNonZero("proximity_alert_radius", config.ProximityAlertRadius)
 827
 828	return params, err
 829}
 830
 831func (config LocationConfig) method() string {
 832	return "sendLocation"
 833}
 834
 835// EditMessageLiveLocationConfig allows you to update a live location.
 836type EditMessageLiveLocationConfig struct {
 837	BaseEdit
 838	Latitude             float64 // required
 839	Longitude            float64 // required
 840	LivePeriod           int     //optional
 841	HorizontalAccuracy   float64 // optional
 842	Heading              int     // optional
 843	ProximityAlertRadius int     // optional
 844}
 845
 846func (config EditMessageLiveLocationConfig) params() (Params, error) {
 847	params, err := config.BaseEdit.params()
 848
 849	params.AddNonZeroFloat("latitude", config.Latitude)
 850	params.AddNonZeroFloat("longitude", config.Longitude)
 851	params.AddNonZeroFloat("horizontal_accuracy", config.HorizontalAccuracy)
 852	params.AddNonZero("heading", config.Heading)
 853	params.AddNonZero("live_period", config.LivePeriod)
 854	params.AddNonZero("proximity_alert_radius", config.ProximityAlertRadius)
 855
 856	return params, err
 857}
 858
 859func (config EditMessageLiveLocationConfig) method() string {
 860	return "editMessageLiveLocation"
 861}
 862
 863// StopMessageLiveLocationConfig stops updating a live location.
 864type StopMessageLiveLocationConfig struct {
 865	BaseEdit
 866}
 867
 868func (config StopMessageLiveLocationConfig) params() (Params, error) {
 869	return config.BaseEdit.params()
 870}
 871
 872func (config StopMessageLiveLocationConfig) method() string {
 873	return "stopMessageLiveLocation"
 874}
 875
 876// VenueConfig contains information about a SendVenue request.
 877type VenueConfig struct {
 878	BaseChat
 879	Latitude        float64 // required
 880	Longitude       float64 // required
 881	Title           string  // required
 882	Address         string  // required
 883	FoursquareID    string
 884	FoursquareType  string
 885	GooglePlaceID   string
 886	GooglePlaceType string
 887}
 888
 889func (config VenueConfig) params() (Params, error) {
 890	params, err := config.BaseChat.params()
 891
 892	params.AddNonZeroFloat("latitude", config.Latitude)
 893	params.AddNonZeroFloat("longitude", config.Longitude)
 894	params["title"] = config.Title
 895	params["address"] = config.Address
 896	params.AddNonEmpty("foursquare_id", config.FoursquareID)
 897	params.AddNonEmpty("foursquare_type", config.FoursquareType)
 898	params.AddNonEmpty("google_place_id", config.GooglePlaceID)
 899	params.AddNonEmpty("google_place_type", config.GooglePlaceType)
 900
 901	return params, err
 902}
 903
 904func (config VenueConfig) method() string {
 905	return "sendVenue"
 906}
 907
 908// ContactConfig allows you to send a contact.
 909type ContactConfig struct {
 910	BaseChat
 911	PhoneNumber string
 912	FirstName   string
 913	LastName    string
 914	VCard       string
 915}
 916
 917func (config ContactConfig) params() (Params, error) {
 918	params, err := config.BaseChat.params()
 919
 920	params["phone_number"] = config.PhoneNumber
 921	params["first_name"] = config.FirstName
 922
 923	params.AddNonEmpty("last_name", config.LastName)
 924	params.AddNonEmpty("vcard", config.VCard)
 925
 926	return params, err
 927}
 928
 929func (config ContactConfig) method() string {
 930	return "sendContact"
 931}
 932
 933// SendPollConfig allows you to send a poll.
 934type SendPollConfig struct {
 935	BaseChat
 936	Question              string
 937	QuestionParseMode     string          // optional
 938	QuestionEntities      []MessageEntity // optional
 939	Options               []InputPollOption
 940	IsAnonymous           bool
 941	Type                  string
 942	AllowsMultipleAnswers bool
 943	CorrectOptionID       int64
 944	Explanation           string
 945	ExplanationParseMode  string
 946	ExplanationEntities   []MessageEntity
 947	OpenPeriod            int
 948	CloseDate             int
 949	IsClosed              bool
 950}
 951
 952func (config SendPollConfig) params() (Params, error) {
 953	params, err := config.BaseChat.params()
 954	if err != nil {
 955		return params, err
 956	}
 957
 958	params["question"] = config.Question
 959	params.AddNonEmpty("question_parse_mode", config.QuestionParseMode)
 960	if err = params.AddInterface("question_entities", config.QuestionEntities); err != nil {
 961		return params, err
 962	}
 963	if err = params.AddInterface("options", config.Options); err != nil {
 964		return params, err
 965	}
 966	params["is_anonymous"] = strconv.FormatBool(config.IsAnonymous)
 967	params.AddNonEmpty("type", config.Type)
 968	params["allows_multiple_answers"] = strconv.FormatBool(config.AllowsMultipleAnswers)
 969	params["correct_option_id"] = strconv.FormatInt(config.CorrectOptionID, 10)
 970	params.AddBool("is_closed", config.IsClosed)
 971	params.AddNonEmpty("explanation", config.Explanation)
 972	params.AddNonEmpty("explanation_parse_mode", config.ExplanationParseMode)
 973	params.AddNonZero("open_period", config.OpenPeriod)
 974	params.AddNonZero("close_date", config.CloseDate)
 975	err = params.AddInterface("explanation_entities", config.ExplanationEntities)
 976
 977	return params, err
 978}
 979
 980func (SendPollConfig) method() string {
 981	return "sendPoll"
 982}
 983
 984// GameConfig allows you to send a game.
 985type GameConfig struct {
 986	BaseChat
 987	GameShortName string
 988}
 989
 990func (config GameConfig) params() (Params, error) {
 991	params, err := config.BaseChat.params()
 992
 993	params["game_short_name"] = config.GameShortName
 994
 995	return params, err
 996}
 997
 998func (config GameConfig) method() string {
 999	return "sendGame"
1000}
1001
1002// SetGameScoreConfig allows you to update the game score in a chat.
1003type SetGameScoreConfig struct {
1004	BaseChatMessage
1005
1006	UserID             int64
1007	Score              int
1008	Force              bool
1009	DisableEditMessage bool
1010	InlineMessageID    string
1011}
1012
1013func (config SetGameScoreConfig) params() (Params, error) {
1014	params := make(Params)
1015
1016	params.AddNonZero64("user_id", config.UserID)
1017	params.AddNonZero("scrore", config.Score)
1018	params.AddBool("disable_edit_message", config.DisableEditMessage)
1019
1020	if config.InlineMessageID != "" {
1021		params["inline_message_id"] = config.InlineMessageID
1022	} else {
1023		p1, err := config.BaseChatMessage.params()
1024		if err != nil {
1025			return params, err
1026		}
1027		params.Merge(p1)
1028	}
1029
1030	return params, nil
1031}
1032
1033func (config SetGameScoreConfig) method() string {
1034	return "setGameScore"
1035}
1036
1037// GetGameHighScoresConfig allows you to fetch the high scores for a game.
1038type GetGameHighScoresConfig struct {
1039	BaseChatMessage
1040
1041	UserID          int64
1042	InlineMessageID string
1043}
1044
1045func (config GetGameHighScoresConfig) params() (Params, error) {
1046	params := make(Params)
1047
1048	params.AddNonZero64("user_id", config.UserID)
1049
1050	if config.InlineMessageID != "" {
1051		params["inline_message_id"] = config.InlineMessageID
1052	} else {
1053		p1, err := config.BaseChatMessage.params()
1054		if err != nil {
1055			return params, err
1056		}
1057		params.Merge(p1)
1058	}
1059
1060	return params, nil
1061}
1062
1063func (config GetGameHighScoresConfig) method() string {
1064	return "getGameHighScores"
1065}
1066
1067// ChatActionConfig contains information about a SendChatAction request.
1068type ChatActionConfig struct {
1069	BaseChat
1070	MessageThreadID int
1071	Action          string // required
1072}
1073
1074func (config ChatActionConfig) params() (Params, error) {
1075	params, err := config.BaseChat.params()
1076
1077	params["action"] = config.Action
1078	params.AddNonZero("message_thread_id", config.MessageThreadID)
1079
1080	return params, err
1081}
1082
1083func (config ChatActionConfig) method() string {
1084	return "sendChatAction"
1085}
1086
1087// EditMessageTextConfig allows you to modify the text in a message.
1088type EditMessageTextConfig struct {
1089	BaseEdit
1090	Text               string
1091	ParseMode          string
1092	Entities           []MessageEntity
1093	LinkPreviewOptions LinkPreviewOptions
1094}
1095
1096func (config EditMessageTextConfig) params() (Params, error) {
1097	params, err := config.BaseEdit.params()
1098	if err != nil {
1099		return params, err
1100	}
1101
1102	params["text"] = config.Text
1103	params.AddNonEmpty("parse_mode", config.ParseMode)
1104	err = params.AddInterface("entities", config.Entities)
1105	if err != nil {
1106		return params, err
1107	}
1108	err = params.AddInterface("link_preview_options", config.LinkPreviewOptions)
1109
1110	return params, err
1111}
1112
1113func (config EditMessageTextConfig) method() string {
1114	return "editMessageText"
1115}
1116
1117// EditMessageCaptionConfig allows you to modify the caption of a message.
1118type EditMessageCaptionConfig struct {
1119	BaseEdit
1120	Caption               string
1121	ParseMode             string
1122	CaptionEntities       []MessageEntity
1123	ShowCaptionAboveMedia bool
1124}
1125
1126func (config EditMessageCaptionConfig) params() (Params, error) {
1127	params, err := config.BaseEdit.params()
1128	if err != nil {
1129		return params, err
1130	}
1131
1132	params["caption"] = config.Caption
1133	params.AddNonEmpty("parse_mode", config.ParseMode)
1134	params.AddBool("show_caption_above_media", config.ShowCaptionAboveMedia)
1135	err = params.AddInterface("caption_entities", config.CaptionEntities)
1136
1137	return params, err
1138}
1139
1140func (config EditMessageCaptionConfig) method() string {
1141	return "editMessageCaption"
1142}
1143
1144// EditMessageMediaConfig allows you to make an editMessageMedia request.
1145type EditMessageMediaConfig struct {
1146	BaseEdit
1147
1148	Media interface{}
1149}
1150
1151func (EditMessageMediaConfig) method() string {
1152	return "editMessageMedia"
1153}
1154
1155func (config EditMessageMediaConfig) params() (Params, error) {
1156	params, err := config.BaseEdit.params()
1157	if err != nil {
1158		return params, err
1159	}
1160
1161	err = params.AddInterface("media", prepareInputMediaParam(config.Media, 0))
1162
1163	return params, err
1164}
1165
1166func (config EditMessageMediaConfig) files() []RequestFile {
1167	return prepareInputMediaFile(config.Media, 0)
1168}
1169
1170// EditMessageReplyMarkupConfig allows you to modify the reply markup
1171// of a message.
1172type EditMessageReplyMarkupConfig struct {
1173	BaseEdit
1174}
1175
1176func (config EditMessageReplyMarkupConfig) params() (Params, error) {
1177	return config.BaseEdit.params()
1178}
1179
1180func (config EditMessageReplyMarkupConfig) method() string {
1181	return "editMessageReplyMarkup"
1182}
1183
1184// StopPollConfig allows you to stop a poll sent by the bot.
1185type StopPollConfig struct {
1186	BaseEdit
1187}
1188
1189func (config StopPollConfig) params() (Params, error) {
1190	return config.BaseEdit.params()
1191}
1192
1193func (StopPollConfig) method() string {
1194	return "stopPoll"
1195}
1196
1197// SetMessageReactionConfig changes reactions on a message. Returns true on success.
1198type SetMessageReactionConfig struct {
1199	BaseChatMessage
1200	Reaction []ReactionType
1201	IsBig    bool
1202}
1203
1204func (config SetMessageReactionConfig) params() (Params, error) {
1205	params, err := config.BaseChatMessage.params()
1206	if err != nil {
1207		return params, err
1208	}
1209	params.AddBool("is_big", config.IsBig)
1210	err = params.AddInterface("reaction", config.Reaction)
1211
1212	return params, err
1213}
1214
1215func (SetMessageReactionConfig) method() string {
1216	return "setMessageReaction"
1217}
1218
1219// UserProfilePhotosConfig contains information about a
1220// GetUserProfilePhotos request.
1221type UserProfilePhotosConfig struct {
1222	UserID int64
1223	Offset int
1224	Limit  int
1225}
1226
1227func (UserProfilePhotosConfig) method() string {
1228	return "getUserProfilePhotos"
1229}
1230
1231func (config UserProfilePhotosConfig) params() (Params, error) {
1232	params := make(Params)
1233
1234	params.AddNonZero64("user_id", config.UserID)
1235	params.AddNonZero("offset", config.Offset)
1236	params.AddNonZero("limit", config.Limit)
1237
1238	return params, nil
1239}
1240
1241// FileConfig has information about a file hosted on Telegram.
1242type FileConfig struct {
1243	FileID string
1244}
1245
1246func (FileConfig) method() string {
1247	return "getFile"
1248}
1249
1250func (config FileConfig) params() (Params, error) {
1251	params := make(Params)
1252
1253	params["file_id"] = config.FileID
1254
1255	return params, nil
1256}
1257
1258// UpdateConfig contains information about a GetUpdates request.
1259type UpdateConfig struct {
1260	Offset         int
1261	Limit          int
1262	Timeout        int
1263	AllowedUpdates []string
1264}
1265
1266func (UpdateConfig) method() string {
1267	return "getUpdates"
1268}
1269
1270func (config UpdateConfig) params() (Params, error) {
1271	params := make(Params)
1272
1273	params.AddNonZero("offset", config.Offset)
1274	params.AddNonZero("limit", config.Limit)
1275	params.AddNonZero("timeout", config.Timeout)
1276	params.AddInterface("allowed_updates", config.AllowedUpdates)
1277
1278	return params, nil
1279}
1280
1281// WebhookConfig contains information about a SetWebhook request.
1282type WebhookConfig struct {
1283	URL                *url.URL
1284	Certificate        RequestFileData
1285	IPAddress          string
1286	MaxConnections     int
1287	AllowedUpdates     []string
1288	DropPendingUpdates bool
1289	SecretToken        string
1290}
1291
1292func (config WebhookConfig) method() string {
1293	return "setWebhook"
1294}
1295
1296func (config WebhookConfig) params() (Params, error) {
1297	params := make(Params)
1298
1299	if config.URL != nil {
1300		params["url"] = config.URL.String()
1301	}
1302
1303	params.AddNonEmpty("ip_address", config.IPAddress)
1304	params.AddNonZero("max_connections", config.MaxConnections)
1305	err := params.AddInterface("allowed_updates", config.AllowedUpdates)
1306	params.AddBool("drop_pending_updates", config.DropPendingUpdates)
1307	params.AddNonEmpty("secret_token", config.SecretToken)
1308
1309	return params, err
1310}
1311
1312func (config WebhookConfig) files() []RequestFile {
1313	if config.Certificate != nil {
1314		return []RequestFile{{
1315			Name: "certificate",
1316			Data: config.Certificate,
1317		}}
1318	}
1319
1320	return nil
1321}
1322
1323// DeleteWebhookConfig is a helper to delete a webhook.
1324type DeleteWebhookConfig struct {
1325	DropPendingUpdates bool
1326}
1327
1328func (config DeleteWebhookConfig) method() string {
1329	return "deleteWebhook"
1330}
1331
1332func (config DeleteWebhookConfig) params() (Params, error) {
1333	params := make(Params)
1334
1335	params.AddBool("drop_pending_updates", config.DropPendingUpdates)
1336
1337	return params, nil
1338}
1339
1340// InlineQueryResultsButton represents a button to be shown above inline query results. You must use exactly one of the optional fields.
1341type InlineQueryResultsButton struct {
1342	//Label text on the button
1343	Text string `json:"text"`
1344	//Description of the Web App that will be launched when the user presses the button. The Web App will be able to switch back to the inline mode using the method switchInlineQuery inside the Web App.
1345	//
1346	//Optional
1347	WebApp *WebAppInfo `json:"web_app,omitempty"`
1348	// Deep-linking parameter for the /start message sent to the bot when a user presses the button. 1-64 characters, only A-Z, a-z, 0-9, _ and - are allowed.
1349	//
1350	//Optional
1351	StartParam string `json:"start_parameter,omitempty"`
1352}
1353
1354// InlineConfig contains information on making an InlineQuery response.
1355type InlineConfig struct {
1356	InlineQueryID string                    `json:"inline_query_id"`
1357	Results       []interface{}             `json:"results"`
1358	CacheTime     int                       `json:"cache_time"`
1359	IsPersonal    bool                      `json:"is_personal"`
1360	NextOffset    string                    `json:"next_offset"`
1361	Button        *InlineQueryResultsButton `json:"button,omitempty"`
1362}
1363
1364func (config InlineConfig) method() string {
1365	return "answerInlineQuery"
1366}
1367
1368func (config InlineConfig) params() (Params, error) {
1369	params := make(Params)
1370
1371	params["inline_query_id"] = config.InlineQueryID
1372	params.AddNonZero("cache_time", config.CacheTime)
1373	params.AddBool("is_personal", config.IsPersonal)
1374	params.AddNonEmpty("next_offset", config.NextOffset)
1375	err := params.AddInterface("button", config.Button)
1376	if err != nil {
1377		return params, err
1378	}
1379	err = params.AddInterface("results", config.Results)
1380
1381	return params, err
1382}
1383
1384// AnswerWebAppQueryConfig is used to set the result of an interaction with a
1385// Web App and send a corresponding message on behalf of the user to the chat
1386// from which the query originated.
1387type AnswerWebAppQueryConfig struct {
1388	// WebAppQueryID is the unique identifier for the query to be answered.
1389	WebAppQueryID string `json:"web_app_query_id"`
1390	// Result is an InlineQueryResult object describing the message to be sent.
1391	Result interface{} `json:"result"`
1392}
1393
1394func (config AnswerWebAppQueryConfig) method() string {
1395	return "answerWebAppQuery"
1396}
1397
1398func (config AnswerWebAppQueryConfig) params() (Params, error) {
1399	params := make(Params)
1400
1401	params["web_app_query_id"] = config.WebAppQueryID
1402	err := params.AddInterface("result", config.Result)
1403
1404	return params, err
1405}
1406
1407// CallbackConfig contains information on making a CallbackQuery response.
1408type CallbackConfig struct {
1409	CallbackQueryID string `json:"callback_query_id"`
1410	Text            string `json:"text"`
1411	ShowAlert       bool   `json:"show_alert"`
1412	URL             string `json:"url"`
1413	CacheTime       int    `json:"cache_time"`
1414}
1415
1416func (config CallbackConfig) method() string {
1417	return "answerCallbackQuery"
1418}
1419
1420func (config CallbackConfig) params() (Params, error) {
1421	params := make(Params)
1422
1423	params["callback_query_id"] = config.CallbackQueryID
1424	params.AddNonEmpty("text", config.Text)
1425	params.AddBool("show_alert", config.ShowAlert)
1426	params.AddNonEmpty("url", config.URL)
1427	params.AddNonZero("cache_time", config.CacheTime)
1428
1429	return params, nil
1430}
1431
1432// ChatMemberConfig contains information about a user in a chat for use
1433// with administrative functions such as kicking or unbanning a user.
1434type ChatMemberConfig struct {
1435	ChatConfig
1436	UserID int64
1437}
1438
1439func (config ChatMemberConfig) params() (Params, error) {
1440	params, err := config.ChatConfig.params()
1441	if err != nil {
1442		return params, err
1443	}
1444	params.AddNonZero64("user_id", config.UserID)
1445	return params, nil
1446}
1447
1448// UnbanChatMemberConfig allows you to unban a user.
1449type UnbanChatMemberConfig struct {
1450	ChatMemberConfig
1451	OnlyIfBanned bool
1452}
1453
1454func (config UnbanChatMemberConfig) method() string {
1455	return "unbanChatMember"
1456}
1457
1458func (config UnbanChatMemberConfig) params() (Params, error) {
1459	params, err := config.ChatMemberConfig.params()
1460	if err != nil {
1461		return params, err
1462	}
1463
1464	params.AddBool("only_if_banned", config.OnlyIfBanned)
1465
1466	return params, nil
1467}
1468
1469// BanChatMemberConfig contains extra fields to kick user.
1470type BanChatMemberConfig struct {
1471	ChatMemberConfig
1472	UntilDate      int64
1473	RevokeMessages bool
1474}
1475
1476func (config BanChatMemberConfig) method() string {
1477	return "banChatMember"
1478}
1479
1480func (config BanChatMemberConfig) params() (Params, error) {
1481	params, err := config.ChatMemberConfig.params()
1482	if err != nil {
1483		return params, err
1484	}
1485
1486	params.AddNonZero64("until_date", config.UntilDate)
1487	params.AddBool("revoke_messages", config.RevokeMessages)
1488
1489	return params, nil
1490}
1491
1492// KickChatMemberConfig contains extra fields to ban user.
1493//
1494// This was renamed to BanChatMember in later versions of the Telegram Bot API.
1495type KickChatMemberConfig = BanChatMemberConfig
1496
1497// RestrictChatMemberConfig contains fields to restrict members of chat
1498type RestrictChatMemberConfig struct {
1499	ChatMemberConfig
1500	UntilDate                     int64
1501	UseIndependentChatPermissions bool
1502	Permissions                   *ChatPermissions
1503}
1504
1505func (config RestrictChatMemberConfig) method() string {
1506	return "restrictChatMember"
1507}
1508
1509func (config RestrictChatMemberConfig) params() (Params, error) {
1510	params, err := config.ChatMemberConfig.params()
1511	if err != nil {
1512		return params, err
1513	}
1514
1515	params.AddBool("use_independent_chat_permissions", config.UseIndependentChatPermissions)
1516	params.AddNonZero64("until_date", config.UntilDate)
1517	err = params.AddInterface("permissions", config.Permissions)
1518
1519	return params, err
1520}
1521
1522// PromoteChatMemberConfig contains fields to promote members of chat
1523type PromoteChatMemberConfig struct {
1524	ChatMemberConfig
1525	IsAnonymous         bool
1526	CanManageChat       bool
1527	CanChangeInfo       bool
1528	CanPostMessages     bool
1529	CanEditMessages     bool
1530	CanDeleteMessages   bool
1531	CanManageVideoChats bool
1532	CanInviteUsers      bool
1533	CanRestrictMembers  bool
1534	CanPinMessages      bool
1535	CanPromoteMembers   bool
1536	CanPostStories      bool
1537	CanEditStories      bool
1538	CanDeleteStories    bool
1539	CanManageTopics     bool
1540}
1541
1542func (config PromoteChatMemberConfig) method() string {
1543	return "promoteChatMember"
1544}
1545
1546func (config PromoteChatMemberConfig) params() (Params, error) {
1547	params, err := config.ChatMemberConfig.params()
1548	if err != nil {
1549		return params, err
1550	}
1551
1552	params.AddBool("is_anonymous", config.IsAnonymous)
1553	params.AddBool("can_manage_chat", config.CanManageChat)
1554	params.AddBool("can_change_info", config.CanChangeInfo)
1555	params.AddBool("can_post_messages", config.CanPostMessages)
1556	params.AddBool("can_edit_messages", config.CanEditMessages)
1557	params.AddBool("can_delete_messages", config.CanDeleteMessages)
1558	params.AddBool("can_manage_video_chats", config.CanManageVideoChats)
1559	params.AddBool("can_invite_users", config.CanInviteUsers)
1560	params.AddBool("can_restrict_members", config.CanRestrictMembers)
1561	params.AddBool("can_pin_messages", config.CanPinMessages)
1562	params.AddBool("can_promote_members", config.CanPromoteMembers)
1563	params.AddBool("can_post_stories", config.CanPostStories)
1564	params.AddBool("can_edit_stories", config.CanEditStories)
1565	params.AddBool("can_delete_stories", config.CanDeleteStories)
1566	params.AddBool("can_manage_topics", config.CanManageTopics)
1567
1568	return params, nil
1569}
1570
1571// SetChatAdministratorCustomTitle sets the title of an administrative user
1572// promoted by the bot for a chat.
1573type SetChatAdministratorCustomTitle struct {
1574	ChatMemberConfig
1575	CustomTitle string
1576}
1577
1578func (SetChatAdministratorCustomTitle) method() string {
1579	return "setChatAdministratorCustomTitle"
1580}
1581
1582func (config SetChatAdministratorCustomTitle) params() (Params, error) {
1583	params, err := config.ChatMemberConfig.params()
1584	if err != nil {
1585		return params, err
1586	}
1587	params.AddNonEmpty("custom_title", config.CustomTitle)
1588
1589	return params, nil
1590}
1591
1592// BanChatSenderChatConfig bans a channel chat in a supergroup or a channel. The
1593// owner of the chat will not be able to send messages and join live streams on
1594// behalf of the chat, unless it is unbanned first. The bot must be an
1595// administrator in the supergroup or channel for this to work and must have the
1596// appropriate administrator rights.
1597type BanChatSenderChatConfig struct {
1598	ChatConfig
1599	SenderChatID int64
1600	UntilDate    int
1601}
1602
1603func (config BanChatSenderChatConfig) method() string {
1604	return "banChatSenderChat"
1605}
1606
1607func (config BanChatSenderChatConfig) params() (Params, error) {
1608	params, err := config.ChatConfig.params()
1609	if err != nil {
1610		return params, err
1611	}
1612	params.AddNonZero64("sender_chat_id", config.SenderChatID)
1613	params.AddNonZero("until_date", config.UntilDate)
1614
1615	return params, nil
1616}
1617
1618// UnbanChatSenderChatConfig unbans a previously banned channel chat in a
1619// supergroup or channel. The bot must be an administrator for this to work and
1620// must have the appropriate administrator rights.
1621type UnbanChatSenderChatConfig struct {
1622	ChatConfig
1623	SenderChatID int64
1624}
1625
1626func (config UnbanChatSenderChatConfig) method() string {
1627	return "unbanChatSenderChat"
1628}
1629
1630func (config UnbanChatSenderChatConfig) params() (Params, error) {
1631	params, err := config.ChatConfig.params()
1632	if err != nil {
1633		return params, err
1634	}
1635	params.AddNonZero64("sender_chat_id", config.SenderChatID)
1636
1637	return params, nil
1638}
1639
1640// ChatInfoConfig contains information about getting chat information.
1641type ChatInfoConfig struct {
1642	ChatConfig
1643}
1644
1645func (ChatInfoConfig) method() string {
1646	return "getChat"
1647}
1648
1649// ChatMemberCountConfig contains information about getting the number of users in a chat.
1650type ChatMemberCountConfig struct {
1651	ChatConfig
1652}
1653
1654func (ChatMemberCountConfig) method() string {
1655	return "getChatMembersCount"
1656}
1657
1658// ChatAdministratorsConfig contains information about getting chat administrators.
1659type ChatAdministratorsConfig struct {
1660	ChatConfig
1661}
1662
1663func (ChatAdministratorsConfig) method() string {
1664	return "getChatAdministrators"
1665}
1666
1667// SetChatPermissionsConfig allows you to set default permissions for the
1668// members in a group. The bot must be an administrator and have rights to
1669// restrict members.
1670type SetChatPermissionsConfig struct {
1671	ChatConfig
1672	UseIndependentChatPermissions bool
1673	Permissions                   *ChatPermissions
1674}
1675
1676func (SetChatPermissionsConfig) method() string {
1677	return "setChatPermissions"
1678}
1679
1680func (config SetChatPermissionsConfig) params() (Params, error) {
1681	params, err := config.ChatConfig.params()
1682	if err != nil {
1683		return params, err
1684	}
1685
1686	params.AddBool("use_independent_chat_permissions", config.UseIndependentChatPermissions)
1687	err = params.AddInterface("permissions", config.Permissions)
1688
1689	return params, err
1690}
1691
1692// ChatInviteLinkConfig contains information about getting a chat link.
1693//
1694// Note that generating a new link will revoke any previous links.
1695type ChatInviteLinkConfig struct {
1696	ChatConfig
1697}
1698
1699func (ChatInviteLinkConfig) method() string {
1700	return "exportChatInviteLink"
1701}
1702
1703func (config ChatInviteLinkConfig) params() (Params, error) {
1704	return config.ChatConfig.params()
1705}
1706
1707// CreateChatInviteLinkConfig allows you to create an additional invite link for
1708// a chat. The bot must be an administrator in the chat for this to work and
1709// must have the appropriate admin rights. The link can be revoked using the
1710// RevokeChatInviteLinkConfig.
1711type CreateChatInviteLinkConfig struct {
1712	ChatConfig
1713	Name               string
1714	ExpireDate         int
1715	MemberLimit        int
1716	CreatesJoinRequest bool
1717}
1718
1719func (CreateChatInviteLinkConfig) method() string {
1720	return "createChatInviteLink"
1721}
1722
1723func (config CreateChatInviteLinkConfig) params() (Params, error) {
1724	params, err := config.ChatConfig.params()
1725	if err != nil {
1726		return params, err
1727	}
1728
1729	params.AddNonEmpty("name", config.Name)
1730	params.AddNonZero("expire_date", config.ExpireDate)
1731	params.AddNonZero("member_limit", config.MemberLimit)
1732	params.AddBool("creates_join_request", config.CreatesJoinRequest)
1733
1734	return params, nil
1735}
1736
1737// EditChatInviteLinkConfig allows you to edit a non-primary invite link created
1738// by the bot. The bot must be an administrator in the chat for this to work and
1739// must have the appropriate admin rights.
1740type EditChatInviteLinkConfig struct {
1741	ChatConfig
1742	InviteLink         string
1743	Name               string
1744	ExpireDate         int
1745	MemberLimit        int
1746	CreatesJoinRequest bool
1747}
1748
1749func (EditChatInviteLinkConfig) method() string {
1750	return "editChatInviteLink"
1751}
1752
1753func (config EditChatInviteLinkConfig) params() (Params, error) {
1754	params, err := config.ChatConfig.params()
1755	if err != nil {
1756		return params, err
1757	}
1758
1759	params.AddNonEmpty("name", config.Name)
1760	params["invite_link"] = config.InviteLink
1761	params.AddNonZero("expire_date", config.ExpireDate)
1762	params.AddNonZero("member_limit", config.MemberLimit)
1763	params.AddBool("creates_join_request", config.CreatesJoinRequest)
1764
1765	return params, nil
1766}
1767
1768// RevokeChatInviteLinkConfig allows you to revoke an invite link created by the
1769// bot. If the primary link is revoked, a new link is automatically generated.
1770// The bot must be an administrator in the chat for this to work and must have
1771// the appropriate admin rights.
1772type RevokeChatInviteLinkConfig struct {
1773	ChatConfig
1774	InviteLink string
1775}
1776
1777func (RevokeChatInviteLinkConfig) method() string {
1778	return "revokeChatInviteLink"
1779}
1780
1781func (config RevokeChatInviteLinkConfig) params() (Params, error) {
1782	params, err := config.ChatConfig.params()
1783	if err != nil {
1784		return params, err
1785	}
1786
1787	params["invite_link"] = config.InviteLink
1788
1789	return params, nil
1790}
1791
1792// ApproveChatJoinRequestConfig allows you to approve a chat join request.
1793type ApproveChatJoinRequestConfig struct {
1794	ChatConfig
1795	UserID int64
1796}
1797
1798func (ApproveChatJoinRequestConfig) method() string {
1799	return "approveChatJoinRequest"
1800}
1801
1802func (config ApproveChatJoinRequestConfig) params() (Params, error) {
1803	params, err := config.ChatConfig.params()
1804	if err != nil {
1805		return params, err
1806	}
1807
1808	params.AddNonZero64("user_id", config.UserID)
1809
1810	return params, nil
1811}
1812
1813// DeclineChatJoinRequest allows you to decline a chat join request.
1814type DeclineChatJoinRequest struct {
1815	ChatConfig
1816	UserID int64
1817}
1818
1819func (DeclineChatJoinRequest) method() string {
1820	return "declineChatJoinRequest"
1821}
1822
1823func (config DeclineChatJoinRequest) params() (Params, error) {
1824	params, err := config.ChatConfig.params()
1825	if err != nil {
1826		return params, err
1827	}
1828	params.AddNonZero64("user_id", config.UserID)
1829
1830	return params, nil
1831}
1832
1833// LeaveChatConfig allows you to leave a chat.
1834type LeaveChatConfig struct {
1835	ChatConfig
1836}
1837
1838func (config LeaveChatConfig) method() string {
1839	return "leaveChat"
1840}
1841
1842func (config LeaveChatConfig) params() (Params, error) {
1843	return config.ChatConfig.params()
1844}
1845
1846// ChatConfigWithUser contains information about a chat and a user.
1847type ChatConfigWithUser struct {
1848	ChatConfig
1849	UserID int64
1850}
1851
1852func (config ChatConfigWithUser) params() (Params, error) {
1853	params, err := config.ChatConfig.params()
1854	if err != nil {
1855		return params, err
1856	}
1857
1858	params.AddNonZero64("user_id", config.UserID)
1859
1860	return params, nil
1861}
1862
1863// GetChatMemberConfig is information about getting a specific member in a chat.
1864type GetChatMemberConfig struct {
1865	ChatConfigWithUser
1866}
1867
1868func (GetChatMemberConfig) method() string {
1869	return "getChatMember"
1870}
1871
1872// InvoiceConfig contains information for sendInvoice request.
1873type InvoiceConfig struct {
1874	BaseChat
1875	Title                     string         // required
1876	Description               string         // required
1877	Payload                   string         // required
1878	ProviderToken             string         // required
1879	Currency                  string         // required
1880	Prices                    []LabeledPrice // required
1881	MaxTipAmount              int
1882	SuggestedTipAmounts       []int
1883	StartParameter            string
1884	ProviderData              string
1885	PhotoURL                  string
1886	PhotoSize                 int
1887	PhotoWidth                int
1888	PhotoHeight               int
1889	NeedName                  bool
1890	NeedPhoneNumber           bool
1891	NeedEmail                 bool
1892	NeedShippingAddress       bool
1893	SendPhoneNumberToProvider bool
1894	SendEmailToProvider       bool
1895	IsFlexible                bool
1896}
1897
1898func (config InvoiceConfig) params() (Params, error) {
1899	params, err := config.BaseChat.params()
1900	if err != nil {
1901		return params, err
1902	}
1903
1904	params["title"] = config.Title
1905	params["description"] = config.Description
1906	params["payload"] = config.Payload
1907	params["currency"] = config.Currency
1908	if err = params.AddInterface("prices", config.Prices); err != nil {
1909		return params, err
1910	}
1911
1912	params.AddNonEmpty("provider_token", config.ProviderToken)
1913	params.AddNonZero("max_tip_amount", config.MaxTipAmount)
1914	err = params.AddInterface("suggested_tip_amounts", config.SuggestedTipAmounts)
1915	params.AddNonEmpty("start_parameter", config.StartParameter)
1916	params.AddNonEmpty("provider_data", config.ProviderData)
1917	params.AddNonEmpty("photo_url", config.PhotoURL)
1918	params.AddNonZero("photo_size", config.PhotoSize)
1919	params.AddNonZero("photo_width", config.PhotoWidth)
1920	params.AddNonZero("photo_height", config.PhotoHeight)
1921	params.AddBool("need_name", config.NeedName)
1922	params.AddBool("need_phone_number", config.NeedPhoneNumber)
1923	params.AddBool("need_email", config.NeedEmail)
1924	params.AddBool("need_shipping_address", config.NeedShippingAddress)
1925	params.AddBool("is_flexible", config.IsFlexible)
1926	params.AddBool("send_phone_number_to_provider", config.SendPhoneNumberToProvider)
1927	params.AddBool("send_email_to_provider", config.SendEmailToProvider)
1928
1929	return params, err
1930}
1931
1932func (config InvoiceConfig) method() string {
1933	return "sendInvoice"
1934}
1935
1936// InvoiceLinkConfig contains information for createInvoiceLink method
1937type InvoiceLinkConfig struct {
1938	Title                     string         //Required
1939	Description               string         //Required
1940	Payload                   string         //Required
1941	ProviderToken             string         //Required
1942	Currency                  string         //Required
1943	Prices                    []LabeledPrice //Required
1944	MaxTipAmount              int
1945	SuggestedTipAmounts       []int
1946	ProviderData              string
1947	PhotoURL                  string
1948	PhotoSize                 int
1949	PhotoWidth                int
1950	PhotoHeight               int
1951	NeedName                  bool
1952	NeedPhoneNumber           bool
1953	NeedEmail                 bool
1954	NeedShippingAddress       bool
1955	SendPhoneNumberToProvider bool
1956	SendEmailToProvider       bool
1957	IsFlexible                bool
1958}
1959
1960func (config InvoiceLinkConfig) params() (Params, error) {
1961	params := make(Params)
1962
1963	params["title"] = config.Title
1964	params["description"] = config.Description
1965	params["payload"] = config.Payload
1966	params["currency"] = config.Currency
1967	if err := params.AddInterface("prices", config.Prices); err != nil {
1968		return params, err
1969	}
1970
1971	params.AddNonEmpty("provider_token", config.ProviderToken)
1972	params.AddNonZero("max_tip_amount", config.MaxTipAmount)
1973	err := params.AddInterface("suggested_tip_amounts", config.SuggestedTipAmounts)
1974	params.AddNonEmpty("provider_data", config.ProviderData)
1975	params.AddNonEmpty("photo_url", config.PhotoURL)
1976	params.AddNonZero("photo_size", config.PhotoSize)
1977	params.AddNonZero("photo_width", config.PhotoWidth)
1978	params.AddNonZero("photo_height", config.PhotoHeight)
1979	params.AddBool("need_name", config.NeedName)
1980	params.AddBool("need_phone_number", config.NeedPhoneNumber)
1981	params.AddBool("need_email", config.NeedEmail)
1982	params.AddBool("need_shipping_address", config.NeedShippingAddress)
1983	params.AddBool("send_phone_number_to_provider", config.SendPhoneNumberToProvider)
1984	params.AddBool("send_email_to_provider", config.SendEmailToProvider)
1985	params.AddBool("is_flexible", config.IsFlexible)
1986
1987	return params, err
1988}
1989
1990func (config InvoiceLinkConfig) method() string {
1991	return "createInvoiceLink"
1992}
1993
1994// ShippingConfig contains information for answerShippingQuery request.
1995type ShippingConfig struct {
1996	ShippingQueryID string // required
1997	OK              bool   // required
1998	ShippingOptions []ShippingOption
1999	ErrorMessage    string
2000}
2001
2002func (config ShippingConfig) method() string {
2003	return "answerShippingQuery"
2004}
2005
2006func (config ShippingConfig) params() (Params, error) {
2007	params := make(Params)
2008
2009	params["shipping_query_id"] = config.ShippingQueryID
2010	params.AddBool("ok", config.OK)
2011	err := params.AddInterface("shipping_options", config.ShippingOptions)
2012	params.AddNonEmpty("error_message", config.ErrorMessage)
2013
2014	return params, err
2015}
2016
2017// PreCheckoutConfig contains information for answerPreCheckoutQuery request.
2018type PreCheckoutConfig struct {
2019	PreCheckoutQueryID string // required
2020	OK                 bool   // required
2021	ErrorMessage       string
2022}
2023
2024func (config PreCheckoutConfig) method() string {
2025	return "answerPreCheckoutQuery"
2026}
2027
2028func (config PreCheckoutConfig) params() (Params, error) {
2029	params := make(Params)
2030
2031	params["pre_checkout_query_id"] = config.PreCheckoutQueryID
2032	params.AddBool("ok", config.OK)
2033	params.AddNonEmpty("error_message", config.ErrorMessage)
2034
2035	return params, nil
2036}
2037
2038// RefundStarPaymentConfig refunds a successful payment in Telegram Stars.
2039// Returns True on success.
2040type RefundStarPaymentConfig struct {
2041	UserID                  int64  //required
2042	TelegramPaymentChargeID string //required
2043}
2044
2045func (config RefundStarPaymentConfig) method() string {
2046	return "refundStarPayment"
2047}
2048
2049func (config RefundStarPaymentConfig) params() (Params, error) {
2050	params := make(Params)
2051
2052	params["telegram_payment_charge_id"] = config.TelegramPaymentChargeID
2053	params.AddNonZero64("user_id", config.UserID)
2054
2055	return params, nil
2056}
2057
2058// DeleteMessageConfig contains information of a message in a chat to delete.
2059type DeleteMessageConfig struct {
2060	BaseChatMessage
2061}
2062
2063func (config DeleteMessageConfig) method() string {
2064	return "deleteMessage"
2065}
2066
2067func (config DeleteMessageConfig) params() (Params, error) {
2068	return config.BaseChatMessage.params()
2069}
2070
2071// DeleteMessageConfig contains information of a messages in a chat to delete.
2072type DeleteMessagesConfig struct {
2073	BaseChatMessages
2074}
2075
2076func (config DeleteMessagesConfig) method() string {
2077	return "deleteMessages"
2078}
2079
2080func (config DeleteMessagesConfig) params() (Params, error) {
2081	return config.BaseChatMessages.params()
2082}
2083
2084// PinChatMessageConfig contains information of a message in a chat to pin.
2085type PinChatMessageConfig struct {
2086	BaseChatMessage
2087	DisableNotification bool
2088}
2089
2090func (config PinChatMessageConfig) method() string {
2091	return "pinChatMessage"
2092}
2093
2094func (config PinChatMessageConfig) params() (Params, error) {
2095	params, err := config.BaseChatMessage.params()
2096	if err != nil {
2097		return params, err
2098	}
2099
2100	params.AddBool("disable_notification", config.DisableNotification)
2101
2102	return params, nil
2103}
2104
2105// UnpinChatMessageConfig contains information of a chat message to unpin.
2106//
2107// If MessageID is not specified, it will unpin the most recent pin.
2108type UnpinChatMessageConfig struct {
2109	BaseChatMessage
2110}
2111
2112func (config UnpinChatMessageConfig) method() string {
2113	return "unpinChatMessage"
2114}
2115
2116func (config UnpinChatMessageConfig) params() (Params, error) {
2117	return config.BaseChatMessage.params()
2118}
2119
2120// UnpinAllChatMessagesConfig contains information of all messages to unpin in
2121// a chat.
2122type UnpinAllChatMessagesConfig struct {
2123	ChatConfig
2124}
2125
2126func (config UnpinAllChatMessagesConfig) method() string {
2127	return "unpinAllChatMessages"
2128}
2129
2130func (config UnpinAllChatMessagesConfig) params() (Params, error) {
2131	return config.ChatConfig.params()
2132}
2133
2134// SetChatPhotoConfig allows you to set a group, supergroup, or channel's photo.
2135type SetChatPhotoConfig struct {
2136	BaseFile
2137}
2138
2139func (config SetChatPhotoConfig) method() string {
2140	return "setChatPhoto"
2141}
2142
2143func (config SetChatPhotoConfig) files() []RequestFile {
2144	return []RequestFile{{
2145		Name: "photo",
2146		Data: config.File,
2147	}}
2148}
2149
2150// DeleteChatPhotoConfig allows you to delete a group, supergroup, or channel's photo.
2151type DeleteChatPhotoConfig struct {
2152	ChatConfig
2153}
2154
2155func (config DeleteChatPhotoConfig) method() string {
2156	return "deleteChatPhoto"
2157}
2158
2159func (config DeleteChatPhotoConfig) params() (Params, error) {
2160	return config.ChatConfig.params()
2161}
2162
2163// SetChatTitleConfig allows you to set the title of something other than a private chat.
2164type SetChatTitleConfig struct {
2165	ChatConfig
2166	Title string
2167}
2168
2169func (config SetChatTitleConfig) method() string {
2170	return "setChatTitle"
2171}
2172
2173func (config SetChatTitleConfig) params() (Params, error) {
2174	params, err := config.ChatConfig.params()
2175	if err != nil {
2176		return params, err
2177	}
2178
2179	params["title"] = config.Title
2180
2181	return params, nil
2182}
2183
2184// SetChatDescriptionConfig allows you to set the description of a supergroup or channel.
2185type SetChatDescriptionConfig struct {
2186	ChatConfig
2187	Description string
2188}
2189
2190func (config SetChatDescriptionConfig) method() string {
2191	return "setChatDescription"
2192}
2193
2194func (config SetChatDescriptionConfig) params() (Params, error) {
2195	params, err := config.ChatConfig.params()
2196	if err != nil {
2197		return params, err
2198	}
2199
2200	params["description"] = config.Description
2201
2202	return params, nil
2203}
2204
2205// GetStickerSetConfig allows you to get the stickers in a set.
2206type GetStickerSetConfig struct {
2207	Name string
2208}
2209
2210func (config GetStickerSetConfig) method() string {
2211	return "getStickerSet"
2212}
2213
2214func (config GetStickerSetConfig) params() (Params, error) {
2215	params := make(Params)
2216
2217	params["name"] = config.Name
2218
2219	return params, nil
2220}
2221
2222// GetCustomEmojiStickersConfig get information about
2223// custom emoji stickers by their identifiers.
2224type GetCustomEmojiStickersConfig struct {
2225	CustomEmojiIDs []string
2226}
2227
2228func (config GetCustomEmojiStickersConfig) params() (Params, error) {
2229	params := make(Params)
2230
2231	params.AddInterface("custom_emoji_ids", config.CustomEmojiIDs)
2232
2233	return params, nil
2234}
2235
2236func (config GetCustomEmojiStickersConfig) method() string {
2237	return "getCustomEmojiStickers"
2238}
2239
2240// UploadStickerConfig allows you to upload a sticker for use in a set later.
2241type UploadStickerConfig struct {
2242	UserID        int64
2243	Sticker       RequestFile
2244	StickerFormat string
2245}
2246
2247func (config UploadStickerConfig) method() string {
2248	return "uploadStickerFile"
2249}
2250
2251func (config UploadStickerConfig) params() (Params, error) {
2252	params := make(Params)
2253
2254	params.AddNonZero64("user_id", config.UserID)
2255	params["sticker_format"] = config.StickerFormat
2256
2257	return params, nil
2258}
2259
2260func (config UploadStickerConfig) files() []RequestFile {
2261	return []RequestFile{config.Sticker}
2262}
2263
2264// NewStickerSetConfig allows creating a new sticker set.
2265type NewStickerSetConfig struct {
2266	UserID          int64
2267	Name            string
2268	Title           string
2269	Stickers        []InputSticker
2270	StickerType     string
2271	NeedsRepainting bool //optional; Pass True if stickers in the sticker set must be repainted to the color of text when used in messages, the accent color if used as emoji status, white on chat photos, or another appropriate color based on context; for custom emoji sticker sets only
2272}
2273
2274func (config NewStickerSetConfig) method() string {
2275	return "createNewStickerSet"
2276}
2277
2278func (config NewStickerSetConfig) params() (Params, error) {
2279	params := make(Params)
2280
2281	params.AddNonZero64("user_id", config.UserID)
2282	params["name"] = config.Name
2283	params["title"] = config.Title
2284
2285	params.AddBool("needs_repainting", config.NeedsRepainting)
2286	params.AddNonEmpty("sticker_type", string(config.StickerType))
2287	err := params.AddInterface("stickers", config.Stickers)
2288
2289	return params, err
2290}
2291
2292func (config NewStickerSetConfig) files() []RequestFile {
2293	requestFiles := []RequestFile{}
2294	for _, v := range config.Stickers {
2295		requestFiles = append(requestFiles, v.Sticker)
2296	}
2297	return requestFiles
2298}
2299
2300// AddStickerConfig allows you to add a sticker to a set.
2301type AddStickerConfig struct {
2302	UserID  int64
2303	Name    string
2304	Sticker InputSticker
2305}
2306
2307func (config AddStickerConfig) method() string {
2308	return "addStickerToSet"
2309}
2310
2311func (config AddStickerConfig) params() (Params, error) {
2312	params := make(Params)
2313
2314	params.AddNonZero64("user_id", config.UserID)
2315	params["name"] = config.Name
2316	err := params.AddInterface("sticker", config.Sticker)
2317	return params, err
2318}
2319
2320func (config AddStickerConfig) files() []RequestFile {
2321	return []RequestFile{config.Sticker.Sticker}
2322}
2323
2324// SetStickerPositionConfig allows you to change the position of a sticker in a set.
2325type SetStickerPositionConfig struct {
2326	Sticker  string
2327	Position int
2328}
2329
2330func (config SetStickerPositionConfig) method() string {
2331	return "setStickerPositionInSet"
2332}
2333
2334func (config SetStickerPositionConfig) params() (Params, error) {
2335	params := make(Params)
2336
2337	params["sticker"] = config.Sticker
2338	params.AddNonZero("position", config.Position)
2339
2340	return params, nil
2341}
2342
2343// SetCustomEmojiStickerSetThumbnailConfig allows you to set the thumbnail of a custom emoji sticker set
2344type SetCustomEmojiStickerSetThumbnailConfig struct {
2345	Name          string
2346	CustomEmojiID string
2347}
2348
2349func (config SetCustomEmojiStickerSetThumbnailConfig) method() string {
2350	return "setCustomEmojiStickerSetThumbnail"
2351}
2352
2353func (config SetCustomEmojiStickerSetThumbnailConfig) params() (Params, error) {
2354	params := make(Params)
2355
2356	params["name"] = config.Name
2357	params.AddNonEmpty("position", config.CustomEmojiID)
2358
2359	return params, nil
2360}
2361
2362// SetStickerSetTitle allows you to set the title of a created sticker set
2363type SetStickerSetTitleConfig struct {
2364	Name  string
2365	Title string
2366}
2367
2368func (config SetStickerSetTitleConfig) method() string {
2369	return "setStickerSetTitle"
2370}
2371
2372func (config SetStickerSetTitleConfig) params() (Params, error) {
2373	params := make(Params)
2374
2375	params["name"] = config.Name
2376	params["title"] = config.Title
2377
2378	return params, nil
2379}
2380
2381// DeleteStickerSetConfig allows you to delete a sticker set that was created by the bot.
2382type DeleteStickerSetConfig struct {
2383	Name string
2384}
2385
2386func (config DeleteStickerSetConfig) method() string {
2387	return "deleteStickerSet"
2388}
2389
2390func (config DeleteStickerSetConfig) params() (Params, error) {
2391	params := make(Params)
2392
2393	params["name"] = config.Name
2394
2395	return params, nil
2396}
2397
2398// DeleteStickerConfig allows you to delete a sticker from a set.
2399type DeleteStickerConfig struct {
2400	Sticker string
2401}
2402
2403func (config DeleteStickerConfig) method() string {
2404	return "deleteStickerFromSet"
2405}
2406
2407func (config DeleteStickerConfig) params() (Params, error) {
2408	params := make(Params)
2409
2410	params["sticker"] = config.Sticker
2411
2412	return params, nil
2413}
2414
2415// ReplaceStickerInSetConfig allows you to replace an existing sticker in a sticker set
2416// with a new one. The method is equivalent to calling deleteStickerFromSet,
2417// then addStickerToSet, then setStickerPositionInSet.
2418// Returns True on success.
2419type ReplaceStickerInSetConfig struct {
2420	UserID     int64
2421	Name       string
2422	OldSticker string
2423	Sticker    InputSticker
2424}
2425
2426func (config ReplaceStickerInSetConfig) method() string {
2427	return "replaceStickerInSet"
2428}
2429
2430func (config ReplaceStickerInSetConfig) params() (Params, error) {
2431	params := make(Params)
2432
2433	params.AddNonZero64("user_id", config.UserID)
2434	params["name"] = config.Name
2435	params["old_sticker"] = config.OldSticker
2436
2437	err := params.AddInterface("sticker", config.Sticker)
2438
2439	return params, err
2440}
2441
2442// SetStickerEmojiListConfig allows you to change the list of emoji assigned to a regular or custom emoji sticker. The sticker must belong to a sticker set created by the bot
2443type SetStickerEmojiListConfig struct {
2444	Sticker   string
2445	EmojiList []string
2446}
2447
2448func (config SetStickerEmojiListConfig) method() string {
2449	return "setStickerEmojiList"
2450}
2451
2452func (config SetStickerEmojiListConfig) params() (Params, error) {
2453	params := make(Params)
2454
2455	params["sticker"] = config.Sticker
2456	err := params.AddInterface("emoji_list", config.EmojiList)
2457
2458	return params, err
2459}
2460
2461// SetStickerKeywordsConfig allows you to change search keywords assigned to a regular or custom emoji sticker. The sticker must belong to a sticker set created by the bot.
2462type SetStickerKeywordsConfig struct {
2463	Sticker  string
2464	Keywords []string
2465}
2466
2467func (config SetStickerKeywordsConfig) method() string {
2468	return "setStickerKeywords"
2469}
2470
2471func (config SetStickerKeywordsConfig) params() (Params, error) {
2472	params := make(Params)
2473
2474	params["sticker"] = config.Sticker
2475	err := params.AddInterface("keywords", config.Keywords)
2476
2477	return params, err
2478}
2479
2480// SetStickerMaskPositionConfig allows you to  change the mask position of a mask sticker. The sticker must belong to a sticker set that was created by the bot
2481type SetStickerMaskPositionConfig struct {
2482	Sticker      string
2483	MaskPosition *MaskPosition
2484}
2485
2486func (config SetStickerMaskPositionConfig) method() string {
2487	return "setStickerMaskPosition"
2488}
2489
2490func (config SetStickerMaskPositionConfig) params() (Params, error) {
2491	params := make(Params)
2492
2493	params["sticker"] = config.Sticker
2494	err := params.AddInterface("keywords", config.MaskPosition)
2495
2496	return params, err
2497}
2498
2499// SetStickerSetThumbConfig allows you to set the thumbnail for a sticker set.
2500type SetStickerSetThumbConfig struct {
2501	Name   string
2502	UserID int64
2503	Thumb  RequestFileData
2504	Format string
2505}
2506
2507func (config SetStickerSetThumbConfig) method() string {
2508	return "setStickerSetThumbnail"
2509}
2510
2511func (config SetStickerSetThumbConfig) params() (Params, error) {
2512	params := make(Params)
2513
2514	params["name"] = config.Name
2515	params["format"] = config.Format
2516
2517	params.AddNonZero64("user_id", config.UserID)
2518
2519	return params, nil
2520}
2521
2522func (config SetStickerSetThumbConfig) files() []RequestFile {
2523	return []RequestFile{{
2524		Name: "thumbnail",
2525		Data: config.Thumb,
2526	}}
2527}
2528
2529// SetChatStickerSetConfig allows you to set the sticker set for a supergroup.
2530type SetChatStickerSetConfig struct {
2531	ChatConfig
2532
2533	StickerSetName string
2534}
2535
2536func (config SetChatStickerSetConfig) method() string {
2537	return "setChatStickerSet"
2538}
2539
2540func (config SetChatStickerSetConfig) params() (Params, error) {
2541	params, err := config.ChatConfig.params()
2542	if err != nil {
2543		return params, err
2544	}
2545
2546	params["sticker_set_name"] = config.StickerSetName
2547
2548	return params, nil
2549}
2550
2551// DeleteChatStickerSetConfig allows you to remove a supergroup's sticker set.
2552type DeleteChatStickerSetConfig struct {
2553	ChatConfig
2554}
2555
2556func (config DeleteChatStickerSetConfig) method() string {
2557	return "deleteChatStickerSet"
2558}
2559
2560func (config DeleteChatStickerSetConfig) params() (Params, error) {
2561	return config.ChatConfig.params()
2562}
2563
2564// GetForumTopicIconStickersConfig allows you to get custom emoji stickers,
2565// which can be used as a forum topic icon by any user.
2566type GetForumTopicIconStickersConfig struct{}
2567
2568func (config GetForumTopicIconStickersConfig) method() string {
2569	return "getForumTopicIconStickers"
2570}
2571
2572func (config GetForumTopicIconStickersConfig) params() (Params, error) {
2573	return nil, nil
2574}
2575
2576// CreateForumTopicConfig allows you to create a topic
2577// in a forum supergroup chat.
2578type CreateForumTopicConfig struct {
2579	ChatConfig
2580	Name              string
2581	IconColor         int
2582	IconCustomEmojiID string
2583}
2584
2585func (config CreateForumTopicConfig) method() string {
2586	return "createForumTopic"
2587}
2588
2589func (config CreateForumTopicConfig) params() (Params, error) {
2590	params, err := config.ChatConfig.params()
2591	if err != nil {
2592		return params, err
2593	}
2594
2595	params.AddNonEmpty("name", config.Name)
2596	params.AddNonZero("icon_color", config.IconColor)
2597	params.AddNonEmpty("icon_custom_emoji_id", config.IconCustomEmojiID)
2598
2599	return params, nil
2600}
2601
2602type BaseForum struct {
2603	ChatConfig
2604	MessageThreadID int
2605}
2606
2607func (base BaseForum) params() (Params, error) {
2608	params, err := base.ChatConfig.params()
2609	if err != nil {
2610		return params, err
2611	}
2612	params.AddNonZero("message_thread_id", base.MessageThreadID)
2613
2614	return params, nil
2615}
2616
2617// EditForumTopicConfig allows you to edit
2618// name and icon of a topic in a forum supergroup chat.
2619type EditForumTopicConfig struct {
2620	BaseForum
2621	Name              string
2622	IconCustomEmojiID string
2623}
2624
2625func (config EditForumTopicConfig) method() string {
2626	return "editForumTopic"
2627}
2628
2629func (config EditForumTopicConfig) params() (Params, error) {
2630	params, err := config.BaseForum.params()
2631	if err != nil {
2632		return params, err
2633	}
2634	params.AddNonEmpty("name", config.Name)
2635	params.AddNonEmpty("icon_custom_emoji_id", config.IconCustomEmojiID)
2636
2637	return params, nil
2638}
2639
2640// CloseForumTopicConfig allows you to close
2641// an open topic in a forum supergroup chat.
2642type CloseForumTopicConfig struct{ BaseForum }
2643
2644func (config CloseForumTopicConfig) method() string {
2645	return "closeForumTopic"
2646}
2647
2648// ReopenForumTopicConfig allows you to reopen
2649// an closed topic in a forum supergroup chat.
2650type ReopenForumTopicConfig struct{ BaseForum }
2651
2652func (config ReopenForumTopicConfig) method() string {
2653	return "reopenForumTopic"
2654}
2655
2656// DeleteForumTopicConfig allows you to delete a forum topic
2657// along with all its messages in a forum supergroup chat.
2658type DeleteForumTopicConfig struct{ BaseForum }
2659
2660func (config DeleteForumTopicConfig) method() string {
2661	return "deleteForumTopic"
2662}
2663
2664// UnpinAllForumTopicMessagesConfig allows you to clear the list
2665// of pinned messages in a forum topic.
2666type UnpinAllForumTopicMessagesConfig struct{ BaseForum }
2667
2668func (config UnpinAllForumTopicMessagesConfig) method() string {
2669	return "unpinAllForumTopicMessages"
2670}
2671
2672// UnpinAllForumTopicMessagesConfig allows you to edit the name of
2673// the 'General' topic in a forum supergroup chat.
2674// The bot must be an administrator in the chat for this to work
2675// and must have can_manage_topics administrator rights. Returns True on success.
2676type EditGeneralForumTopicConfig struct {
2677	BaseForum
2678	Name string
2679}
2680
2681func (config EditGeneralForumTopicConfig) method() string {
2682	return "editGeneralForumTopic"
2683}
2684
2685func (config EditGeneralForumTopicConfig) params() (Params, error) {
2686	params, err := config.BaseForum.params()
2687	if err != nil {
2688		return params, err
2689	}
2690	params.AddNonEmpty("name", config.Name)
2691
2692	return params, nil
2693}
2694
2695// CloseGeneralForumTopicConfig allows you to to close an open 'General' topic
2696// in a forum supergroup chat. The bot must be an administrator in the chat
2697// for this to work and must have the can_manage_topics administrator rights.
2698// Returns True on success.
2699type CloseGeneralForumTopicConfig struct{ BaseForum }
2700
2701func (config CloseGeneralForumTopicConfig) method() string {
2702	return "closeGeneralForumTopic"
2703}
2704
2705// CloseGeneralForumTopicConfig allows you to reopen a closed 'General' topic
2706// in a forum supergroup chat. The bot must be an administrator in the chat
2707// for this to work and must have the can_manage_topics administrator rights.
2708// The topic will be automatically unhidden if it was hidden.
2709// Returns True on success.
2710type ReopenGeneralForumTopicConfig struct{ BaseForum }
2711
2712func (config ReopenGeneralForumTopicConfig) method() string {
2713	return "reopenGeneralForumTopic"
2714}
2715
2716// HideGeneralForumTopicConfig allows you to hide the 'General' topic
2717// in a forum supergroup chat. The bot must be an administrator in the chat
2718// for this to work and must have the can_manage_topics administrator rights.
2719// The topic will be automatically closed if it was open.
2720// Returns True on success.
2721type HideGeneralForumTopicConfig struct{ BaseForum }
2722
2723func (config HideGeneralForumTopicConfig) method() string {
2724	return "hideGeneralForumTopic"
2725}
2726
2727// UnhideGeneralForumTopicConfig allows you to unhide the 'General' topic
2728// in a forum supergroup chat. The bot must be an administrator in the chat
2729// for this to work and must have the can_manage_topics administrator rights.
2730// Returns True on success.
2731type UnhideGeneralForumTopicConfig struct{ BaseForum }
2732
2733func (config UnhideGeneralForumTopicConfig) method() string {
2734	return "unhideGeneralForumTopic"
2735}
2736
2737// UnpinAllGeneralForumTopicMessagesConfig allows you to to clear
2738// the list of pinned messages in a General forum topic.
2739// The bot must be an administrator in the chat for this to work
2740// and must have the can_pin_messages administrator right in the supergroup.
2741// Returns True on success.
2742type UnpinAllGeneralForumTopicMessagesConfig struct{ BaseForum }
2743
2744func (config UnpinAllGeneralForumTopicMessagesConfig) method() string {
2745	return "unpinAllGeneralForumTopicMessages"
2746}
2747
2748// MediaGroupConfig allows you to send a group of media.
2749//
2750// Media consist of InputMedia items (InputMediaPhoto, InputMediaVideo).
2751type MediaGroupConfig struct {
2752	BaseChat
2753	Media []interface{}
2754}
2755
2756func (config MediaGroupConfig) method() string {
2757	return "sendMediaGroup"
2758}
2759
2760func (config MediaGroupConfig) params() (Params, error) {
2761	params, err := config.BaseChat.params()
2762	if err != nil {
2763		return nil, err
2764	}
2765
2766	err = params.AddInterface("media", prepareInputMediaForParams(config.Media))
2767
2768	return params, err
2769}
2770
2771func (config MediaGroupConfig) files() []RequestFile {
2772	return prepareInputMediaForFiles(config.Media)
2773}
2774
2775// DiceConfig contains information about a sendDice request.
2776type DiceConfig struct {
2777	BaseChat
2778	// Emoji on which the dice throw animation is based.
2779	// Currently, must be one of 🎲, 🎯, 🏀, ⚽, 🎳, or 🎰.
2780	// Dice can have values 1-6 for 🎲, 🎯, and 🎳, values 1-5 for 🏀 and ⚽,
2781	// and values 1-64 for 🎰.
2782	// Defaults to “🎲”
2783	Emoji string
2784}
2785
2786func (config DiceConfig) method() string {
2787	return "sendDice"
2788}
2789
2790func (config DiceConfig) params() (Params, error) {
2791	params, err := config.BaseChat.params()
2792	if err != nil {
2793		return params, err
2794	}
2795
2796	params.AddNonEmpty("emoji", config.Emoji)
2797
2798	return params, err
2799}
2800
2801type GetUserChatBoostsConfig struct {
2802	ChatConfig
2803	UserID int64
2804}
2805
2806func (config GetUserChatBoostsConfig) method() string {
2807	return "getUserChatBoosts"
2808}
2809
2810func (config GetUserChatBoostsConfig) params() (Params, error) {
2811	params, err := config.ChatConfig.params()
2812	if err != nil {
2813		return params, err
2814	}
2815
2816	params.AddNonZero64("user_id", config.UserID)
2817
2818	return params, err
2819}
2820
2821type (
2822	GetBusinessConnectionConfig struct {
2823		BusinessConnectionID BusinessConnectionID
2824	}
2825	BusinessConnectionID string
2826)
2827
2828func (GetBusinessConnectionConfig) method() string {
2829	return "getBusinessConnection"
2830}
2831
2832func (config GetBusinessConnectionConfig) params() (Params, error) {
2833	return config.BusinessConnectionID.params()
2834}
2835
2836func (config BusinessConnectionID) params() (Params, error) {
2837	params := make(Params)
2838
2839	params["business_connection_id"] = string(config)
2840
2841	return params, nil
2842}
2843
2844// GetMyCommandsConfig gets a list of the currently registered commands.
2845type GetMyCommandsConfig struct {
2846	Scope        *BotCommandScope
2847	LanguageCode string
2848}
2849
2850func (config GetMyCommandsConfig) method() string {
2851	return "getMyCommands"
2852}
2853
2854func (config GetMyCommandsConfig) params() (Params, error) {
2855	params := make(Params)
2856
2857	err := params.AddInterface("scope", config.Scope)
2858	params.AddNonEmpty("language_code", config.LanguageCode)
2859
2860	return params, err
2861}
2862
2863// SetMyCommandsConfig sets a list of commands the bot understands.
2864type SetMyCommandsConfig struct {
2865	Commands     []BotCommand
2866	Scope        *BotCommandScope
2867	LanguageCode string
2868}
2869
2870func (config SetMyCommandsConfig) method() string {
2871	return "setMyCommands"
2872}
2873
2874func (config SetMyCommandsConfig) params() (Params, error) {
2875	params := make(Params)
2876
2877	if err := params.AddInterface("commands", config.Commands); err != nil {
2878		return params, err
2879	}
2880	err := params.AddInterface("scope", config.Scope)
2881	params.AddNonEmpty("language_code", config.LanguageCode)
2882
2883	return params, err
2884}
2885
2886type DeleteMyCommandsConfig struct {
2887	Scope        *BotCommandScope
2888	LanguageCode string
2889}
2890
2891func (config DeleteMyCommandsConfig) method() string {
2892	return "deleteMyCommands"
2893}
2894
2895func (config DeleteMyCommandsConfig) params() (Params, error) {
2896	params := make(Params)
2897
2898	err := params.AddInterface("scope", config.Scope)
2899	params.AddNonEmpty("language_code", config.LanguageCode)
2900
2901	return params, err
2902}
2903
2904// SetMyNameConfig change the bot's name
2905type SetMyNameConfig struct {
2906	Name         string
2907	LanguageCode string
2908}
2909
2910func (config SetMyNameConfig) method() string {
2911	return "setMyName"
2912}
2913
2914func (config SetMyNameConfig) params() (Params, error) {
2915	params := make(Params)
2916
2917	params.AddNonEmpty("name", config.Name)
2918	params.AddNonEmpty("language_code", config.LanguageCode)
2919
2920	return params, nil
2921}
2922
2923type GetMyNameConfig struct {
2924	LanguageCode string
2925}
2926
2927func (config GetMyNameConfig) method() string {
2928	return "getMyName"
2929}
2930
2931func (config GetMyNameConfig) params() (Params, error) {
2932	params := make(Params)
2933
2934	params.AddNonEmpty("language_code", config.LanguageCode)
2935
2936	return params, nil
2937}
2938
2939// GetMyDescriptionConfig get the current bot description for the given user language
2940type GetMyDescriptionConfig struct {
2941	LanguageCode string
2942}
2943
2944func (config GetMyDescriptionConfig) method() string {
2945	return "getMyDescription"
2946}
2947
2948func (config GetMyDescriptionConfig) params() (Params, error) {
2949	params := make(Params)
2950
2951	params.AddNonEmpty("language_code", config.LanguageCode)
2952
2953	return params, nil
2954}
2955
2956// SetMyDescroptionConfig sets the bot's description, which is shown in the chat with the bot if the chat is empty
2957type SetMyDescriptionConfig struct {
2958	// Pass an empty string to remove the dedicated description for the given language.
2959	Description string
2960	//If empty, the description will be applied to all users for whose language there is no dedicated description.
2961	LanguageCode string
2962}
2963
2964func (config SetMyDescriptionConfig) method() string {
2965	return "setMyDescription"
2966}
2967
2968func (config SetMyDescriptionConfig) params() (Params, error) {
2969	params := make(Params)
2970
2971	params.AddNonEmpty("description", config.Description)
2972	params.AddNonEmpty("language_code", config.LanguageCode)
2973
2974	return params, nil
2975}
2976
2977// GetMyShortDescriptionConfig get the current bot short description for the given user language
2978type GetMyShortDescriptionConfig struct {
2979	LanguageCode string
2980}
2981
2982func (config GetMyShortDescriptionConfig) method() string {
2983	return "getMyShortDescription"
2984}
2985
2986func (config GetMyShortDescriptionConfig) params() (Params, error) {
2987	params := make(Params)
2988
2989	params.AddNonEmpty("language_code", config.LanguageCode)
2990
2991	return params, nil
2992}
2993
2994// SetMyDescroptionConfig sets the bot's short description, which is shown on the bot's profile page and is sent together with the link when users share the bot.
2995type SetMyShortDescriptionConfig struct {
2996	// New short description for the bot; 0-120 characters.
2997	//
2998	//Pass an empty string to remove the dedicated short description for the given language.
2999	ShortDescription string
3000	//A two-letter ISO 639-1 language code.
3001	//
3002	//If empty, the short description will be applied to all users for whose language there is no dedicated short description.
3003	LanguageCode string
3004}
3005
3006func (config SetMyShortDescriptionConfig) method() string {
3007	return "setMyShortDescription"
3008}
3009
3010func (config SetMyShortDescriptionConfig) params() (Params, error) {
3011	params := make(Params)
3012
3013	params.AddNonEmpty("short_description", config.ShortDescription)
3014	params.AddNonEmpty("language_code", config.LanguageCode)
3015
3016	return params, nil
3017}
3018
3019// SetChatMenuButtonConfig changes the bot's menu button in a private chat,
3020// or the default menu button.
3021type SetChatMenuButtonConfig struct {
3022	ChatConfig
3023
3024	MenuButton *MenuButton
3025}
3026
3027func (config SetChatMenuButtonConfig) method() string {
3028	return "setChatMenuButton"
3029}
3030
3031func (config SetChatMenuButtonConfig) params() (Params, error) {
3032	params, err := config.ChatConfig.params()
3033	if err != nil {
3034		return params, err
3035	}
3036
3037	err = params.AddInterface("menu_button", config.MenuButton)
3038
3039	return params, err
3040}
3041
3042type GetChatMenuButtonConfig struct {
3043	ChatConfig
3044}
3045
3046func (config GetChatMenuButtonConfig) method() string {
3047	return "getChatMenuButton"
3048}
3049
3050func (config GetChatMenuButtonConfig) params() (Params, error) {
3051	return config.ChatConfig.params()
3052}
3053
3054type SetMyDefaultAdministratorRightsConfig struct {
3055	Rights      ChatAdministratorRights
3056	ForChannels bool
3057}
3058
3059func (config SetMyDefaultAdministratorRightsConfig) method() string {
3060	return "setMyDefaultAdministratorRights"
3061}
3062
3063func (config SetMyDefaultAdministratorRightsConfig) params() (Params, error) {
3064	params := make(Params)
3065
3066	err := params.AddInterface("rights", config.Rights)
3067	params.AddBool("for_channels", config.ForChannels)
3068
3069	return params, err
3070}
3071
3072type GetMyDefaultAdministratorRightsConfig struct {
3073	ForChannels bool
3074}
3075
3076func (config GetMyDefaultAdministratorRightsConfig) method() string {
3077	return "getMyDefaultAdministratorRights"
3078}
3079
3080func (config GetMyDefaultAdministratorRightsConfig) params() (Params, error) {
3081	params := make(Params)
3082
3083	params.AddBool("for_channels", config.ForChannels)
3084
3085	return params, nil
3086}
3087
3088// prepareInputMediaParam evaluates a single InputMedia and determines if it
3089// needs to be modified for a successful upload. If it returns nil, then the
3090// value does not need to be included in the params. Otherwise, it will return
3091// the same type as was originally provided.
3092//
3093// The idx is used to calculate the file field name. If you only have a single
3094// file, 0 may be used. It is formatted into "attach://file-%d" for the primary
3095// media and "attach://file-%d-thumb" for thumbnails.
3096//
3097// It is expected to be used in conjunction with prepareInputMediaFile.
3098func prepareInputMediaParam(inputMedia interface{}, idx int) interface{} {
3099	switch m := inputMedia.(type) {
3100	case InputMediaPhoto:
3101		if m.Media.NeedsUpload() {
3102			m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
3103		}
3104
3105		return m
3106	case InputMediaVideo:
3107		if m.Media.NeedsUpload() {
3108			m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
3109		}
3110
3111		if m.Thumb != nil && m.Thumb.NeedsUpload() {
3112			m.Thumb = fileAttach(fmt.Sprintf("attach://file-%d-thumb", idx))
3113		}
3114
3115		return m
3116	case InputMediaAudio:
3117		if m.Media.NeedsUpload() {
3118			m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
3119		}
3120
3121		if m.Thumb != nil && m.Thumb.NeedsUpload() {
3122			m.Thumb = fileAttach(fmt.Sprintf("attach://file-%d-thumb", idx))
3123		}
3124
3125		return m
3126	case InputMediaDocument:
3127		if m.Media.NeedsUpload() {
3128			m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
3129		}
3130
3131		if m.Thumb != nil && m.Thumb.NeedsUpload() {
3132			m.Thumb = fileAttach(fmt.Sprintf("attach://file-%d-thumb", idx))
3133		}
3134
3135		return m
3136	}
3137
3138	return nil
3139}
3140
3141// prepareInputMediaFile generates an array of RequestFile to provide for
3142// Fileable's files method. It returns an array as a single InputMedia may have
3143// multiple files, for the primary media and a thumbnail.
3144//
3145// The idx parameter is used to generate file field names. It uses the names
3146// "file-%d" for the main file and "file-%d-thumb" for the thumbnail.
3147//
3148// It is expected to be used in conjunction with prepareInputMediaParam.
3149func prepareInputMediaFile(inputMedia interface{}, idx int) []RequestFile {
3150	files := []RequestFile{}
3151
3152	switch m := inputMedia.(type) {
3153	case InputMediaPhoto:
3154		if m.Media.NeedsUpload() {
3155			files = append(files, RequestFile{
3156				Name: fmt.Sprintf("file-%d", idx),
3157				Data: m.Media,
3158			})
3159		}
3160	case InputMediaVideo:
3161		if m.Media.NeedsUpload() {
3162			files = append(files, RequestFile{
3163				Name: fmt.Sprintf("file-%d", idx),
3164				Data: m.Media,
3165			})
3166		}
3167
3168		if m.Thumb != nil && m.Thumb.NeedsUpload() {
3169			files = append(files, RequestFile{
3170				Name: fmt.Sprintf("file-%d", idx),
3171				Data: m.Thumb,
3172			})
3173		}
3174	case InputMediaDocument:
3175		if m.Media.NeedsUpload() {
3176			files = append(files, RequestFile{
3177				Name: fmt.Sprintf("file-%d", idx),
3178				Data: m.Media,
3179			})
3180		}
3181
3182		if m.Thumb != nil && m.Thumb.NeedsUpload() {
3183			files = append(files, RequestFile{
3184				Name: fmt.Sprintf("file-%d", idx),
3185				Data: m.Thumb,
3186			})
3187		}
3188	case InputMediaAudio:
3189		if m.Media.NeedsUpload() {
3190			files = append(files, RequestFile{
3191				Name: fmt.Sprintf("file-%d", idx),
3192				Data: m.Media,
3193			})
3194		}
3195
3196		if m.Thumb != nil && m.Thumb.NeedsUpload() {
3197			files = append(files, RequestFile{
3198				Name: fmt.Sprintf("file-%d", idx),
3199				Data: m.Thumb,
3200			})
3201		}
3202	}
3203
3204	return files
3205}
3206
3207// prepareInputMediaForParams calls prepareInputMediaParam for each item
3208// provided and returns a new array with the correct params for a request.
3209//
3210// It is expected that files will get data from the associated function,
3211// prepareInputMediaForFiles.
3212func prepareInputMediaForParams(inputMedia []interface{}) []interface{} {
3213	newMedia := make([]interface{}, len(inputMedia))
3214	copy(newMedia, inputMedia)
3215
3216	for idx, media := range inputMedia {
3217		if param := prepareInputMediaParam(media, idx); param != nil {
3218			newMedia[idx] = param
3219		}
3220	}
3221
3222	return newMedia
3223}
3224
3225// prepareInputMediaForFiles calls prepareInputMediaFile for each item
3226// provided and returns a new array with the correct files for a request.
3227//
3228// It is expected that params will get data from the associated function,
3229// prepareInputMediaForParams.
3230func prepareInputMediaForFiles(inputMedia []interface{}) []RequestFile {
3231	files := []RequestFile{}
3232
3233	for idx, media := range inputMedia {
3234		if file := prepareInputMediaFile(media, idx); file != nil {
3235			files = append(files, file...)
3236		}
3237	}
3238
3239	return files
3240}