all repos — telegram-bot-api @ 45f563879fbcfee2a821f03039e4eaf16074033e

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