all repos — telegram-bot-api @ 86db6004365c757b39f7961e114875f2844a3dc5

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