all repos — telegram-bot-api @ 1deaa64606373cd1f36dfc4248ed5b70e90923f3

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// Returns the bot's Telegram Star transactions in chronological order. On success, returns a StarTransactions object.
2039type GetStarTransactionsConfig struct {
2040	// Number of transactions to skip in the response
2041	Offset int64
2042	// The maximum number of transactions to be retrieved. Values between 1-100 are accepted. Defaults to 100.
2043	Limit int64
2044}
2045
2046func (config GetStarTransactionsConfig) method() string {
2047	return "getStarTransactions"
2048}
2049
2050func (config GetStarTransactionsConfig) params() (Params, error) {
2051	params := make(Params)
2052
2053	params.AddNonZero64("offset", config.Offset)
2054	params.AddNonZero64("limit", config.Limit)
2055
2056	return params, nil
2057}
2058
2059// RefundStarPaymentConfig refunds a successful payment in Telegram Stars.
2060// Returns True on success.
2061type RefundStarPaymentConfig struct {
2062	UserID                  int64  //required
2063	TelegramPaymentChargeID string //required
2064}
2065
2066func (config RefundStarPaymentConfig) method() string {
2067	return "refundStarPayment"
2068}
2069
2070func (config RefundStarPaymentConfig) params() (Params, error) {
2071	params := make(Params)
2072
2073	params["telegram_payment_charge_id"] = config.TelegramPaymentChargeID
2074	params.AddNonZero64("user_id", config.UserID)
2075
2076	return params, nil
2077}
2078
2079// DeleteMessageConfig contains information of a message in a chat to delete.
2080type DeleteMessageConfig struct {
2081	BaseChatMessage
2082}
2083
2084func (config DeleteMessageConfig) method() string {
2085	return "deleteMessage"
2086}
2087
2088func (config DeleteMessageConfig) params() (Params, error) {
2089	return config.BaseChatMessage.params()
2090}
2091
2092// DeleteMessageConfig contains information of a messages in a chat to delete.
2093type DeleteMessagesConfig struct {
2094	BaseChatMessages
2095}
2096
2097func (config DeleteMessagesConfig) method() string {
2098	return "deleteMessages"
2099}
2100
2101func (config DeleteMessagesConfig) params() (Params, error) {
2102	return config.BaseChatMessages.params()
2103}
2104
2105// PinChatMessageConfig contains information of a message in a chat to pin.
2106type PinChatMessageConfig struct {
2107	BaseChatMessage
2108	DisableNotification bool
2109}
2110
2111func (config PinChatMessageConfig) method() string {
2112	return "pinChatMessage"
2113}
2114
2115func (config PinChatMessageConfig) params() (Params, error) {
2116	params, err := config.BaseChatMessage.params()
2117	if err != nil {
2118		return params, err
2119	}
2120
2121	params.AddBool("disable_notification", config.DisableNotification)
2122
2123	return params, nil
2124}
2125
2126// UnpinChatMessageConfig contains information of a chat message to unpin.
2127//
2128// If MessageID is not specified, it will unpin the most recent pin.
2129type UnpinChatMessageConfig struct {
2130	BaseChatMessage
2131}
2132
2133func (config UnpinChatMessageConfig) method() string {
2134	return "unpinChatMessage"
2135}
2136
2137func (config UnpinChatMessageConfig) params() (Params, error) {
2138	return config.BaseChatMessage.params()
2139}
2140
2141// UnpinAllChatMessagesConfig contains information of all messages to unpin in
2142// a chat.
2143type UnpinAllChatMessagesConfig struct {
2144	ChatConfig
2145}
2146
2147func (config UnpinAllChatMessagesConfig) method() string {
2148	return "unpinAllChatMessages"
2149}
2150
2151func (config UnpinAllChatMessagesConfig) params() (Params, error) {
2152	return config.ChatConfig.params()
2153}
2154
2155// SetChatPhotoConfig allows you to set a group, supergroup, or channel's photo.
2156type SetChatPhotoConfig struct {
2157	BaseFile
2158}
2159
2160func (config SetChatPhotoConfig) method() string {
2161	return "setChatPhoto"
2162}
2163
2164func (config SetChatPhotoConfig) files() []RequestFile {
2165	return []RequestFile{{
2166		Name: "photo",
2167		Data: config.File,
2168	}}
2169}
2170
2171// DeleteChatPhotoConfig allows you to delete a group, supergroup, or channel's photo.
2172type DeleteChatPhotoConfig struct {
2173	ChatConfig
2174}
2175
2176func (config DeleteChatPhotoConfig) method() string {
2177	return "deleteChatPhoto"
2178}
2179
2180func (config DeleteChatPhotoConfig) params() (Params, error) {
2181	return config.ChatConfig.params()
2182}
2183
2184// SetChatTitleConfig allows you to set the title of something other than a private chat.
2185type SetChatTitleConfig struct {
2186	ChatConfig
2187	Title string
2188}
2189
2190func (config SetChatTitleConfig) method() string {
2191	return "setChatTitle"
2192}
2193
2194func (config SetChatTitleConfig) params() (Params, error) {
2195	params, err := config.ChatConfig.params()
2196	if err != nil {
2197		return params, err
2198	}
2199
2200	params["title"] = config.Title
2201
2202	return params, nil
2203}
2204
2205// SetChatDescriptionConfig allows you to set the description of a supergroup or channel.
2206type SetChatDescriptionConfig struct {
2207	ChatConfig
2208	Description string
2209}
2210
2211func (config SetChatDescriptionConfig) method() string {
2212	return "setChatDescription"
2213}
2214
2215func (config SetChatDescriptionConfig) params() (Params, error) {
2216	params, err := config.ChatConfig.params()
2217	if err != nil {
2218		return params, err
2219	}
2220
2221	params["description"] = config.Description
2222
2223	return params, nil
2224}
2225
2226// GetStickerSetConfig allows you to get the stickers in a set.
2227type GetStickerSetConfig struct {
2228	Name string
2229}
2230
2231func (config GetStickerSetConfig) method() string {
2232	return "getStickerSet"
2233}
2234
2235func (config GetStickerSetConfig) params() (Params, error) {
2236	params := make(Params)
2237
2238	params["name"] = config.Name
2239
2240	return params, nil
2241}
2242
2243// GetCustomEmojiStickersConfig get information about
2244// custom emoji stickers by their identifiers.
2245type GetCustomEmojiStickersConfig struct {
2246	CustomEmojiIDs []string
2247}
2248
2249func (config GetCustomEmojiStickersConfig) params() (Params, error) {
2250	params := make(Params)
2251
2252	params.AddInterface("custom_emoji_ids", config.CustomEmojiIDs)
2253
2254	return params, nil
2255}
2256
2257func (config GetCustomEmojiStickersConfig) method() string {
2258	return "getCustomEmojiStickers"
2259}
2260
2261// UploadStickerConfig allows you to upload a sticker for use in a set later.
2262type UploadStickerConfig struct {
2263	UserID        int64
2264	Sticker       RequestFile
2265	StickerFormat string
2266}
2267
2268func (config UploadStickerConfig) method() string {
2269	return "uploadStickerFile"
2270}
2271
2272func (config UploadStickerConfig) params() (Params, error) {
2273	params := make(Params)
2274
2275	params.AddNonZero64("user_id", config.UserID)
2276	params["sticker_format"] = config.StickerFormat
2277
2278	return params, nil
2279}
2280
2281func (config UploadStickerConfig) files() []RequestFile {
2282	return []RequestFile{config.Sticker}
2283}
2284
2285// NewStickerSetConfig allows creating a new sticker set.
2286type NewStickerSetConfig struct {
2287	UserID          int64
2288	Name            string
2289	Title           string
2290	Stickers        []InputSticker
2291	StickerType     string
2292	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
2293}
2294
2295func (config NewStickerSetConfig) method() string {
2296	return "createNewStickerSet"
2297}
2298
2299func (config NewStickerSetConfig) params() (Params, error) {
2300	params := make(Params)
2301
2302	params.AddNonZero64("user_id", config.UserID)
2303	params["name"] = config.Name
2304	params["title"] = config.Title
2305
2306	params.AddBool("needs_repainting", config.NeedsRepainting)
2307	params.AddNonEmpty("sticker_type", string(config.StickerType))
2308	err := params.AddInterface("stickers", config.Stickers)
2309
2310	return params, err
2311}
2312
2313func (config NewStickerSetConfig) files() []RequestFile {
2314	requestFiles := []RequestFile{}
2315	for _, v := range config.Stickers {
2316		requestFiles = append(requestFiles, v.Sticker)
2317	}
2318	return requestFiles
2319}
2320
2321// AddStickerConfig allows you to add a sticker to a set.
2322type AddStickerConfig struct {
2323	UserID  int64
2324	Name    string
2325	Sticker InputSticker
2326}
2327
2328func (config AddStickerConfig) method() string {
2329	return "addStickerToSet"
2330}
2331
2332func (config AddStickerConfig) params() (Params, error) {
2333	params := make(Params)
2334
2335	params.AddNonZero64("user_id", config.UserID)
2336	params["name"] = config.Name
2337	err := params.AddInterface("sticker", config.Sticker)
2338	return params, err
2339}
2340
2341func (config AddStickerConfig) files() []RequestFile {
2342	return []RequestFile{config.Sticker.Sticker}
2343}
2344
2345// SetStickerPositionConfig allows you to change the position of a sticker in a set.
2346type SetStickerPositionConfig struct {
2347	Sticker  string
2348	Position int
2349}
2350
2351func (config SetStickerPositionConfig) method() string {
2352	return "setStickerPositionInSet"
2353}
2354
2355func (config SetStickerPositionConfig) params() (Params, error) {
2356	params := make(Params)
2357
2358	params["sticker"] = config.Sticker
2359	params.AddNonZero("position", config.Position)
2360
2361	return params, nil
2362}
2363
2364// SetCustomEmojiStickerSetThumbnailConfig allows you to set the thumbnail of a custom emoji sticker set
2365type SetCustomEmojiStickerSetThumbnailConfig struct {
2366	Name          string
2367	CustomEmojiID string
2368}
2369
2370func (config SetCustomEmojiStickerSetThumbnailConfig) method() string {
2371	return "setCustomEmojiStickerSetThumbnail"
2372}
2373
2374func (config SetCustomEmojiStickerSetThumbnailConfig) params() (Params, error) {
2375	params := make(Params)
2376
2377	params["name"] = config.Name
2378	params.AddNonEmpty("position", config.CustomEmojiID)
2379
2380	return params, nil
2381}
2382
2383// SetStickerSetTitle allows you to set the title of a created sticker set
2384type SetStickerSetTitleConfig struct {
2385	Name  string
2386	Title string
2387}
2388
2389func (config SetStickerSetTitleConfig) method() string {
2390	return "setStickerSetTitle"
2391}
2392
2393func (config SetStickerSetTitleConfig) params() (Params, error) {
2394	params := make(Params)
2395
2396	params["name"] = config.Name
2397	params["title"] = config.Title
2398
2399	return params, nil
2400}
2401
2402// DeleteStickerSetConfig allows you to delete a sticker set that was created by the bot.
2403type DeleteStickerSetConfig struct {
2404	Name string
2405}
2406
2407func (config DeleteStickerSetConfig) method() string {
2408	return "deleteStickerSet"
2409}
2410
2411func (config DeleteStickerSetConfig) params() (Params, error) {
2412	params := make(Params)
2413
2414	params["name"] = config.Name
2415
2416	return params, nil
2417}
2418
2419// DeleteStickerConfig allows you to delete a sticker from a set.
2420type DeleteStickerConfig struct {
2421	Sticker string
2422}
2423
2424func (config DeleteStickerConfig) method() string {
2425	return "deleteStickerFromSet"
2426}
2427
2428func (config DeleteStickerConfig) params() (Params, error) {
2429	params := make(Params)
2430
2431	params["sticker"] = config.Sticker
2432
2433	return params, nil
2434}
2435
2436// ReplaceStickerInSetConfig allows you to replace an existing sticker in a sticker set
2437// with a new one. The method is equivalent to calling deleteStickerFromSet,
2438// then addStickerToSet, then setStickerPositionInSet.
2439// Returns True on success.
2440type ReplaceStickerInSetConfig struct {
2441	UserID     int64
2442	Name       string
2443	OldSticker string
2444	Sticker    InputSticker
2445}
2446
2447func (config ReplaceStickerInSetConfig) method() string {
2448	return "replaceStickerInSet"
2449}
2450
2451func (config ReplaceStickerInSetConfig) params() (Params, error) {
2452	params := make(Params)
2453
2454	params.AddNonZero64("user_id", config.UserID)
2455	params["name"] = config.Name
2456	params["old_sticker"] = config.OldSticker
2457
2458	err := params.AddInterface("sticker", config.Sticker)
2459
2460	return params, err
2461}
2462
2463// 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
2464type SetStickerEmojiListConfig struct {
2465	Sticker   string
2466	EmojiList []string
2467}
2468
2469func (config SetStickerEmojiListConfig) method() string {
2470	return "setStickerEmojiList"
2471}
2472
2473func (config SetStickerEmojiListConfig) params() (Params, error) {
2474	params := make(Params)
2475
2476	params["sticker"] = config.Sticker
2477	err := params.AddInterface("emoji_list", config.EmojiList)
2478
2479	return params, err
2480}
2481
2482// 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.
2483type SetStickerKeywordsConfig struct {
2484	Sticker  string
2485	Keywords []string
2486}
2487
2488func (config SetStickerKeywordsConfig) method() string {
2489	return "setStickerKeywords"
2490}
2491
2492func (config SetStickerKeywordsConfig) params() (Params, error) {
2493	params := make(Params)
2494
2495	params["sticker"] = config.Sticker
2496	err := params.AddInterface("keywords", config.Keywords)
2497
2498	return params, err
2499}
2500
2501// 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
2502type SetStickerMaskPositionConfig struct {
2503	Sticker      string
2504	MaskPosition *MaskPosition
2505}
2506
2507func (config SetStickerMaskPositionConfig) method() string {
2508	return "setStickerMaskPosition"
2509}
2510
2511func (config SetStickerMaskPositionConfig) params() (Params, error) {
2512	params := make(Params)
2513
2514	params["sticker"] = config.Sticker
2515	err := params.AddInterface("keywords", config.MaskPosition)
2516
2517	return params, err
2518}
2519
2520// SetStickerSetThumbConfig allows you to set the thumbnail for a sticker set.
2521type SetStickerSetThumbConfig struct {
2522	Name   string
2523	UserID int64
2524	Thumb  RequestFileData
2525	Format string
2526}
2527
2528func (config SetStickerSetThumbConfig) method() string {
2529	return "setStickerSetThumbnail"
2530}
2531
2532func (config SetStickerSetThumbConfig) params() (Params, error) {
2533	params := make(Params)
2534
2535	params["name"] = config.Name
2536	params["format"] = config.Format
2537
2538	params.AddNonZero64("user_id", config.UserID)
2539
2540	return params, nil
2541}
2542
2543func (config SetStickerSetThumbConfig) files() []RequestFile {
2544	return []RequestFile{{
2545		Name: "thumbnail",
2546		Data: config.Thumb,
2547	}}
2548}
2549
2550// SetChatStickerSetConfig allows you to set the sticker set for a supergroup.
2551type SetChatStickerSetConfig struct {
2552	ChatConfig
2553
2554	StickerSetName string
2555}
2556
2557func (config SetChatStickerSetConfig) method() string {
2558	return "setChatStickerSet"
2559}
2560
2561func (config SetChatStickerSetConfig) params() (Params, error) {
2562	params, err := config.ChatConfig.params()
2563	if err != nil {
2564		return params, err
2565	}
2566
2567	params["sticker_set_name"] = config.StickerSetName
2568
2569	return params, nil
2570}
2571
2572// DeleteChatStickerSetConfig allows you to remove a supergroup's sticker set.
2573type DeleteChatStickerSetConfig struct {
2574	ChatConfig
2575}
2576
2577func (config DeleteChatStickerSetConfig) method() string {
2578	return "deleteChatStickerSet"
2579}
2580
2581func (config DeleteChatStickerSetConfig) params() (Params, error) {
2582	return config.ChatConfig.params()
2583}
2584
2585// GetForumTopicIconStickersConfig allows you to get custom emoji stickers,
2586// which can be used as a forum topic icon by any user.
2587type GetForumTopicIconStickersConfig struct{}
2588
2589func (config GetForumTopicIconStickersConfig) method() string {
2590	return "getForumTopicIconStickers"
2591}
2592
2593func (config GetForumTopicIconStickersConfig) params() (Params, error) {
2594	return nil, nil
2595}
2596
2597// CreateForumTopicConfig allows you to create a topic
2598// in a forum supergroup chat.
2599type CreateForumTopicConfig struct {
2600	ChatConfig
2601	Name              string
2602	IconColor         int
2603	IconCustomEmojiID string
2604}
2605
2606func (config CreateForumTopicConfig) method() string {
2607	return "createForumTopic"
2608}
2609
2610func (config CreateForumTopicConfig) params() (Params, error) {
2611	params, err := config.ChatConfig.params()
2612	if err != nil {
2613		return params, err
2614	}
2615
2616	params.AddNonEmpty("name", config.Name)
2617	params.AddNonZero("icon_color", config.IconColor)
2618	params.AddNonEmpty("icon_custom_emoji_id", config.IconCustomEmojiID)
2619
2620	return params, nil
2621}
2622
2623type BaseForum struct {
2624	ChatConfig
2625	MessageThreadID int
2626}
2627
2628func (base BaseForum) params() (Params, error) {
2629	params, err := base.ChatConfig.params()
2630	if err != nil {
2631		return params, err
2632	}
2633	params.AddNonZero("message_thread_id", base.MessageThreadID)
2634
2635	return params, nil
2636}
2637
2638// EditForumTopicConfig allows you to edit
2639// name and icon of a topic in a forum supergroup chat.
2640type EditForumTopicConfig struct {
2641	BaseForum
2642	Name              string
2643	IconCustomEmojiID string
2644}
2645
2646func (config EditForumTopicConfig) method() string {
2647	return "editForumTopic"
2648}
2649
2650func (config EditForumTopicConfig) params() (Params, error) {
2651	params, err := config.BaseForum.params()
2652	if err != nil {
2653		return params, err
2654	}
2655	params.AddNonEmpty("name", config.Name)
2656	params.AddNonEmpty("icon_custom_emoji_id", config.IconCustomEmojiID)
2657
2658	return params, nil
2659}
2660
2661// CloseForumTopicConfig allows you to close
2662// an open topic in a forum supergroup chat.
2663type CloseForumTopicConfig struct{ BaseForum }
2664
2665func (config CloseForumTopicConfig) method() string {
2666	return "closeForumTopic"
2667}
2668
2669// ReopenForumTopicConfig allows you to reopen
2670// an closed topic in a forum supergroup chat.
2671type ReopenForumTopicConfig struct{ BaseForum }
2672
2673func (config ReopenForumTopicConfig) method() string {
2674	return "reopenForumTopic"
2675}
2676
2677// DeleteForumTopicConfig allows you to delete a forum topic
2678// along with all its messages in a forum supergroup chat.
2679type DeleteForumTopicConfig struct{ BaseForum }
2680
2681func (config DeleteForumTopicConfig) method() string {
2682	return "deleteForumTopic"
2683}
2684
2685// UnpinAllForumTopicMessagesConfig allows you to clear the list
2686// of pinned messages in a forum topic.
2687type UnpinAllForumTopicMessagesConfig struct{ BaseForum }
2688
2689func (config UnpinAllForumTopicMessagesConfig) method() string {
2690	return "unpinAllForumTopicMessages"
2691}
2692
2693// UnpinAllForumTopicMessagesConfig allows you to edit the name of
2694// the 'General' topic in a forum supergroup chat.
2695// The bot must be an administrator in the chat for this to work
2696// and must have can_manage_topics administrator rights. Returns True on success.
2697type EditGeneralForumTopicConfig struct {
2698	BaseForum
2699	Name string
2700}
2701
2702func (config EditGeneralForumTopicConfig) method() string {
2703	return "editGeneralForumTopic"
2704}
2705
2706func (config EditGeneralForumTopicConfig) params() (Params, error) {
2707	params, err := config.BaseForum.params()
2708	if err != nil {
2709		return params, err
2710	}
2711	params.AddNonEmpty("name", config.Name)
2712
2713	return params, nil
2714}
2715
2716// CloseGeneralForumTopicConfig allows you to to close an open '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// Returns True on success.
2720type CloseGeneralForumTopicConfig struct{ BaseForum }
2721
2722func (config CloseGeneralForumTopicConfig) method() string {
2723	return "closeGeneralForumTopic"
2724}
2725
2726// CloseGeneralForumTopicConfig allows you to reopen a closed 'General' topic
2727// in a forum supergroup chat. The bot must be an administrator in the chat
2728// for this to work and must have the can_manage_topics administrator rights.
2729// The topic will be automatically unhidden if it was hidden.
2730// Returns True on success.
2731type ReopenGeneralForumTopicConfig struct{ BaseForum }
2732
2733func (config ReopenGeneralForumTopicConfig) method() string {
2734	return "reopenGeneralForumTopic"
2735}
2736
2737// HideGeneralForumTopicConfig allows you to hide the 'General' topic
2738// in a forum supergroup chat. The bot must be an administrator in the chat
2739// for this to work and must have the can_manage_topics administrator rights.
2740// The topic will be automatically closed if it was open.
2741// Returns True on success.
2742type HideGeneralForumTopicConfig struct{ BaseForum }
2743
2744func (config HideGeneralForumTopicConfig) method() string {
2745	return "hideGeneralForumTopic"
2746}
2747
2748// UnhideGeneralForumTopicConfig allows you to unhide the 'General' topic
2749// in a forum supergroup chat. The bot must be an administrator in the chat
2750// for this to work and must have the can_manage_topics administrator rights.
2751// Returns True on success.
2752type UnhideGeneralForumTopicConfig struct{ BaseForum }
2753
2754func (config UnhideGeneralForumTopicConfig) method() string {
2755	return "unhideGeneralForumTopic"
2756}
2757
2758// UnpinAllGeneralForumTopicMessagesConfig allows you to to clear
2759// the list of pinned messages in a General forum topic.
2760// The bot must be an administrator in the chat for this to work
2761// and must have the can_pin_messages administrator right in the supergroup.
2762// Returns True on success.
2763type UnpinAllGeneralForumTopicMessagesConfig struct{ BaseForum }
2764
2765func (config UnpinAllGeneralForumTopicMessagesConfig) method() string {
2766	return "unpinAllGeneralForumTopicMessages"
2767}
2768
2769// MediaGroupConfig allows you to send a group of media.
2770//
2771// Media consist of InputMedia items (InputMediaPhoto, InputMediaVideo).
2772type MediaGroupConfig struct {
2773	BaseChat
2774	Media []interface{}
2775}
2776
2777func (config MediaGroupConfig) method() string {
2778	return "sendMediaGroup"
2779}
2780
2781func (config MediaGroupConfig) params() (Params, error) {
2782	params, err := config.BaseChat.params()
2783	if err != nil {
2784		return nil, err
2785	}
2786
2787	err = params.AddInterface("media", prepareInputMediaForParams(config.Media))
2788
2789	return params, err
2790}
2791
2792func (config MediaGroupConfig) files() []RequestFile {
2793	return prepareInputMediaForFiles(config.Media)
2794}
2795
2796// DiceConfig contains information about a sendDice request.
2797type DiceConfig struct {
2798	BaseChat
2799	// Emoji on which the dice throw animation is based.
2800	// Currently, must be one of 🎲, 🎯, 🏀, ⚽, 🎳, or 🎰.
2801	// Dice can have values 1-6 for 🎲, 🎯, and 🎳, values 1-5 for 🏀 and ⚽,
2802	// and values 1-64 for 🎰.
2803	// Defaults to “🎲”
2804	Emoji string
2805}
2806
2807func (config DiceConfig) method() string {
2808	return "sendDice"
2809}
2810
2811func (config DiceConfig) params() (Params, error) {
2812	params, err := config.BaseChat.params()
2813	if err != nil {
2814		return params, err
2815	}
2816
2817	params.AddNonEmpty("emoji", config.Emoji)
2818
2819	return params, err
2820}
2821
2822type GetUserChatBoostsConfig struct {
2823	ChatConfig
2824	UserID int64
2825}
2826
2827func (config GetUserChatBoostsConfig) method() string {
2828	return "getUserChatBoosts"
2829}
2830
2831func (config GetUserChatBoostsConfig) params() (Params, error) {
2832	params, err := config.ChatConfig.params()
2833	if err != nil {
2834		return params, err
2835	}
2836
2837	params.AddNonZero64("user_id", config.UserID)
2838
2839	return params, err
2840}
2841
2842type (
2843	GetBusinessConnectionConfig struct {
2844		BusinessConnectionID BusinessConnectionID
2845	}
2846	BusinessConnectionID string
2847)
2848
2849func (GetBusinessConnectionConfig) method() string {
2850	return "getBusinessConnection"
2851}
2852
2853func (config GetBusinessConnectionConfig) params() (Params, error) {
2854	return config.BusinessConnectionID.params()
2855}
2856
2857func (config BusinessConnectionID) params() (Params, error) {
2858	params := make(Params)
2859
2860	params["business_connection_id"] = string(config)
2861
2862	return params, nil
2863}
2864
2865// GetMyCommandsConfig gets a list of the currently registered commands.
2866type GetMyCommandsConfig struct {
2867	Scope        *BotCommandScope
2868	LanguageCode string
2869}
2870
2871func (config GetMyCommandsConfig) method() string {
2872	return "getMyCommands"
2873}
2874
2875func (config GetMyCommandsConfig) params() (Params, error) {
2876	params := make(Params)
2877
2878	err := params.AddInterface("scope", config.Scope)
2879	params.AddNonEmpty("language_code", config.LanguageCode)
2880
2881	return params, err
2882}
2883
2884// SetMyCommandsConfig sets a list of commands the bot understands.
2885type SetMyCommandsConfig struct {
2886	Commands     []BotCommand
2887	Scope        *BotCommandScope
2888	LanguageCode string
2889}
2890
2891func (config SetMyCommandsConfig) method() string {
2892	return "setMyCommands"
2893}
2894
2895func (config SetMyCommandsConfig) params() (Params, error) {
2896	params := make(Params)
2897
2898	if err := params.AddInterface("commands", config.Commands); err != nil {
2899		return params, err
2900	}
2901	err := params.AddInterface("scope", config.Scope)
2902	params.AddNonEmpty("language_code", config.LanguageCode)
2903
2904	return params, err
2905}
2906
2907type DeleteMyCommandsConfig struct {
2908	Scope        *BotCommandScope
2909	LanguageCode string
2910}
2911
2912func (config DeleteMyCommandsConfig) method() string {
2913	return "deleteMyCommands"
2914}
2915
2916func (config DeleteMyCommandsConfig) params() (Params, error) {
2917	params := make(Params)
2918
2919	err := params.AddInterface("scope", config.Scope)
2920	params.AddNonEmpty("language_code", config.LanguageCode)
2921
2922	return params, err
2923}
2924
2925// SetMyNameConfig change the bot's name
2926type SetMyNameConfig struct {
2927	Name         string
2928	LanguageCode string
2929}
2930
2931func (config SetMyNameConfig) method() string {
2932	return "setMyName"
2933}
2934
2935func (config SetMyNameConfig) params() (Params, error) {
2936	params := make(Params)
2937
2938	params.AddNonEmpty("name", config.Name)
2939	params.AddNonEmpty("language_code", config.LanguageCode)
2940
2941	return params, nil
2942}
2943
2944type GetMyNameConfig struct {
2945	LanguageCode string
2946}
2947
2948func (config GetMyNameConfig) method() string {
2949	return "getMyName"
2950}
2951
2952func (config GetMyNameConfig) params() (Params, error) {
2953	params := make(Params)
2954
2955	params.AddNonEmpty("language_code", config.LanguageCode)
2956
2957	return params, nil
2958}
2959
2960// GetMyDescriptionConfig get the current bot description for the given user language
2961type GetMyDescriptionConfig struct {
2962	LanguageCode string
2963}
2964
2965func (config GetMyDescriptionConfig) method() string {
2966	return "getMyDescription"
2967}
2968
2969func (config GetMyDescriptionConfig) params() (Params, error) {
2970	params := make(Params)
2971
2972	params.AddNonEmpty("language_code", config.LanguageCode)
2973
2974	return params, nil
2975}
2976
2977// SetMyDescroptionConfig sets the bot's description, which is shown in the chat with the bot if the chat is empty
2978type SetMyDescriptionConfig struct {
2979	// Pass an empty string to remove the dedicated description for the given language.
2980	Description string
2981	//If empty, the description will be applied to all users for whose language there is no dedicated description.
2982	LanguageCode string
2983}
2984
2985func (config SetMyDescriptionConfig) method() string {
2986	return "setMyDescription"
2987}
2988
2989func (config SetMyDescriptionConfig) params() (Params, error) {
2990	params := make(Params)
2991
2992	params.AddNonEmpty("description", config.Description)
2993	params.AddNonEmpty("language_code", config.LanguageCode)
2994
2995	return params, nil
2996}
2997
2998// GetMyShortDescriptionConfig get the current bot short description for the given user language
2999type GetMyShortDescriptionConfig struct {
3000	LanguageCode string
3001}
3002
3003func (config GetMyShortDescriptionConfig) method() string {
3004	return "getMyShortDescription"
3005}
3006
3007func (config GetMyShortDescriptionConfig) params() (Params, error) {
3008	params := make(Params)
3009
3010	params.AddNonEmpty("language_code", config.LanguageCode)
3011
3012	return params, nil
3013}
3014
3015// 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.
3016type SetMyShortDescriptionConfig struct {
3017	// New short description for the bot; 0-120 characters.
3018	//
3019	//Pass an empty string to remove the dedicated short description for the given language.
3020	ShortDescription string
3021	//A two-letter ISO 639-1 language code.
3022	//
3023	//If empty, the short description will be applied to all users for whose language there is no dedicated short description.
3024	LanguageCode string
3025}
3026
3027func (config SetMyShortDescriptionConfig) method() string {
3028	return "setMyShortDescription"
3029}
3030
3031func (config SetMyShortDescriptionConfig) params() (Params, error) {
3032	params := make(Params)
3033
3034	params.AddNonEmpty("short_description", config.ShortDescription)
3035	params.AddNonEmpty("language_code", config.LanguageCode)
3036
3037	return params, nil
3038}
3039
3040// SetChatMenuButtonConfig changes the bot's menu button in a private chat,
3041// or the default menu button.
3042type SetChatMenuButtonConfig struct {
3043	ChatConfig
3044
3045	MenuButton *MenuButton
3046}
3047
3048func (config SetChatMenuButtonConfig) method() string {
3049	return "setChatMenuButton"
3050}
3051
3052func (config SetChatMenuButtonConfig) params() (Params, error) {
3053	params, err := config.ChatConfig.params()
3054	if err != nil {
3055		return params, err
3056	}
3057
3058	err = params.AddInterface("menu_button", config.MenuButton)
3059
3060	return params, err
3061}
3062
3063type GetChatMenuButtonConfig struct {
3064	ChatConfig
3065}
3066
3067func (config GetChatMenuButtonConfig) method() string {
3068	return "getChatMenuButton"
3069}
3070
3071func (config GetChatMenuButtonConfig) params() (Params, error) {
3072	return config.ChatConfig.params()
3073}
3074
3075type SetMyDefaultAdministratorRightsConfig struct {
3076	Rights      ChatAdministratorRights
3077	ForChannels bool
3078}
3079
3080func (config SetMyDefaultAdministratorRightsConfig) method() string {
3081	return "setMyDefaultAdministratorRights"
3082}
3083
3084func (config SetMyDefaultAdministratorRightsConfig) params() (Params, error) {
3085	params := make(Params)
3086
3087	err := params.AddInterface("rights", config.Rights)
3088	params.AddBool("for_channels", config.ForChannels)
3089
3090	return params, err
3091}
3092
3093type GetMyDefaultAdministratorRightsConfig struct {
3094	ForChannels bool
3095}
3096
3097func (config GetMyDefaultAdministratorRightsConfig) method() string {
3098	return "getMyDefaultAdministratorRights"
3099}
3100
3101func (config GetMyDefaultAdministratorRightsConfig) params() (Params, error) {
3102	params := make(Params)
3103
3104	params.AddBool("for_channels", config.ForChannels)
3105
3106	return params, nil
3107}
3108
3109// prepareInputMediaParam evaluates a single InputMedia and determines if it
3110// needs to be modified for a successful upload. If it returns nil, then the
3111// value does not need to be included in the params. Otherwise, it will return
3112// the same type as was originally provided.
3113//
3114// The idx is used to calculate the file field name. If you only have a single
3115// file, 0 may be used. It is formatted into "attach://file-%d" for the primary
3116// media and "attach://file-%d-thumb" for thumbnails.
3117//
3118// It is expected to be used in conjunction with prepareInputMediaFile.
3119func prepareInputMediaParam(inputMedia interface{}, idx int) interface{} {
3120	switch m := inputMedia.(type) {
3121	case InputMediaPhoto:
3122		if m.Media.NeedsUpload() {
3123			m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
3124		}
3125
3126		return m
3127	case InputMediaVideo:
3128		if m.Media.NeedsUpload() {
3129			m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
3130		}
3131
3132		if m.Thumb != nil && m.Thumb.NeedsUpload() {
3133			m.Thumb = fileAttach(fmt.Sprintf("attach://file-%d-thumb", idx))
3134		}
3135
3136		return m
3137	case InputMediaAudio:
3138		if m.Media.NeedsUpload() {
3139			m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
3140		}
3141
3142		if m.Thumb != nil && m.Thumb.NeedsUpload() {
3143			m.Thumb = fileAttach(fmt.Sprintf("attach://file-%d-thumb", idx))
3144		}
3145
3146		return m
3147	case InputMediaDocument:
3148		if m.Media.NeedsUpload() {
3149			m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
3150		}
3151
3152		if m.Thumb != nil && m.Thumb.NeedsUpload() {
3153			m.Thumb = fileAttach(fmt.Sprintf("attach://file-%d-thumb", idx))
3154		}
3155
3156		return m
3157	}
3158
3159	return nil
3160}
3161
3162// prepareInputMediaFile generates an array of RequestFile to provide for
3163// Fileable's files method. It returns an array as a single InputMedia may have
3164// multiple files, for the primary media and a thumbnail.
3165//
3166// The idx parameter is used to generate file field names. It uses the names
3167// "file-%d" for the main file and "file-%d-thumb" for the thumbnail.
3168//
3169// It is expected to be used in conjunction with prepareInputMediaParam.
3170func prepareInputMediaFile(inputMedia interface{}, idx int) []RequestFile {
3171	files := []RequestFile{}
3172
3173	switch m := inputMedia.(type) {
3174	case InputMediaPhoto:
3175		if m.Media.NeedsUpload() {
3176			files = append(files, RequestFile{
3177				Name: fmt.Sprintf("file-%d", idx),
3178				Data: m.Media,
3179			})
3180		}
3181	case InputMediaVideo:
3182		if m.Media.NeedsUpload() {
3183			files = append(files, RequestFile{
3184				Name: fmt.Sprintf("file-%d", idx),
3185				Data: m.Media,
3186			})
3187		}
3188
3189		if m.Thumb != nil && m.Thumb.NeedsUpload() {
3190			files = append(files, RequestFile{
3191				Name: fmt.Sprintf("file-%d", idx),
3192				Data: m.Thumb,
3193			})
3194		}
3195	case InputMediaDocument:
3196		if m.Media.NeedsUpload() {
3197			files = append(files, RequestFile{
3198				Name: fmt.Sprintf("file-%d", idx),
3199				Data: m.Media,
3200			})
3201		}
3202
3203		if m.Thumb != nil && m.Thumb.NeedsUpload() {
3204			files = append(files, RequestFile{
3205				Name: fmt.Sprintf("file-%d", idx),
3206				Data: m.Thumb,
3207			})
3208		}
3209	case InputMediaAudio:
3210		if m.Media.NeedsUpload() {
3211			files = append(files, RequestFile{
3212				Name: fmt.Sprintf("file-%d", idx),
3213				Data: m.Media,
3214			})
3215		}
3216
3217		if m.Thumb != nil && m.Thumb.NeedsUpload() {
3218			files = append(files, RequestFile{
3219				Name: fmt.Sprintf("file-%d", idx),
3220				Data: m.Thumb,
3221			})
3222		}
3223	}
3224
3225	return files
3226}
3227
3228// prepareInputMediaForParams calls prepareInputMediaParam for each item
3229// provided and returns a new array with the correct params for a request.
3230//
3231// It is expected that files will get data from the associated function,
3232// prepareInputMediaForFiles.
3233func prepareInputMediaForParams(inputMedia []interface{}) []interface{} {
3234	newMedia := make([]interface{}, len(inputMedia))
3235	copy(newMedia, inputMedia)
3236
3237	for idx, media := range inputMedia {
3238		if param := prepareInputMediaParam(media, idx); param != nil {
3239			newMedia[idx] = param
3240		}
3241	}
3242
3243	return newMedia
3244}
3245
3246// prepareInputMediaForFiles calls prepareInputMediaFile for each item
3247// provided and returns a new array with the correct files for a request.
3248//
3249// It is expected that params will get data from the associated function,
3250// prepareInputMediaForParams.
3251func prepareInputMediaForFiles(inputMedia []interface{}) []RequestFile {
3252	files := []RequestFile{}
3253
3254	for idx, media := range inputMedia {
3255		if file := prepareInputMediaFile(media, idx); file != nil {
3256			files = append(files, file...)
3257		}
3258	}
3259
3260	return files
3261}