all repos — telegram-bot-api @ 16635e50ea30023ca1223b6320bafa885fa849d5

Golang bindings for the Telegram Bot API

configs.go (view raw)

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