all repos — telegram-bot-api @ 17d3e395d52d40e76b22f043424937a4e8d2f58c

Golang bindings for the Telegram Bot API

configs.go (view raw)

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