all repos — telegram-bot-api @ 7d82083b039394e83ef7319853e29a3d4ef66b60

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	//
1278	Text string `json:"text"`
1279	//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.
1280	//
1281	//Optional
1282	WebApp *WebAppInfo `json:"web_app,omitempty"`
1283	// 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.
1284	//
1285	//Optional
1286	StartParam string `json:"start_parameter,omitempty"`
1287}
1288
1289// InlineConfig contains information on making an InlineQuery response.
1290type InlineConfig struct {
1291	InlineQueryID string                    `json:"inline_query_id"`
1292	Results       []interface{}             `json:"results"`
1293	CacheTime     int                       `json:"cache_time"`
1294	IsPersonal    bool                      `json:"is_personal"`
1295	NextOffset    string                    `json:"next_offset"`
1296	Button        *InlineQueryResultsButton `json:"button,omitempty"`
1297}
1298
1299func (config InlineConfig) method() string {
1300	return "answerInlineQuery"
1301}
1302
1303func (config InlineConfig) params() (Params, error) {
1304	params := make(Params)
1305
1306	params["inline_query_id"] = config.InlineQueryID
1307	params.AddNonZero("cache_time", config.CacheTime)
1308	params.AddBool("is_personal", config.IsPersonal)
1309	params.AddNonEmpty("next_offset", config.NextOffset)
1310	err := params.AddInterface("button", config.Button)
1311	if err != nil {
1312		return params, err
1313	}
1314	err = params.AddInterface("results", config.Results)
1315
1316	return params, err
1317}
1318
1319// AnswerWebAppQueryConfig is used to set the result of an interaction with a
1320// Web App and send a corresponding message on behalf of the user to the chat
1321// from which the query originated.
1322type AnswerWebAppQueryConfig struct {
1323	// WebAppQueryID is the unique identifier for the query to be answered.
1324	WebAppQueryID string `json:"web_app_query_id"`
1325	// Result is an InlineQueryResult object describing the message to be sent.
1326	Result interface{} `json:"result"`
1327}
1328
1329func (config AnswerWebAppQueryConfig) method() string {
1330	return "answerWebAppQuery"
1331}
1332
1333func (config AnswerWebAppQueryConfig) params() (Params, error) {
1334	params := make(Params)
1335
1336	params["web_app_query_id"] = config.WebAppQueryID
1337	err := params.AddInterface("result", config.Result)
1338
1339	return params, err
1340}
1341
1342// CallbackConfig contains information on making a CallbackQuery response.
1343type CallbackConfig struct {
1344	CallbackQueryID string `json:"callback_query_id"`
1345	Text            string `json:"text"`
1346	ShowAlert       bool   `json:"show_alert"`
1347	URL             string `json:"url"`
1348	CacheTime       int    `json:"cache_time"`
1349}
1350
1351func (config CallbackConfig) method() string {
1352	return "answerCallbackQuery"
1353}
1354
1355func (config CallbackConfig) params() (Params, error) {
1356	params := make(Params)
1357
1358	params["callback_query_id"] = config.CallbackQueryID
1359	params.AddNonEmpty("text", config.Text)
1360	params.AddBool("show_alert", config.ShowAlert)
1361	params.AddNonEmpty("url", config.URL)
1362	params.AddNonZero("cache_time", config.CacheTime)
1363
1364	return params, nil
1365}
1366
1367// ChatMemberConfig contains information about a user in a chat for use
1368// with administrative functions such as kicking or unbanning a user.
1369type ChatMemberConfig struct {
1370	ChatID             int64
1371	SuperGroupUsername string
1372	ChannelUsername    string
1373	UserID             int64
1374}
1375
1376// UnbanChatMemberConfig allows you to unban a user.
1377type UnbanChatMemberConfig struct {
1378	ChatMemberConfig
1379	OnlyIfBanned bool
1380}
1381
1382func (config UnbanChatMemberConfig) method() string {
1383	return "unbanChatMember"
1384}
1385
1386func (config UnbanChatMemberConfig) params() (Params, error) {
1387	params := make(Params)
1388
1389	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername)
1390	params.AddNonZero64("user_id", config.UserID)
1391	params.AddBool("only_if_banned", config.OnlyIfBanned)
1392
1393	return params, nil
1394}
1395
1396// BanChatMemberConfig contains extra fields to kick user.
1397type BanChatMemberConfig struct {
1398	ChatMemberConfig
1399	UntilDate      int64
1400	RevokeMessages bool
1401}
1402
1403func (config BanChatMemberConfig) method() string {
1404	return "banChatMember"
1405}
1406
1407func (config BanChatMemberConfig) params() (Params, error) {
1408	params := make(Params)
1409
1410	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1411	params.AddNonZero64("user_id", config.UserID)
1412	params.AddNonZero64("until_date", config.UntilDate)
1413	params.AddBool("revoke_messages", config.RevokeMessages)
1414
1415	return params, nil
1416}
1417
1418// KickChatMemberConfig contains extra fields to ban user.
1419//
1420// This was renamed to BanChatMember in later versions of the Telegram Bot API.
1421type KickChatMemberConfig = BanChatMemberConfig
1422
1423// RestrictChatMemberConfig contains fields to restrict members of chat
1424type RestrictChatMemberConfig struct {
1425	ChatMemberConfig
1426	UntilDate                     int64
1427	UseIndependentChatPermissions bool
1428	Permissions                   *ChatPermissions
1429}
1430
1431func (config RestrictChatMemberConfig) method() string {
1432	return "restrictChatMember"
1433}
1434
1435func (config RestrictChatMemberConfig) params() (Params, error) {
1436	params := make(Params)
1437
1438	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername)
1439	params.AddNonZero64("user_id", config.UserID)
1440	params.AddBool("use_independent_chat_permissions", config.UseIndependentChatPermissions)
1441
1442	err := params.AddInterface("permissions", config.Permissions)
1443	params.AddNonZero64("until_date", config.UntilDate)
1444
1445	return params, err
1446}
1447
1448// PromoteChatMemberConfig contains fields to promote members of chat
1449type PromoteChatMemberConfig struct {
1450	ChatMemberConfig
1451	IsAnonymous         bool
1452	CanManageChat       bool
1453	CanChangeInfo       bool
1454	CanPostMessages     bool
1455	CanEditMessages     bool
1456	CanDeleteMessages   bool
1457	CanManageVideoChats bool
1458	CanInviteUsers      bool
1459	CanRestrictMembers  bool
1460	CanPinMessages      bool
1461	CanPromoteMembers   bool
1462	CanManageTopics     bool
1463}
1464
1465func (config PromoteChatMemberConfig) method() string {
1466	return "promoteChatMember"
1467}
1468
1469func (config PromoteChatMemberConfig) params() (Params, error) {
1470	params := make(Params)
1471
1472	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername)
1473	params.AddNonZero64("user_id", config.UserID)
1474
1475	params.AddBool("is_anonymous", config.IsAnonymous)
1476	params.AddBool("can_manage_chat", config.CanManageChat)
1477	params.AddBool("can_change_info", config.CanChangeInfo)
1478	params.AddBool("can_post_messages", config.CanPostMessages)
1479	params.AddBool("can_edit_messages", config.CanEditMessages)
1480	params.AddBool("can_delete_messages", config.CanDeleteMessages)
1481	params.AddBool("can_manage_video_chats", config.CanManageVideoChats)
1482	params.AddBool("can_invite_users", config.CanInviteUsers)
1483	params.AddBool("can_restrict_members", config.CanRestrictMembers)
1484	params.AddBool("can_pin_messages", config.CanPinMessages)
1485	params.AddBool("can_promote_members", config.CanPromoteMembers)
1486	params.AddBool("can_manage_topics", config.CanManageTopics)
1487
1488	return params, nil
1489}
1490
1491// SetChatAdministratorCustomTitle sets the title of an administrative user
1492// promoted by the bot for a chat.
1493type SetChatAdministratorCustomTitle struct {
1494	ChatMemberConfig
1495	CustomTitle string
1496}
1497
1498func (SetChatAdministratorCustomTitle) method() string {
1499	return "setChatAdministratorCustomTitle"
1500}
1501
1502func (config SetChatAdministratorCustomTitle) params() (Params, error) {
1503	params := make(Params)
1504
1505	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername)
1506	params.AddNonZero64("user_id", config.UserID)
1507	params.AddNonEmpty("custom_title", config.CustomTitle)
1508
1509	return params, nil
1510}
1511
1512// BanChatSenderChatConfig bans a channel chat in a supergroup or a channel. The
1513// owner of the chat will not be able to send messages and join live streams on
1514// behalf of the chat, unless it is unbanned first. The bot must be an
1515// administrator in the supergroup or channel for this to work and must have the
1516// appropriate administrator rights.
1517type BanChatSenderChatConfig struct {
1518	ChatID          int64
1519	ChannelUsername string
1520	SenderChatID    int64
1521	UntilDate       int
1522}
1523
1524func (config BanChatSenderChatConfig) method() string {
1525	return "banChatSenderChat"
1526}
1527
1528func (config BanChatSenderChatConfig) params() (Params, error) {
1529	params := make(Params)
1530
1531	_ = params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1532	params.AddNonZero64("sender_chat_id", config.SenderChatID)
1533	params.AddNonZero("until_date", config.UntilDate)
1534
1535	return params, nil
1536}
1537
1538// UnbanChatSenderChatConfig unbans a previously banned channel chat in a
1539// supergroup or channel. The bot must be an administrator for this to work and
1540// must have the appropriate administrator rights.
1541type UnbanChatSenderChatConfig struct {
1542	ChatID          int64
1543	ChannelUsername string
1544	SenderChatID    int64
1545}
1546
1547func (config UnbanChatSenderChatConfig) method() string {
1548	return "unbanChatSenderChat"
1549}
1550
1551func (config UnbanChatSenderChatConfig) params() (Params, error) {
1552	params := make(Params)
1553
1554	_ = params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1555	params.AddNonZero64("sender_chat_id", config.SenderChatID)
1556
1557	return params, nil
1558}
1559
1560// ChatConfig contains information about getting information on a chat.
1561type ChatConfig struct {
1562	ChatID             int64
1563	SuperGroupUsername string
1564}
1565
1566func (config ChatConfig) params() (Params, error) {
1567	params := make(Params)
1568
1569	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1570
1571	return params, nil
1572}
1573
1574// ChatInfoConfig contains information about getting chat information.
1575type ChatInfoConfig struct {
1576	ChatConfig
1577}
1578
1579func (ChatInfoConfig) method() string {
1580	return "getChat"
1581}
1582
1583// ChatMemberCountConfig contains information about getting the number of users in a chat.
1584type ChatMemberCountConfig struct {
1585	ChatConfig
1586}
1587
1588func (ChatMemberCountConfig) method() string {
1589	return "getChatMembersCount"
1590}
1591
1592// ChatAdministratorsConfig contains information about getting chat administrators.
1593type ChatAdministratorsConfig struct {
1594	ChatConfig
1595}
1596
1597func (ChatAdministratorsConfig) method() string {
1598	return "getChatAdministrators"
1599}
1600
1601// SetChatPermissionsConfig allows you to set default permissions for the
1602// members in a group. The bot must be an administrator and have rights to
1603// restrict members.
1604type SetChatPermissionsConfig struct {
1605	ChatConfig
1606	UseIndependentChatPermissions bool
1607	Permissions                   *ChatPermissions
1608}
1609
1610func (SetChatPermissionsConfig) method() string {
1611	return "setChatPermissions"
1612}
1613
1614func (config SetChatPermissionsConfig) params() (Params, error) {
1615	params := make(Params)
1616
1617	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1618	params.AddBool("use_independent_chat_permissions", config.UseIndependentChatPermissions)
1619	err := params.AddInterface("permissions", config.Permissions)
1620
1621	return params, err
1622}
1623
1624// ChatInviteLinkConfig contains information about getting a chat link.
1625//
1626// Note that generating a new link will revoke any previous links.
1627type ChatInviteLinkConfig struct {
1628	ChatConfig
1629}
1630
1631func (ChatInviteLinkConfig) method() string {
1632	return "exportChatInviteLink"
1633}
1634
1635func (config ChatInviteLinkConfig) params() (Params, error) {
1636	params := make(Params)
1637
1638	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1639
1640	return params, nil
1641}
1642
1643// CreateChatInviteLinkConfig allows you to create an additional invite link for
1644// a chat. The bot must be an administrator in the chat for this to work and
1645// must have the appropriate admin rights. The link can be revoked using the
1646// RevokeChatInviteLinkConfig.
1647type CreateChatInviteLinkConfig struct {
1648	ChatConfig
1649	Name               string
1650	ExpireDate         int
1651	MemberLimit        int
1652	CreatesJoinRequest bool
1653}
1654
1655func (CreateChatInviteLinkConfig) method() string {
1656	return "createChatInviteLink"
1657}
1658
1659func (config CreateChatInviteLinkConfig) params() (Params, error) {
1660	params := make(Params)
1661
1662	params.AddNonEmpty("name", config.Name)
1663	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1664	params.AddNonZero("expire_date", config.ExpireDate)
1665	params.AddNonZero("member_limit", config.MemberLimit)
1666	params.AddBool("creates_join_request", config.CreatesJoinRequest)
1667
1668	return params, nil
1669}
1670
1671// EditChatInviteLinkConfig allows you to edit a non-primary invite link created
1672// by the bot. The bot must be an administrator in the chat for this to work and
1673// must have the appropriate admin rights.
1674type EditChatInviteLinkConfig struct {
1675	ChatConfig
1676	InviteLink         string
1677	Name               string
1678	ExpireDate         int
1679	MemberLimit        int
1680	CreatesJoinRequest bool
1681}
1682
1683func (EditChatInviteLinkConfig) method() string {
1684	return "editChatInviteLink"
1685}
1686
1687func (config EditChatInviteLinkConfig) params() (Params, error) {
1688	params := make(Params)
1689
1690	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1691	params.AddNonEmpty("name", config.Name)
1692	params["invite_link"] = config.InviteLink
1693	params.AddNonZero("expire_date", config.ExpireDate)
1694	params.AddNonZero("member_limit", config.MemberLimit)
1695	params.AddBool("creates_join_request", config.CreatesJoinRequest)
1696
1697	return params, nil
1698}
1699
1700// RevokeChatInviteLinkConfig allows you to revoke an invite link created by the
1701// bot. If the primary link is revoked, a new link is automatically generated.
1702// The bot must be an administrator in the chat for this to work and must have
1703// the appropriate admin rights.
1704type RevokeChatInviteLinkConfig struct {
1705	ChatConfig
1706	InviteLink string
1707}
1708
1709func (RevokeChatInviteLinkConfig) method() string {
1710	return "revokeChatInviteLink"
1711}
1712
1713func (config RevokeChatInviteLinkConfig) params() (Params, error) {
1714	params := make(Params)
1715
1716	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1717	params["invite_link"] = config.InviteLink
1718
1719	return params, nil
1720}
1721
1722// ApproveChatJoinRequestConfig allows you to approve a chat join request.
1723type ApproveChatJoinRequestConfig struct {
1724	ChatConfig
1725	UserID int64
1726}
1727
1728func (ApproveChatJoinRequestConfig) method() string {
1729	return "approveChatJoinRequest"
1730}
1731
1732func (config ApproveChatJoinRequestConfig) params() (Params, error) {
1733	params := make(Params)
1734
1735	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1736	params.AddNonZero("user_id", int(config.UserID))
1737
1738	return params, nil
1739}
1740
1741// DeclineChatJoinRequest allows you to decline a chat join request.
1742type DeclineChatJoinRequest struct {
1743	ChatConfig
1744	UserID int64
1745}
1746
1747func (DeclineChatJoinRequest) method() string {
1748	return "declineChatJoinRequest"
1749}
1750
1751func (config DeclineChatJoinRequest) params() (Params, error) {
1752	params := make(Params)
1753
1754	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1755	params.AddNonZero("user_id", int(config.UserID))
1756
1757	return params, nil
1758}
1759
1760// LeaveChatConfig allows you to leave a chat.
1761type LeaveChatConfig struct {
1762	ChatID          int64
1763	ChannelUsername string
1764}
1765
1766func (config LeaveChatConfig) method() string {
1767	return "leaveChat"
1768}
1769
1770func (config LeaveChatConfig) params() (Params, error) {
1771	params := make(Params)
1772
1773	params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1774
1775	return params, nil
1776}
1777
1778// ChatConfigWithUser contains information about a chat and a user.
1779type ChatConfigWithUser struct {
1780	ChatID             int64
1781	SuperGroupUsername string
1782	UserID             int64
1783}
1784
1785func (config ChatConfigWithUser) params() (Params, error) {
1786	params := make(Params)
1787
1788	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1789	params.AddNonZero64("user_id", config.UserID)
1790
1791	return params, nil
1792}
1793
1794// GetChatMemberConfig is information about getting a specific member in a chat.
1795type GetChatMemberConfig struct {
1796	ChatConfigWithUser
1797}
1798
1799func (GetChatMemberConfig) method() string {
1800	return "getChatMember"
1801}
1802
1803// InvoiceConfig contains information for sendInvoice request.
1804type InvoiceConfig struct {
1805	BaseChat
1806	Title                     string         // required
1807	Description               string         // required
1808	Payload                   string         // required
1809	ProviderToken             string         // required
1810	Currency                  string         // required
1811	Prices                    []LabeledPrice // required
1812	MaxTipAmount              int
1813	SuggestedTipAmounts       []int
1814	StartParameter            string
1815	ProviderData              string
1816	PhotoURL                  string
1817	PhotoSize                 int
1818	PhotoWidth                int
1819	PhotoHeight               int
1820	NeedName                  bool
1821	NeedPhoneNumber           bool
1822	NeedEmail                 bool
1823	NeedShippingAddress       bool
1824	SendPhoneNumberToProvider bool
1825	SendEmailToProvider       bool
1826	IsFlexible                bool
1827}
1828
1829func (config InvoiceConfig) params() (Params, error) {
1830	params, err := config.BaseChat.params()
1831	if err != nil {
1832		return params, err
1833	}
1834
1835	params["title"] = config.Title
1836	params["description"] = config.Description
1837	params["payload"] = config.Payload
1838	params["provider_token"] = config.ProviderToken
1839	params["currency"] = config.Currency
1840	if err = params.AddInterface("prices", config.Prices); err != nil {
1841		return params, err
1842	}
1843
1844	params.AddNonZero("max_tip_amount", config.MaxTipAmount)
1845	err = params.AddInterface("suggested_tip_amounts", config.SuggestedTipAmounts)
1846	params.AddNonEmpty("start_parameter", config.StartParameter)
1847	params.AddNonEmpty("provider_data", config.ProviderData)
1848	params.AddNonEmpty("photo_url", config.PhotoURL)
1849	params.AddNonZero("photo_size", config.PhotoSize)
1850	params.AddNonZero("photo_width", config.PhotoWidth)
1851	params.AddNonZero("photo_height", config.PhotoHeight)
1852	params.AddBool("need_name", config.NeedName)
1853	params.AddBool("need_phone_number", config.NeedPhoneNumber)
1854	params.AddBool("need_email", config.NeedEmail)
1855	params.AddBool("need_shipping_address", config.NeedShippingAddress)
1856	params.AddBool("is_flexible", config.IsFlexible)
1857	params.AddBool("send_phone_number_to_provider", config.SendPhoneNumberToProvider)
1858	params.AddBool("send_email_to_provider", config.SendEmailToProvider)
1859
1860	return params, err
1861}
1862
1863func (config InvoiceConfig) method() string {
1864	return "sendInvoice"
1865}
1866
1867// InvoiceLinkConfig contains information for createInvoiceLink method
1868type InvoiceLinkConfig struct {
1869	Title                     string         //Required
1870	Description               string         //Required
1871	Payload                   string         //Required
1872	ProviderToken             string         //Required
1873	Currency                  string         //Required
1874	Prices                    []LabeledPrice //Required
1875	MaxTipAmount              int
1876	SuggestedTipAmounts       []int
1877	ProviderData              string
1878	PhotoURL                  string
1879	PhotoSize                 int
1880	PhotoWidth                int
1881	PhotoHeight               int
1882	NeedName                  bool
1883	NeedPhoneNumber           bool
1884	NeedEmail                 bool
1885	NeedShippingAddress       bool
1886	SendPhoneNumberToProvider bool
1887	SendEmailToProvider       bool
1888	IsFlexible                bool
1889}
1890
1891func (config InvoiceLinkConfig) params() (Params, error) {
1892	params := make(Params)
1893
1894	params["title"] = config.Title
1895	params["description"] = config.Description
1896	params["payload"] = config.Payload
1897	params["provider_token"] = config.ProviderToken
1898	params["currency"] = config.Currency
1899	if err := params.AddInterface("prices", config.Prices); err != nil {
1900		return params, err
1901	}
1902
1903	params.AddNonZero("max_tip_amount", config.MaxTipAmount)
1904	err := params.AddInterface("suggested_tip_amounts", config.SuggestedTipAmounts)
1905	params.AddNonEmpty("provider_data", config.ProviderData)
1906	params.AddNonEmpty("photo_url", config.PhotoURL)
1907	params.AddNonZero("photo_size", config.PhotoSize)
1908	params.AddNonZero("photo_width", config.PhotoWidth)
1909	params.AddNonZero("photo_height", config.PhotoHeight)
1910	params.AddBool("need_name", config.NeedName)
1911	params.AddBool("need_phone_number", config.NeedPhoneNumber)
1912	params.AddBool("need_email", config.NeedEmail)
1913	params.AddBool("need_shipping_address", config.NeedShippingAddress)
1914	params.AddBool("send_phone_number_to_provider", config.SendPhoneNumberToProvider)
1915	params.AddBool("send_email_to_provider", config.SendEmailToProvider)
1916	params.AddBool("is_flexible", config.IsFlexible)
1917
1918	return params, err
1919}
1920
1921func (config InvoiceLinkConfig) method() string {
1922	return "createInvoiceLink"
1923}
1924
1925// ShippingConfig contains information for answerShippingQuery request.
1926type ShippingConfig struct {
1927	ShippingQueryID string // required
1928	OK              bool   // required
1929	ShippingOptions []ShippingOption
1930	ErrorMessage    string
1931}
1932
1933func (config ShippingConfig) method() string {
1934	return "answerShippingQuery"
1935}
1936
1937func (config ShippingConfig) params() (Params, error) {
1938	params := make(Params)
1939
1940	params["shipping_query_id"] = config.ShippingQueryID
1941	params.AddBool("ok", config.OK)
1942	err := params.AddInterface("shipping_options", config.ShippingOptions)
1943	params.AddNonEmpty("error_message", config.ErrorMessage)
1944
1945	return params, err
1946}
1947
1948// PreCheckoutConfig contains information for answerPreCheckoutQuery request.
1949type PreCheckoutConfig struct {
1950	PreCheckoutQueryID string // required
1951	OK                 bool   // required
1952	ErrorMessage       string
1953}
1954
1955func (config PreCheckoutConfig) method() string {
1956	return "answerPreCheckoutQuery"
1957}
1958
1959func (config PreCheckoutConfig) params() (Params, error) {
1960	params := make(Params)
1961
1962	params["pre_checkout_query_id"] = config.PreCheckoutQueryID
1963	params.AddBool("ok", config.OK)
1964	params.AddNonEmpty("error_message", config.ErrorMessage)
1965
1966	return params, nil
1967}
1968
1969// DeleteMessageConfig contains information of a message in a chat to delete.
1970type DeleteMessageConfig struct {
1971	ChannelUsername string
1972	ChatID          int64
1973	MessageID       int
1974}
1975
1976func (config DeleteMessageConfig) method() string {
1977	return "deleteMessage"
1978}
1979
1980func (config DeleteMessageConfig) params() (Params, error) {
1981	params := make(Params)
1982
1983	params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1984	params.AddNonZero("message_id", config.MessageID)
1985
1986	return params, nil
1987}
1988
1989// PinChatMessageConfig contains information of a message in a chat to pin.
1990type PinChatMessageConfig struct {
1991	ChatID              int64
1992	ChannelUsername     string
1993	MessageID           int
1994	DisableNotification bool
1995}
1996
1997func (config PinChatMessageConfig) method() string {
1998	return "pinChatMessage"
1999}
2000
2001func (config PinChatMessageConfig) params() (Params, error) {
2002	params := make(Params)
2003
2004	params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
2005	params.AddNonZero("message_id", config.MessageID)
2006	params.AddBool("disable_notification", config.DisableNotification)
2007
2008	return params, nil
2009}
2010
2011// UnpinChatMessageConfig contains information of a chat message to unpin.
2012//
2013// If MessageID is not specified, it will unpin the most recent pin.
2014type UnpinChatMessageConfig struct {
2015	ChatID          int64
2016	ChannelUsername string
2017	MessageID       int
2018}
2019
2020func (config UnpinChatMessageConfig) method() string {
2021	return "unpinChatMessage"
2022}
2023
2024func (config UnpinChatMessageConfig) params() (Params, error) {
2025	params := make(Params)
2026
2027	params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
2028	params.AddNonZero("message_id", config.MessageID)
2029
2030	return params, nil
2031}
2032
2033// UnpinAllChatMessagesConfig contains information of all messages to unpin in
2034// a chat.
2035type UnpinAllChatMessagesConfig struct {
2036	ChatID          int64
2037	ChannelUsername string
2038}
2039
2040func (config UnpinAllChatMessagesConfig) method() string {
2041	return "unpinAllChatMessages"
2042}
2043
2044func (config UnpinAllChatMessagesConfig) params() (Params, error) {
2045	params := make(Params)
2046
2047	params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
2048
2049	return params, nil
2050}
2051
2052// SetChatPhotoConfig allows you to set a group, supergroup, or channel's photo.
2053type SetChatPhotoConfig struct {
2054	BaseFile
2055}
2056
2057func (config SetChatPhotoConfig) method() string {
2058	return "setChatPhoto"
2059}
2060
2061func (config SetChatPhotoConfig) files() []RequestFile {
2062	return []RequestFile{{
2063		Name: "photo",
2064		Data: config.File,
2065	}}
2066}
2067
2068// DeleteChatPhotoConfig allows you to delete a group, supergroup, or channel's photo.
2069type DeleteChatPhotoConfig struct {
2070	ChatID          int64
2071	ChannelUsername string
2072}
2073
2074func (config DeleteChatPhotoConfig) method() string {
2075	return "deleteChatPhoto"
2076}
2077
2078func (config DeleteChatPhotoConfig) params() (Params, error) {
2079	params := make(Params)
2080
2081	params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
2082
2083	return params, nil
2084}
2085
2086// SetChatTitleConfig allows you to set the title of something other than a private chat.
2087type SetChatTitleConfig struct {
2088	ChatID          int64
2089	ChannelUsername string
2090
2091	Title string
2092}
2093
2094func (config SetChatTitleConfig) method() string {
2095	return "setChatTitle"
2096}
2097
2098func (config SetChatTitleConfig) params() (Params, error) {
2099	params := make(Params)
2100
2101	params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
2102	params["title"] = config.Title
2103
2104	return params, nil
2105}
2106
2107// SetChatDescriptionConfig allows you to set the description of a supergroup or channel.
2108type SetChatDescriptionConfig struct {
2109	ChatID          int64
2110	ChannelUsername string
2111
2112	Description string
2113}
2114
2115func (config SetChatDescriptionConfig) method() string {
2116	return "setChatDescription"
2117}
2118
2119func (config SetChatDescriptionConfig) params() (Params, error) {
2120	params := make(Params)
2121
2122	params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
2123	params["description"] = config.Description
2124
2125	return params, nil
2126}
2127
2128// GetStickerSetConfig allows you to get the stickers in a set.
2129type GetStickerSetConfig struct {
2130	Name string
2131}
2132
2133func (config GetStickerSetConfig) method() string {
2134	return "getStickerSet"
2135}
2136
2137func (config GetStickerSetConfig) params() (Params, error) {
2138	params := make(Params)
2139
2140	params["name"] = config.Name
2141
2142	return params, nil
2143}
2144
2145// GetCustomEmojiStickersConfig get information about
2146// custom emoji stickers by their identifiers.
2147type GetCustomEmojiStickersConfig struct {
2148	CustomEmojiIDs []string
2149}
2150
2151func (config GetCustomEmojiStickersConfig) params() (Params, error) {
2152	params := make(Params)
2153
2154	params.AddInterface("custom_emoji_ids", config.CustomEmojiIDs)
2155
2156	return params, nil
2157}
2158
2159func (config GetCustomEmojiStickersConfig) method() string {
2160	return "getCustomEmojiStickers"
2161}
2162
2163// UploadStickerConfig allows you to upload a sticker for use in a set later.
2164type UploadStickerConfig struct {
2165	UserID        int64
2166	Sticker       RequestFile
2167	StickerFormat string
2168}
2169
2170func (config UploadStickerConfig) method() string {
2171	return "uploadStickerFile"
2172}
2173
2174func (config UploadStickerConfig) params() (Params, error) {
2175	params := make(Params)
2176
2177	params.AddNonZero64("user_id", config.UserID)
2178	params["sticker_format"] = config.StickerFormat
2179
2180	return params, nil
2181}
2182
2183func (config UploadStickerConfig) files() []RequestFile {
2184	return []RequestFile{config.Sticker}
2185}
2186
2187// NewStickerSetConfig allows creating a new sticker set.
2188type NewStickerSetConfig struct {
2189	UserID          int64
2190	Name            string
2191	Title           string
2192	Stickers        []InputSticker
2193	StickerFormat   string
2194	StickerType     string
2195	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
2196}
2197
2198func (config NewStickerSetConfig) method() string {
2199	return "createNewStickerSet"
2200}
2201
2202func (config NewStickerSetConfig) params() (Params, error) {
2203	params := make(Params)
2204
2205	params.AddNonZero64("user_id", config.UserID)
2206	params["name"] = config.Name
2207	params["title"] = config.Title
2208	params["sticker_format"] = config.StickerFormat
2209
2210	params.AddBool("needs_repainting", config.NeedsRepainting)
2211	params.AddNonEmpty("sticker_type", string(config.StickerType))
2212	err := params.AddInterface("stickers", config.Stickers)
2213
2214	return params, err
2215}
2216
2217func (config NewStickerSetConfig) files() []RequestFile {
2218	requestFiles := []RequestFile{}
2219	for _, v := range config.Stickers {
2220		requestFiles = append(requestFiles, v.Sticker)
2221	}
2222	return requestFiles
2223}
2224
2225// AddStickerConfig allows you to add a sticker to a set.
2226type AddStickerConfig struct {
2227	UserID  int64
2228	Name    string
2229	Sticker InputSticker
2230}
2231
2232func (config AddStickerConfig) method() string {
2233	return "addStickerToSet"
2234}
2235
2236func (config AddStickerConfig) params() (Params, error) {
2237	params := make(Params)
2238
2239	params.AddNonZero64("user_id", config.UserID)
2240	params["name"] = config.Name
2241	err := params.AddInterface("sticker", config.Sticker)
2242	return params, err
2243}
2244
2245func (config AddStickerConfig) files() []RequestFile {
2246	return []RequestFile{config.Sticker.Sticker}
2247}
2248
2249// SetStickerPositionConfig allows you to change the position of a sticker in a set.
2250type SetStickerPositionConfig struct {
2251	Sticker  string
2252	Position int
2253}
2254
2255func (config SetStickerPositionConfig) method() string {
2256	return "setStickerPositionInSet"
2257}
2258
2259func (config SetStickerPositionConfig) params() (Params, error) {
2260	params := make(Params)
2261
2262	params["sticker"] = config.Sticker
2263	params.AddNonZero("position", config.Position)
2264
2265	return params, nil
2266}
2267
2268// SetCustomEmojiStickerSetThumbnalConfig allows you to set the thumbnail of a custom emoji sticker set
2269type SetCustomEmojiStickerSetThumbnalConfig struct {
2270	Name          string
2271	CustomEmojiID string
2272}
2273
2274func (config SetCustomEmojiStickerSetThumbnalConfig) method() string {
2275	return "setCustomEmojiStickerSetThumbnail"
2276}
2277
2278func (config SetCustomEmojiStickerSetThumbnalConfig) params() (Params, error) {
2279	params := make(Params)
2280
2281	params["name"] = config.Name
2282	params.AddNonEmpty("position", config.CustomEmojiID)
2283
2284	return params, nil
2285}
2286
2287// SetStickerSetTitle allows you to set the title of a created sticker set
2288type SetStickerSetTitleConfig struct {
2289	Name  string
2290	Title string
2291}
2292
2293func (config SetStickerSetTitleConfig) method() string {
2294	return "setStickerSetTitle"
2295}
2296
2297func (config SetStickerSetTitleConfig) params() (Params, error) {
2298	params := make(Params)
2299
2300	params["name"] = config.Name
2301	params["title"] = config.Title
2302
2303	return params, nil
2304}
2305
2306// DeleteStickerSetConfig allows you to delete a sticker set that was created by the bot.
2307type DeleteStickerSetConfig struct {
2308	Name string
2309}
2310
2311func (config DeleteStickerSetConfig) method() string {
2312	return "deleteStickerSet"
2313}
2314
2315func (config DeleteStickerSetConfig) params() (Params, error) {
2316	params := make(Params)
2317
2318	params["name"] = config.Name
2319
2320	return params, nil
2321}
2322
2323// DeleteStickerConfig allows you to delete a sticker from a set.
2324type DeleteStickerConfig struct {
2325	Sticker string
2326}
2327
2328func (config DeleteStickerConfig) method() string {
2329	return "deleteStickerFromSet"
2330}
2331
2332func (config DeleteStickerConfig) params() (Params, error) {
2333	params := make(Params)
2334
2335	params["sticker"] = config.Sticker
2336
2337	return params, nil
2338}
2339
2340// 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
2341type SetStickerEmojiListConfig struct {
2342	Sticker   string
2343	EmojiList []string
2344}
2345
2346func (config SetStickerEmojiListConfig) method() string {
2347	return "setStickerEmojiList"
2348}
2349
2350func (config SetStickerEmojiListConfig) params() (Params, error) {
2351	params := make(Params)
2352
2353	params["sticker"] = config.Sticker
2354	err := params.AddInterface("emoji_list", config.EmojiList)
2355
2356	return params, err
2357}
2358
2359// 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.
2360type SetStickerKeywordsConfig struct {
2361	Sticker  string
2362	Keywords []string
2363}
2364
2365func (config SetStickerKeywordsConfig) method() string {
2366	return "setStickerKeywords"
2367}
2368
2369func (config SetStickerKeywordsConfig) params() (Params, error) {
2370	params := make(Params)
2371
2372	params["sticker"] = config.Sticker
2373	err := params.AddInterface("keywords", config.Keywords)
2374
2375	return params, err
2376}
2377
2378// 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
2379type SetStickerMaskPositionConfig struct {
2380	Sticker      string
2381	MaskPosition *MaskPosition
2382}
2383
2384func (config SetStickerMaskPositionConfig) method() string {
2385	return "setStickerMaskPosition"
2386}
2387
2388func (config SetStickerMaskPositionConfig) params() (Params, error) {
2389	params := make(Params)
2390
2391	params["sticker"] = config.Sticker
2392	err := params.AddInterface("keywords", config.MaskPosition)
2393
2394	return params, err
2395}
2396
2397// SetStickerSetThumbConfig allows you to set the thumbnail for a sticker set.
2398type SetStickerSetThumbConfig struct {
2399	Name   string
2400	UserID int64
2401	Thumb  RequestFileData
2402}
2403
2404func (config SetStickerSetThumbConfig) method() string {
2405	return "setStickerSetThumbnail"
2406}
2407
2408func (config SetStickerSetThumbConfig) params() (Params, error) {
2409	params := make(Params)
2410
2411	params["name"] = config.Name
2412	params.AddNonZero64("user_id", config.UserID)
2413
2414	return params, nil
2415}
2416
2417func (config SetStickerSetThumbConfig) files() []RequestFile {
2418	return []RequestFile{{
2419		Name: "thumbnail",
2420		Data: config.Thumb,
2421	}}
2422}
2423
2424// SetChatStickerSetConfig allows you to set the sticker set for a supergroup.
2425type SetChatStickerSetConfig struct {
2426	ChatID             int64
2427	SuperGroupUsername string
2428
2429	StickerSetName string
2430}
2431
2432func (config SetChatStickerSetConfig) method() string {
2433	return "setChatStickerSet"
2434}
2435
2436func (config SetChatStickerSetConfig) params() (Params, error) {
2437	params := make(Params)
2438
2439	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
2440	params["sticker_set_name"] = config.StickerSetName
2441
2442	return params, nil
2443}
2444
2445// DeleteChatStickerSetConfig allows you to remove a supergroup's sticker set.
2446type DeleteChatStickerSetConfig struct {
2447	ChatID             int64
2448	SuperGroupUsername string
2449}
2450
2451func (config DeleteChatStickerSetConfig) method() string {
2452	return "deleteChatStickerSet"
2453}
2454
2455func (config DeleteChatStickerSetConfig) params() (Params, error) {
2456	params := make(Params)
2457
2458	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
2459
2460	return params, nil
2461}
2462
2463// GetForumTopicIconStickersConfig allows you to get custom emoji stickers,
2464// which can be used as a forum topic icon by any user.
2465type GetForumTopicIconStickersConfig struct{}
2466
2467func (config GetForumTopicIconStickersConfig) method() string {
2468	return "getForumTopicIconStickers"
2469}
2470
2471func (config GetForumTopicIconStickersConfig) params() (Params, error) {
2472	return nil, nil
2473}
2474
2475// BaseForum is a base type for all forum config types.
2476type BaseForum struct {
2477	ChatID             int64
2478	SuperGroupUsername string
2479}
2480
2481func (config BaseForum) params() (Params, error) {
2482	params := make(Params)
2483
2484	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
2485
2486	return params, nil
2487}
2488
2489// CreateForumTopicConfig allows you to create a topic
2490// in a forum supergroup chat.
2491type CreateForumTopicConfig struct {
2492	BaseForum
2493	Name              string
2494	IconColor         int
2495	IconCustomEmojiID string
2496}
2497
2498func (config CreateForumTopicConfig) method() string {
2499	return "createForumTopic"
2500}
2501
2502func (config CreateForumTopicConfig) params() (Params, error) {
2503	params := make(Params)
2504
2505	params.AddNonEmpty("name", config.Name)
2506	params.AddNonZero("icon_color", config.IconColor)
2507	params.AddNonEmpty("icon_custom_emoji_id", config.IconCustomEmojiID)
2508
2509	p1, _ := config.BaseForum.params()
2510	params.Merge(p1)
2511
2512	return params, nil
2513}
2514
2515// EditForumTopicConfig allows you to edit
2516// name and icon of a topic in a forum supergroup chat.
2517type EditForumTopicConfig struct {
2518	BaseForum
2519	MessageThreadID   int
2520	Name              string
2521	IconCustomEmojiID string
2522}
2523
2524func (config EditForumTopicConfig) method() string {
2525	return "editForumTopic"
2526}
2527
2528func (config EditForumTopicConfig) params() (Params, error) {
2529	params := make(Params)
2530
2531	params.AddNonZero("message_thread_id", config.MessageThreadID)
2532	params.AddNonEmpty("name", config.Name)
2533	params.AddNonEmpty("icon_custom_emoji_id", config.IconCustomEmojiID)
2534
2535	p1, _ := config.BaseForum.params()
2536	params.Merge(p1)
2537
2538	return params, nil
2539}
2540
2541// CloseForumTopicConfig allows you to close
2542// an open topic in a forum supergroup chat.
2543type CloseForumTopicConfig struct {
2544	BaseForum
2545	MessageThreadID int
2546}
2547
2548func (config CloseForumTopicConfig) method() string {
2549	return "closeForumTopic"
2550}
2551
2552func (config CloseForumTopicConfig) params() (Params, error) {
2553	params := make(Params)
2554
2555	params.AddNonZero("message_thread_id", config.MessageThreadID)
2556
2557	p1, _ := config.BaseForum.params()
2558	params.Merge(p1)
2559
2560	return params, nil
2561}
2562
2563// ReopenForumTopicConfig allows you to reopen
2564// an closed topic in a forum supergroup chat.
2565type ReopenForumTopicConfig struct {
2566	BaseForum
2567	MessageThreadID int
2568}
2569
2570func (config ReopenForumTopicConfig) method() string {
2571	return "reopenForumTopic"
2572}
2573
2574func (config ReopenForumTopicConfig) params() (Params, error) {
2575	params := make(Params)
2576
2577	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
2578	params.AddNonZero("message_thread_id", config.MessageThreadID)
2579
2580	p1, _ := config.BaseForum.params()
2581	params.Merge(p1)
2582
2583	return params, nil
2584}
2585
2586// DeleteForumTopicConfig allows you to delete a forum topic
2587// along with all its messages in a forum supergroup chat.
2588type DeleteForumTopicConfig struct {
2589	BaseForum
2590	MessageThreadID int
2591}
2592
2593func (config DeleteForumTopicConfig) method() string {
2594	return "deleteForumTopic"
2595}
2596
2597func (config DeleteForumTopicConfig) params() (Params, error) {
2598	params := make(Params)
2599
2600	params.AddNonZero("message_thread_id", config.MessageThreadID)
2601
2602	p1, _ := config.BaseForum.params()
2603	params.Merge(p1)
2604
2605	return params, nil
2606}
2607
2608// UnpinAllForumTopicMessagesConfig allows you to clear the list
2609// of pinned messages in a forum topic.
2610type UnpinAllForumTopicMessagesConfig struct {
2611	BaseForum
2612	MessageThreadID int
2613}
2614
2615func (config UnpinAllForumTopicMessagesConfig) method() string {
2616	return "unpinAllForumTopicMessages"
2617}
2618
2619func (config UnpinAllForumTopicMessagesConfig) params() (Params, error) {
2620	params := make(Params)
2621
2622	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
2623	params.AddNonZero("message_thread_id", config.MessageThreadID)
2624
2625	p1, _ := config.BaseForum.params()
2626	params.Merge(p1)
2627
2628	return params, nil
2629}
2630
2631// UnpinAllForumTopicMessagesConfig allows you to edit the name of
2632// the 'General' topic in a forum supergroup chat.
2633// The bot must be an administrator in the chat for this to work
2634// and must have can_manage_topics administrator rights. Returns True on success.
2635type EditGeneralForumTopicConfig struct {
2636	BaseForum
2637	Name string
2638}
2639
2640func (config EditGeneralForumTopicConfig) method() string {
2641	return "editGeneralForumTopic"
2642}
2643
2644func (config EditGeneralForumTopicConfig) params() (Params, error) {
2645	params := make(Params)
2646
2647	params.AddNonEmpty("name", config.Name)
2648
2649	p1, _ := config.BaseForum.params()
2650	params.Merge(p1)
2651
2652	return params, nil
2653}
2654
2655// CloseGeneralForumTopicConfig allows you to to close an open 'General' topic
2656// in a forum supergroup chat. The bot must be an administrator in the chat
2657// for this to work and must have the can_manage_topics administrator rights.
2658// Returns True on success.
2659type CloseGeneralForumTopicConfig struct{ BaseForum }
2660
2661func (config CloseGeneralForumTopicConfig) method() string {
2662	return "closeGeneralForumTopic"
2663}
2664
2665// CloseGeneralForumTopicConfig allows you to reopen a closed 'General' topic
2666// in a forum supergroup chat. The bot must be an administrator in the chat
2667// for this to work and must have the can_manage_topics administrator rights.
2668// The topic will be automatically unhidden if it was hidden.
2669// Returns True on success.
2670type ReopenGeneralForumTopicConfig struct{ BaseForum }
2671
2672func (config ReopenGeneralForumTopicConfig) method() string {
2673	return "reopenGeneralForumTopic"
2674}
2675
2676// HideGeneralForumTopicConfig allows you to hide the 'General' topic
2677// in a forum supergroup chat. The bot must be an administrator in the chat
2678// for this to work and must have the can_manage_topics administrator rights.
2679// The topic will be automatically closed if it was open.
2680// Returns True on success.
2681type HideGeneralForumTopicConfig struct{ BaseForum }
2682
2683func (config HideGeneralForumTopicConfig) method() string {
2684	return "hideGeneralForumTopic"
2685}
2686
2687// UnhideGeneralForumTopicConfig allows you to unhide the 'General' topic
2688// in a forum supergroup chat. The bot must be an administrator in the chat
2689// for this to work and must have the can_manage_topics administrator rights.
2690// Returns True on success.
2691type UnhideGeneralForumTopicConfig struct{ BaseForum }
2692
2693func (config UnhideGeneralForumTopicConfig) method() string {
2694	return "unhideGeneralForumTopic"
2695}
2696
2697// MediaGroupConfig allows you to send a group of media.
2698//
2699// Media consist of InputMedia items (InputMediaPhoto, InputMediaVideo).
2700type MediaGroupConfig struct {
2701	BaseChat
2702	Media []interface{}
2703}
2704
2705func (config MediaGroupConfig) method() string {
2706	return "sendMediaGroup"
2707}
2708
2709func (config MediaGroupConfig) params() (Params, error) {
2710	params, err := config.BaseChat.params()
2711	if err != nil {
2712		return nil, err
2713	}
2714
2715	params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
2716	params.AddBool("disable_notification", config.DisableNotification)
2717	params.AddNonZero("reply_to_message_id", config.ReplyToMessageID)
2718
2719	err = params.AddInterface("media", prepareInputMediaForParams(config.Media))
2720
2721	return params, err
2722}
2723
2724func (config MediaGroupConfig) files() []RequestFile {
2725	return prepareInputMediaForFiles(config.Media)
2726}
2727
2728// DiceConfig contains information about a sendDice request.
2729type DiceConfig struct {
2730	BaseChat
2731	// Emoji on which the dice throw animation is based.
2732	// Currently, must be one of 🎲, 🎯, 🏀, ⚽, 🎳, or 🎰.
2733	// Dice can have values 1-6 for 🎲, 🎯, and 🎳, values 1-5 for 🏀 and ⚽,
2734	// and values 1-64 for 🎰.
2735	// Defaults to “🎲”
2736	Emoji string
2737}
2738
2739func (config DiceConfig) method() string {
2740	return "sendDice"
2741}
2742
2743func (config DiceConfig) params() (Params, error) {
2744	params, err := config.BaseChat.params()
2745	if err != nil {
2746		return params, err
2747	}
2748
2749	params.AddNonEmpty("emoji", config.Emoji)
2750
2751	return params, err
2752}
2753
2754// GetMyCommandsConfig gets a list of the currently registered commands.
2755type GetMyCommandsConfig struct {
2756	Scope        *BotCommandScope
2757	LanguageCode string
2758}
2759
2760func (config GetMyCommandsConfig) method() string {
2761	return "getMyCommands"
2762}
2763
2764func (config GetMyCommandsConfig) params() (Params, error) {
2765	params := make(Params)
2766
2767	err := params.AddInterface("scope", config.Scope)
2768	params.AddNonEmpty("language_code", config.LanguageCode)
2769
2770	return params, err
2771}
2772
2773// SetMyCommandsConfig sets a list of commands the bot understands.
2774type SetMyCommandsConfig struct {
2775	Commands     []BotCommand
2776	Scope        *BotCommandScope
2777	LanguageCode string
2778}
2779
2780func (config SetMyCommandsConfig) method() string {
2781	return "setMyCommands"
2782}
2783
2784func (config SetMyCommandsConfig) params() (Params, error) {
2785	params := make(Params)
2786
2787	if err := params.AddInterface("commands", config.Commands); err != nil {
2788		return params, err
2789	}
2790	err := params.AddInterface("scope", config.Scope)
2791	params.AddNonEmpty("language_code", config.LanguageCode)
2792
2793	return params, err
2794}
2795
2796type DeleteMyCommandsConfig struct {
2797	Scope        *BotCommandScope
2798	LanguageCode string
2799}
2800
2801func (config DeleteMyCommandsConfig) method() string {
2802	return "deleteMyCommands"
2803}
2804
2805func (config DeleteMyCommandsConfig) params() (Params, error) {
2806	params := make(Params)
2807
2808	err := params.AddInterface("scope", config.Scope)
2809	params.AddNonEmpty("language_code", config.LanguageCode)
2810
2811	return params, err
2812}
2813
2814// SetMyNameConfig change the bot's name
2815type SetMyNameConfig struct {
2816	Name         string
2817	LanguageCode string
2818}
2819
2820func (config SetMyNameConfig) method() string {
2821	return "setMyName"
2822}
2823
2824func (config SetMyNameConfig) params() (Params, error) {
2825	params := make(Params)
2826
2827	params.AddNonEmpty("name", config.Name)
2828	params.AddNonEmpty("language_code", config.LanguageCode)
2829
2830	return params, nil
2831}
2832
2833type GetMyNameConfig struct {
2834	LanguageCode string
2835}
2836
2837func (config GetMyNameConfig) method() string {
2838	return "getMyName"
2839}
2840
2841func (config GetMyNameConfig) params() (Params, error) {
2842	params := make(Params)
2843
2844	params.AddNonEmpty("language_code", config.LanguageCode)
2845
2846	return params, nil
2847}
2848
2849// GetMyDescriptionConfig get the current bot description for the given user language
2850type GetMyDescriptionConfig struct {
2851	LanguageCode string
2852}
2853
2854func (config GetMyDescriptionConfig) method() string {
2855	return "getMyDescription"
2856}
2857
2858func (config GetMyDescriptionConfig) params() (Params, error) {
2859	params := make(Params)
2860
2861	params.AddNonEmpty("language_code", config.LanguageCode)
2862
2863	return params, nil
2864}
2865
2866// SetMyDescroptionConfig sets the bot's description, which is shown in the chat with the bot if the chat is empty
2867type SetMyDescriptionConfig struct {
2868	// Pass an empty string to remove the dedicated description for the given language.
2869	Description string
2870	//If empty, the description will be applied to all users for whose language there is no dedicated description.
2871	LanguageCode string
2872}
2873
2874func (config SetMyDescriptionConfig) method() string {
2875	return "setMyDescription"
2876}
2877
2878func (config SetMyDescriptionConfig) params() (Params, error) {
2879	params := make(Params)
2880
2881	params.AddNonEmpty("description", config.Description)
2882	params.AddNonEmpty("language_code", config.LanguageCode)
2883
2884	return params, nil
2885}
2886
2887// GetMyShortDescriptionConfig get the current bot short description for the given user language
2888type GetMyShortDescriptionConfig struct {
2889	LanguageCode string
2890}
2891
2892func (config GetMyShortDescriptionConfig) method() string {
2893	return "getMyShortDescription"
2894}
2895
2896func (config GetMyShortDescriptionConfig) params() (Params, error) {
2897	params := make(Params)
2898
2899	params.AddNonEmpty("language_code", config.LanguageCode)
2900
2901	return params, nil
2902}
2903
2904// 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.
2905type SetMyShortDescriptionConfig struct {
2906	// New short description for the bot; 0-120 characters.
2907	//
2908	//Pass an empty string to remove the dedicated short description for the given language.
2909	ShortDescription string
2910	//A two-letter ISO 639-1 language code.
2911	//
2912	//If empty, the short description will be applied to all users for whose language there is no dedicated short description.
2913	LanguageCode string
2914}
2915
2916func (config SetMyShortDescriptionConfig) method() string {
2917	return "setMyDescription"
2918}
2919
2920func (config SetMyShortDescriptionConfig) params() (Params, error) {
2921	params := make(Params)
2922
2923	params.AddNonEmpty("short_description", config.ShortDescription)
2924	params.AddNonEmpty("language_code", config.LanguageCode)
2925
2926	return params, nil
2927}
2928
2929// SetChatMenuButtonConfig changes the bot's menu button in a private chat,
2930// or the default menu button.
2931type SetChatMenuButtonConfig struct {
2932	ChatID          int64
2933	ChannelUsername string
2934
2935	MenuButton *MenuButton
2936}
2937
2938func (config SetChatMenuButtonConfig) method() string {
2939	return "setChatMenuButton"
2940}
2941
2942func (config SetChatMenuButtonConfig) params() (Params, error) {
2943	params := make(Params)
2944
2945	if err := params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername); err != nil {
2946		return params, err
2947	}
2948	err := params.AddInterface("menu_button", config.MenuButton)
2949
2950	return params, err
2951}
2952
2953type GetChatMenuButtonConfig struct {
2954	ChatID          int64
2955	ChannelUsername string
2956}
2957
2958func (config GetChatMenuButtonConfig) method() string {
2959	return "getChatMenuButton"
2960}
2961
2962func (config GetChatMenuButtonConfig) params() (Params, error) {
2963	params := make(Params)
2964
2965	err := params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
2966
2967	return params, err
2968}
2969
2970type SetMyDefaultAdministratorRightsConfig struct {
2971	Rights      ChatAdministratorRights
2972	ForChannels bool
2973}
2974
2975func (config SetMyDefaultAdministratorRightsConfig) method() string {
2976	return "setMyDefaultAdministratorRights"
2977}
2978
2979func (config SetMyDefaultAdministratorRightsConfig) params() (Params, error) {
2980	params := make(Params)
2981
2982	err := params.AddInterface("rights", config.Rights)
2983	params.AddBool("for_channels", config.ForChannels)
2984
2985	return params, err
2986}
2987
2988type GetMyDefaultAdministratorRightsConfig struct {
2989	ForChannels bool
2990}
2991
2992func (config GetMyDefaultAdministratorRightsConfig) method() string {
2993	return "getMyDefaultAdministratorRights"
2994}
2995
2996func (config GetMyDefaultAdministratorRightsConfig) params() (Params, error) {
2997	params := make(Params)
2998
2999	params.AddBool("for_channels", config.ForChannels)
3000
3001	return params, nil
3002}
3003
3004// prepareInputMediaParam evaluates a single InputMedia and determines if it
3005// needs to be modified for a successful upload. If it returns nil, then the
3006// value does not need to be included in the params. Otherwise, it will return
3007// the same type as was originally provided.
3008//
3009// The idx is used to calculate the file field name. If you only have a single
3010// file, 0 may be used. It is formatted into "attach://file-%d" for the primary
3011// media and "attach://file-%d-thumb" for thumbnails.
3012//
3013// It is expected to be used in conjunction with prepareInputMediaFile.
3014func prepareInputMediaParam(inputMedia interface{}, idx int) interface{} {
3015	switch m := inputMedia.(type) {
3016	case InputMediaPhoto:
3017		if m.Media.NeedsUpload() {
3018			m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
3019		}
3020
3021		return m
3022	case InputMediaVideo:
3023		if m.Media.NeedsUpload() {
3024			m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
3025		}
3026
3027		if m.Thumb != nil && m.Thumb.NeedsUpload() {
3028			m.Thumb = fileAttach(fmt.Sprintf("attach://file-%d-thumb", idx))
3029		}
3030
3031		return m
3032	case InputMediaAudio:
3033		if m.Media.NeedsUpload() {
3034			m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
3035		}
3036
3037		if m.Thumb != nil && m.Thumb.NeedsUpload() {
3038			m.Thumb = fileAttach(fmt.Sprintf("attach://file-%d-thumb", idx))
3039		}
3040
3041		return m
3042	case InputMediaDocument:
3043		if m.Media.NeedsUpload() {
3044			m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
3045		}
3046
3047		if m.Thumb != nil && m.Thumb.NeedsUpload() {
3048			m.Thumb = fileAttach(fmt.Sprintf("attach://file-%d-thumb", idx))
3049		}
3050
3051		return m
3052	}
3053
3054	return nil
3055}
3056
3057// prepareInputMediaFile generates an array of RequestFile to provide for
3058// Fileable's files method. It returns an array as a single InputMedia may have
3059// multiple files, for the primary media and a thumbnail.
3060//
3061// The idx parameter is used to generate file field names. It uses the names
3062// "file-%d" for the main file and "file-%d-thumb" for the thumbnail.
3063//
3064// It is expected to be used in conjunction with prepareInputMediaParam.
3065func prepareInputMediaFile(inputMedia interface{}, idx int) []RequestFile {
3066	files := []RequestFile{}
3067
3068	switch m := inputMedia.(type) {
3069	case InputMediaPhoto:
3070		if m.Media.NeedsUpload() {
3071			files = append(files, RequestFile{
3072				Name: fmt.Sprintf("file-%d", idx),
3073				Data: m.Media,
3074			})
3075		}
3076	case InputMediaVideo:
3077		if m.Media.NeedsUpload() {
3078			files = append(files, RequestFile{
3079				Name: fmt.Sprintf("file-%d", idx),
3080				Data: m.Media,
3081			})
3082		}
3083
3084		if m.Thumb != nil && m.Thumb.NeedsUpload() {
3085			files = append(files, RequestFile{
3086				Name: fmt.Sprintf("file-%d", idx),
3087				Data: m.Thumb,
3088			})
3089		}
3090	case InputMediaDocument:
3091		if m.Media.NeedsUpload() {
3092			files = append(files, RequestFile{
3093				Name: fmt.Sprintf("file-%d", idx),
3094				Data: m.Media,
3095			})
3096		}
3097
3098		if m.Thumb != nil && m.Thumb.NeedsUpload() {
3099			files = append(files, RequestFile{
3100				Name: fmt.Sprintf("file-%d", idx),
3101				Data: m.Thumb,
3102			})
3103		}
3104	case InputMediaAudio:
3105		if m.Media.NeedsUpload() {
3106			files = append(files, RequestFile{
3107				Name: fmt.Sprintf("file-%d", idx),
3108				Data: m.Media,
3109			})
3110		}
3111
3112		if m.Thumb != nil && m.Thumb.NeedsUpload() {
3113			files = append(files, RequestFile{
3114				Name: fmt.Sprintf("file-%d", idx),
3115				Data: m.Thumb,
3116			})
3117		}
3118	}
3119
3120	return files
3121}
3122
3123// prepareInputMediaForParams calls prepareInputMediaParam for each item
3124// provided and returns a new array with the correct params for a request.
3125//
3126// It is expected that files will get data from the associated function,
3127// prepareInputMediaForFiles.
3128func prepareInputMediaForParams(inputMedia []interface{}) []interface{} {
3129	newMedia := make([]interface{}, len(inputMedia))
3130	copy(newMedia, inputMedia)
3131
3132	for idx, media := range inputMedia {
3133		if param := prepareInputMediaParam(media, idx); param != nil {
3134			newMedia[idx] = param
3135		}
3136	}
3137
3138	return newMedia
3139}
3140
3141// prepareInputMediaForFiles calls prepareInputMediaFile for each item
3142// provided and returns a new array with the correct files for a request.
3143//
3144// It is expected that params will get data from the associated function,
3145// prepareInputMediaForParams.
3146func prepareInputMediaForFiles(inputMedia []interface{}) []RequestFile {
3147	files := []RequestFile{}
3148
3149	for idx, media := range inputMedia {
3150		if file := prepareInputMediaFile(media, idx); file != nil {
3151			files = append(files, file...)
3152		}
3153	}
3154
3155	return files
3156}