all repos — telegram-bot-api @ bb07769ea9a507112da471c1df8f0d28eacaef31

Golang bindings for the Telegram Bot API

configs.go (view raw)

   1package tgbotapi
   2
   3import (
   4	"encoding/json"
   5	"io"
   6	"net/url"
   7	"strconv"
   8)
   9
  10// Telegram constants
  11const (
  12	// APIEndpoint is the endpoint for all API methods,
  13	// with formatting for Sprintf.
  14	APIEndpoint = "https://api.telegram.org/bot%s/%s"
  15	// FileEndpoint is the endpoint for downloading a file from Telegram.
  16	FileEndpoint = "https://api.telegram.org/file/bot%s/%s"
  17)
  18
  19// Constant values for ChatActions
  20const (
  21	ChatTyping         = "typing"
  22	ChatUploadPhoto    = "upload_photo"
  23	ChatRecordVideo    = "record_video"
  24	ChatUploadVideo    = "upload_video"
  25	ChatRecordAudio    = "record_audio"
  26	ChatUploadAudio    = "upload_audio"
  27	ChatUploadDocument = "upload_document"
  28	ChatFindLocation   = "find_location"
  29)
  30
  31// API errors
  32const (
  33	// ErrAPIForbidden happens when a token is bad
  34	ErrAPIForbidden = "forbidden"
  35)
  36
  37// Constant values for ParseMode in MessageConfig
  38const (
  39	ModeMarkdown = "Markdown"
  40	ModeHTML     = "HTML"
  41)
  42
  43// Library errors
  44const (
  45	// ErrBadFileType happens when you pass an unknown type
  46	ErrBadFileType = "bad file type"
  47	ErrBadURL      = "bad or empty url"
  48)
  49
  50// Chattable is any config type that can be sent.
  51type Chattable interface {
  52	values() (url.Values, error)
  53	method() string
  54}
  55
  56// Fileable is any config type that can be sent that includes a file.
  57type Fileable interface {
  58	Chattable
  59	params() (map[string]string, error)
  60	name() string
  61	getFile() interface{}
  62	useExistingFile() bool
  63}
  64
  65// BaseChat is base type for all chat config types.
  66type BaseChat struct {
  67	ChatID              int64 // required
  68	ChannelUsername     string
  69	ReplyToMessageID    int
  70	ReplyMarkup         interface{}
  71	DisableNotification bool
  72}
  73
  74// values returns url.Values representation of BaseChat
  75func (chat *BaseChat) values() (url.Values, error) {
  76	v := url.Values{}
  77	if chat.ChannelUsername != "" {
  78		v.Add("chat_id", chat.ChannelUsername)
  79	} else {
  80		v.Add("chat_id", strconv.FormatInt(chat.ChatID, 10))
  81	}
  82
  83	if chat.ReplyToMessageID != 0 {
  84		v.Add("reply_to_message_id", strconv.Itoa(chat.ReplyToMessageID))
  85	}
  86
  87	if chat.ReplyMarkup != nil {
  88		data, err := json.Marshal(chat.ReplyMarkup)
  89		if err != nil {
  90			return v, err
  91		}
  92
  93		v.Add("reply_markup", string(data))
  94	}
  95
  96	v.Add("disable_notification", strconv.FormatBool(chat.DisableNotification))
  97
  98	return v, nil
  99}
 100
 101// BaseFile is a base type for all file config types.
 102type BaseFile struct {
 103	BaseChat
 104	File        interface{}
 105	FileID      string
 106	UseExisting bool
 107	MimeType    string
 108	FileSize    int
 109}
 110
 111// params returns a map[string]string representation of BaseFile.
 112func (file BaseFile) params() (map[string]string, error) {
 113	params := make(map[string]string)
 114
 115	if file.ChannelUsername != "" {
 116		params["chat_id"] = file.ChannelUsername
 117	} else {
 118		params["chat_id"] = strconv.FormatInt(file.ChatID, 10)
 119	}
 120
 121	if file.ReplyToMessageID != 0 {
 122		params["reply_to_message_id"] = strconv.Itoa(file.ReplyToMessageID)
 123	}
 124
 125	if file.ReplyMarkup != nil {
 126		data, err := json.Marshal(file.ReplyMarkup)
 127		if err != nil {
 128			return params, err
 129		}
 130
 131		params["reply_markup"] = string(data)
 132	}
 133
 134	if file.MimeType != "" {
 135		params["mime_type"] = file.MimeType
 136	}
 137
 138	if file.FileSize > 0 {
 139		params["file_size"] = strconv.Itoa(file.FileSize)
 140	}
 141
 142	params["disable_notification"] = strconv.FormatBool(file.DisableNotification)
 143
 144	return params, nil
 145}
 146
 147// getFile returns the file.
 148func (file BaseFile) getFile() interface{} {
 149	return file.File
 150}
 151
 152// useExistingFile returns if the BaseFile has already been uploaded.
 153func (file BaseFile) useExistingFile() bool {
 154	return file.UseExisting
 155}
 156
 157// BaseEdit is base type of all chat edits.
 158type BaseEdit struct {
 159	ChatID          int64
 160	ChannelUsername string
 161	MessageID       int
 162	InlineMessageID string
 163	ReplyMarkup     *InlineKeyboardMarkup
 164}
 165
 166func (edit BaseEdit) values() (url.Values, error) {
 167	v := url.Values{}
 168
 169	if edit.InlineMessageID == "" {
 170		if edit.ChannelUsername != "" {
 171			v.Add("chat_id", edit.ChannelUsername)
 172		} else {
 173			v.Add("chat_id", strconv.FormatInt(edit.ChatID, 10))
 174		}
 175		v.Add("message_id", strconv.Itoa(edit.MessageID))
 176	} else {
 177		v.Add("inline_message_id", edit.InlineMessageID)
 178	}
 179
 180	if edit.ReplyMarkup != nil {
 181		data, err := json.Marshal(edit.ReplyMarkup)
 182		if err != nil {
 183			return v, err
 184		}
 185		v.Add("reply_markup", string(data))
 186	}
 187
 188	return v, nil
 189}
 190
 191// MessageConfig contains information about a SendMessage request.
 192type MessageConfig struct {
 193	BaseChat
 194	Text                  string
 195	ParseMode             string
 196	DisableWebPagePreview bool
 197}
 198
 199// values returns a url.Values representation of MessageConfig.
 200func (config MessageConfig) values() (url.Values, error) {
 201	v, err := config.BaseChat.values()
 202	if err != nil {
 203		return v, err
 204	}
 205	v.Add("text", config.Text)
 206	v.Add("disable_web_page_preview", strconv.FormatBool(config.DisableWebPagePreview))
 207	if config.ParseMode != "" {
 208		v.Add("parse_mode", config.ParseMode)
 209	}
 210
 211	return v, nil
 212}
 213
 214// method returns Telegram API method name for sending Message.
 215func (config MessageConfig) method() string {
 216	return "sendMessage"
 217}
 218
 219// ForwardConfig contains information about a ForwardMessage request.
 220type ForwardConfig struct {
 221	BaseChat
 222	FromChatID          int64 // required
 223	FromChannelUsername string
 224	MessageID           int // required
 225}
 226
 227// values returns a url.Values representation of ForwardConfig.
 228func (config ForwardConfig) values() (url.Values, error) {
 229	v, err := config.BaseChat.values()
 230	if err != nil {
 231		return v, err
 232	}
 233	v.Add("from_chat_id", strconv.FormatInt(config.FromChatID, 10))
 234	v.Add("message_id", strconv.Itoa(config.MessageID))
 235	return v, nil
 236}
 237
 238// method returns Telegram API method name for sending Forward.
 239func (config ForwardConfig) method() string {
 240	return "forwardMessage"
 241}
 242
 243// PhotoConfig contains information about a SendPhoto request.
 244type PhotoConfig struct {
 245	BaseFile
 246	Caption string
 247}
 248
 249// Params returns a map[string]string representation of PhotoConfig.
 250func (config PhotoConfig) params() (map[string]string, error) {
 251	params, _ := config.BaseFile.params()
 252
 253	if config.Caption != "" {
 254		params["caption"] = config.Caption
 255	}
 256
 257	return params, nil
 258}
 259
 260// Values returns a url.Values representation of PhotoConfig.
 261func (config PhotoConfig) values() (url.Values, error) {
 262	v, err := config.BaseChat.values()
 263	if err != nil {
 264		return v, err
 265	}
 266
 267	v.Add(config.name(), config.FileID)
 268	if config.Caption != "" {
 269		v.Add("caption", config.Caption)
 270	}
 271	return v, nil
 272}
 273
 274// name returns the field name for the Photo.
 275func (config PhotoConfig) name() string {
 276	return "photo"
 277}
 278
 279// method returns Telegram API method name for sending Photo.
 280func (config PhotoConfig) method() string {
 281	return "sendPhoto"
 282}
 283
 284// AudioConfig contains information about a SendAudio request.
 285type AudioConfig struct {
 286	BaseFile
 287	Caption   string
 288	Duration  int
 289	Performer string
 290	Title     string
 291}
 292
 293// values returns a url.Values representation of AudioConfig.
 294func (config AudioConfig) values() (url.Values, error) {
 295	v, err := config.BaseChat.values()
 296	if err != nil {
 297		return v, err
 298	}
 299
 300	v.Add(config.name(), config.FileID)
 301	if config.Duration != 0 {
 302		v.Add("duration", strconv.Itoa(config.Duration))
 303	}
 304
 305	if config.Performer != "" {
 306		v.Add("performer", config.Performer)
 307	}
 308	if config.Title != "" {
 309		v.Add("title", config.Title)
 310	}
 311	if config.Caption != "" {
 312		v.Add("caption", config.Caption)
 313	}
 314
 315	return v, nil
 316}
 317
 318// params returns a map[string]string representation of AudioConfig.
 319func (config AudioConfig) params() (map[string]string, error) {
 320	params, _ := config.BaseFile.params()
 321
 322	if config.Duration != 0 {
 323		params["duration"] = strconv.Itoa(config.Duration)
 324	}
 325
 326	if config.Performer != "" {
 327		params["performer"] = config.Performer
 328	}
 329	if config.Title != "" {
 330		params["title"] = config.Title
 331	}
 332	if config.Caption != "" {
 333		params["caption"] = config.Caption
 334	}
 335
 336	return params, nil
 337}
 338
 339// name returns the field name for the Audio.
 340func (config AudioConfig) name() string {
 341	return "audio"
 342}
 343
 344// method returns Telegram API method name for sending Audio.
 345func (config AudioConfig) method() string {
 346	return "sendAudio"
 347}
 348
 349// DocumentConfig contains information about a SendDocument request.
 350type DocumentConfig struct {
 351	BaseFile
 352	Caption string
 353}
 354
 355// values returns a url.Values representation of DocumentConfig.
 356func (config DocumentConfig) values() (url.Values, error) {
 357	v, err := config.BaseChat.values()
 358	if err != nil {
 359		return v, err
 360	}
 361
 362	v.Add(config.name(), config.FileID)
 363	if config.Caption != "" {
 364		v.Add("caption", config.Caption)
 365	}
 366
 367	return v, nil
 368}
 369
 370// params returns a map[string]string representation of DocumentConfig.
 371func (config DocumentConfig) params() (map[string]string, error) {
 372	params, _ := config.BaseFile.params()
 373
 374	if config.Caption != "" {
 375		params["caption"] = config.Caption
 376	}
 377
 378	return params, nil
 379}
 380
 381// name returns the field name for the Document.
 382func (config DocumentConfig) name() string {
 383	return "document"
 384}
 385
 386// method returns Telegram API method name for sending Document.
 387func (config DocumentConfig) method() string {
 388	return "sendDocument"
 389}
 390
 391// StickerConfig contains information about a SendSticker request.
 392type StickerConfig struct {
 393	BaseFile
 394}
 395
 396// values returns a url.Values representation of StickerConfig.
 397func (config StickerConfig) values() (url.Values, error) {
 398	v, err := config.BaseChat.values()
 399	if err != nil {
 400		return v, err
 401	}
 402
 403	v.Add(config.name(), config.FileID)
 404
 405	return v, nil
 406}
 407
 408// params returns a map[string]string representation of StickerConfig.
 409func (config StickerConfig) params() (map[string]string, error) {
 410	params, _ := config.BaseFile.params()
 411
 412	return params, nil
 413}
 414
 415// name returns the field name for the Sticker.
 416func (config StickerConfig) name() string {
 417	return "sticker"
 418}
 419
 420// method returns Telegram API method name for sending Sticker.
 421func (config StickerConfig) method() string {
 422	return "sendSticker"
 423}
 424
 425// VideoConfig contains information about a SendVideo request.
 426type VideoConfig struct {
 427	BaseFile
 428	Duration int
 429	Caption  string
 430}
 431
 432// values returns a url.Values representation of VideoConfig.
 433func (config VideoConfig) values() (url.Values, error) {
 434	v, err := config.BaseChat.values()
 435	if err != nil {
 436		return v, err
 437	}
 438
 439	v.Add(config.name(), config.FileID)
 440	if config.Duration != 0 {
 441		v.Add("duration", strconv.Itoa(config.Duration))
 442	}
 443	if config.Caption != "" {
 444		v.Add("caption", config.Caption)
 445	}
 446
 447	return v, nil
 448}
 449
 450// params returns a map[string]string representation of VideoConfig.
 451func (config VideoConfig) params() (map[string]string, error) {
 452	params, _ := config.BaseFile.params()
 453
 454	if config.Caption != "" {
 455		params["caption"] = config.Caption
 456	}
 457
 458	return params, nil
 459}
 460
 461// name returns the field name for the Video.
 462func (config VideoConfig) name() string {
 463	return "video"
 464}
 465
 466// method returns Telegram API method name for sending Video.
 467func (config VideoConfig) method() string {
 468	return "sendVideo"
 469}
 470
 471// VideoNoteConfig contains information about a SendVideoNote request.
 472type VideoNoteConfig struct {
 473	BaseFile
 474	Duration int
 475	Length   int
 476}
 477
 478// values returns a url.Values representation of VideoNoteConfig.
 479func (config VideoNoteConfig) values() (url.Values, error) {
 480	v, err := config.BaseChat.values()
 481	if err != nil {
 482		return v, err
 483	}
 484
 485	v.Add(config.name(), config.FileID)
 486	if config.Duration != 0 {
 487		v.Add("duration", strconv.Itoa(config.Duration))
 488	}
 489
 490	// Telegram API seems to have a bug, if no length is provided or it is 0, it will send an error response
 491	if config.Length != 0 {
 492		v.Add("length", strconv.Itoa(config.Length))
 493	}
 494
 495	return v, nil
 496}
 497
 498// params returns a map[string]string representation of VideoNoteConfig.
 499func (config VideoNoteConfig) params() (map[string]string, error) {
 500	params, _ := config.BaseFile.params()
 501
 502	if config.Length != 0 {
 503		params["length"] = strconv.Itoa(config.Length)
 504	}
 505	if config.Duration != 0 {
 506		params["duration"] = strconv.Itoa(config.Duration)
 507	}
 508
 509	return params, nil
 510}
 511
 512// name returns the field name for the VideoNote.
 513func (config VideoNoteConfig) name() string {
 514	return "video_note"
 515}
 516
 517// method returns Telegram API method name for sending VideoNote.
 518func (config VideoNoteConfig) method() string {
 519	return "sendVideoNote"
 520}
 521
 522// VoiceConfig contains information about a SendVoice request.
 523type VoiceConfig struct {
 524	BaseFile
 525	Caption  string
 526	Duration int
 527}
 528
 529// values returns a url.Values representation of VoiceConfig.
 530func (config VoiceConfig) values() (url.Values, error) {
 531	v, err := config.BaseChat.values()
 532	if err != nil {
 533		return v, err
 534	}
 535
 536	v.Add(config.name(), config.FileID)
 537	if config.Duration != 0 {
 538		v.Add("duration", strconv.Itoa(config.Duration))
 539	}
 540	if config.Caption != "" {
 541		v.Add("caption", config.Caption)
 542	}
 543
 544	return v, nil
 545}
 546
 547// params returns a map[string]string representation of VoiceConfig.
 548func (config VoiceConfig) params() (map[string]string, error) {
 549	params, _ := config.BaseFile.params()
 550
 551	if config.Duration != 0 {
 552		params["duration"] = strconv.Itoa(config.Duration)
 553	}
 554	if config.Caption != "" {
 555		params["caption"] = config.Caption
 556	}
 557
 558	return params, nil
 559}
 560
 561// name returns the field name for the Voice.
 562func (config VoiceConfig) name() string {
 563	return "voice"
 564}
 565
 566// method returns Telegram API method name for sending Voice.
 567func (config VoiceConfig) method() string {
 568	return "sendVoice"
 569}
 570
 571// LocationConfig contains information about a SendLocation request.
 572type LocationConfig struct {
 573	BaseChat
 574	Latitude   float64 // required
 575	Longitude  float64 // required
 576	LivePeriod int     // optional
 577}
 578
 579// values returns a url.Values representation of LocationConfig.
 580func (config LocationConfig) values() (url.Values, error) {
 581	v, err := config.BaseChat.values()
 582	if err != nil {
 583		return v, err
 584	}
 585
 586	v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
 587	v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
 588	if config.LivePeriod != 0 {
 589		v.Add("live_period", strconv.Itoa(config.LivePeriod))
 590	}
 591
 592	return v, nil
 593}
 594
 595// method returns Telegram API method name for sending Location.
 596func (config LocationConfig) method() string {
 597	return "sendLocation"
 598}
 599
 600// LocationConfig contains information about a SendLocation request.
 601type EditMessageLiveLocationConfig struct {
 602	BaseEdit
 603	Latitude  float64 // required
 604	Longitude float64 // required
 605}
 606
 607// values returns a url.Values representation of EditMessageLiveLocationConfig.
 608func (config EditMessageLiveLocationConfig) values() (url.Values, error) {
 609	v, err := config.BaseEdit.values()
 610	if err != nil {
 611		return v, err
 612	}
 613
 614	v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
 615	v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
 616
 617	return v, nil
 618}
 619
 620// method returns Telegram API method name for edit message Live Location.
 621func (config EditMessageLiveLocationConfig) method() string {
 622	return "editMessageLiveLocation"
 623}
 624
 625// LocationConfig contains information about a StopMessageLiveLocation request.
 626type StopMessageLiveLocationConfig struct {
 627	BaseEdit
 628}
 629
 630// values returns a url.Values representation of StopMessageLiveLocationConfig.
 631func (config StopMessageLiveLocationConfig) values() (url.Values, error) {
 632	v, err := config.BaseEdit.values()
 633	if err != nil {
 634		return v, err
 635	}
 636
 637	return v, nil
 638}
 639
 640// method returns Telegram API method name for stop message Live Location.
 641func (config StopMessageLiveLocationConfig) method() string {
 642	return "stopMessageLiveLocation"
 643}
 644
 645// VenueConfig contains information about a SendVenue request.
 646type VenueConfig struct {
 647	BaseChat
 648	Latitude     float64 // required
 649	Longitude    float64 // required
 650	Title        string  // required
 651	Address      string  // required
 652	FoursquareID string
 653}
 654
 655func (config VenueConfig) values() (url.Values, error) {
 656	v, err := config.BaseChat.values()
 657	if err != nil {
 658		return v, err
 659	}
 660
 661	v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
 662	v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
 663	v.Add("title", config.Title)
 664	v.Add("address", config.Address)
 665	if config.FoursquareID != "" {
 666		v.Add("foursquare_id", config.FoursquareID)
 667	}
 668
 669	return v, nil
 670}
 671
 672func (config VenueConfig) method() string {
 673	return "sendVenue"
 674}
 675
 676// ContactConfig allows you to send a contact.
 677type ContactConfig struct {
 678	BaseChat
 679	PhoneNumber string
 680	FirstName   string
 681	LastName    string
 682}
 683
 684func (config ContactConfig) values() (url.Values, error) {
 685	v, err := config.BaseChat.values()
 686	if err != nil {
 687		return v, err
 688	}
 689
 690	v.Add("phone_number", config.PhoneNumber)
 691	v.Add("first_name", config.FirstName)
 692	v.Add("last_name", config.LastName)
 693
 694	return v, nil
 695}
 696
 697func (config ContactConfig) method() string {
 698	return "sendContact"
 699}
 700
 701// GameConfig allows you to send a game.
 702type GameConfig struct {
 703	BaseChat
 704	GameShortName string
 705}
 706
 707func (config GameConfig) values() (url.Values, error) {
 708	v, err := config.BaseChat.values()
 709	if err != nil {
 710		return v, err
 711	}
 712
 713	v.Add("game_short_name", config.GameShortName)
 714
 715	return v, nil
 716}
 717
 718func (config GameConfig) method() string {
 719	return "sendGame"
 720}
 721
 722// SetGameScoreConfig allows you to update the game score in a chat.
 723type SetGameScoreConfig struct {
 724	UserID             int
 725	Score              int
 726	Force              bool
 727	DisableEditMessage bool
 728	ChatID             int
 729	ChannelUsername    string
 730	MessageID          int
 731	InlineMessageID    string
 732}
 733
 734func (config SetGameScoreConfig) values() (url.Values, error) {
 735	v := url.Values{}
 736
 737	v.Add("user_id", strconv.Itoa(config.UserID))
 738	v.Add("score", strconv.Itoa(config.Score))
 739	if config.InlineMessageID == "" {
 740		if config.ChannelUsername == "" {
 741			v.Add("chat_id", strconv.Itoa(config.ChatID))
 742		} else {
 743			v.Add("chat_id", config.ChannelUsername)
 744		}
 745		v.Add("message_id", strconv.Itoa(config.MessageID))
 746	} else {
 747		v.Add("inline_message_id", config.InlineMessageID)
 748	}
 749	v.Add("disable_edit_message", strconv.FormatBool(config.DisableEditMessage))
 750
 751	return v, nil
 752}
 753
 754func (config SetGameScoreConfig) method() string {
 755	return "setGameScore"
 756}
 757
 758// GetGameHighScoresConfig allows you to fetch the high scores for a game.
 759type GetGameHighScoresConfig struct {
 760	UserID          int
 761	ChatID          int
 762	ChannelUsername string
 763	MessageID       int
 764	InlineMessageID string
 765}
 766
 767func (config GetGameHighScoresConfig) values() (url.Values, error) {
 768	v := url.Values{}
 769
 770	v.Add("user_id", strconv.Itoa(config.UserID))
 771	if config.InlineMessageID == "" {
 772		if config.ChannelUsername == "" {
 773			v.Add("chat_id", strconv.Itoa(config.ChatID))
 774		} else {
 775			v.Add("chat_id", config.ChannelUsername)
 776		}
 777		v.Add("message_id", strconv.Itoa(config.MessageID))
 778	} else {
 779		v.Add("inline_message_id", config.InlineMessageID)
 780	}
 781
 782	return v, nil
 783}
 784
 785func (config GetGameHighScoresConfig) method() string {
 786	return "getGameHighScores"
 787}
 788
 789// ChatActionConfig contains information about a SendChatAction request.
 790type ChatActionConfig struct {
 791	BaseChat
 792	Action string // required
 793}
 794
 795// values returns a url.Values representation of ChatActionConfig.
 796func (config ChatActionConfig) values() (url.Values, error) {
 797	v, err := config.BaseChat.values()
 798	if err != nil {
 799		return v, err
 800	}
 801	v.Add("action", config.Action)
 802	return v, nil
 803}
 804
 805// method returns Telegram API method name for sending ChatAction.
 806func (config ChatActionConfig) method() string {
 807	return "sendChatAction"
 808}
 809
 810// EditMessageTextConfig allows you to modify the text in a message.
 811type EditMessageTextConfig struct {
 812	BaseEdit
 813	Text                  string
 814	ParseMode             string
 815	DisableWebPagePreview bool
 816}
 817
 818func (config EditMessageTextConfig) values() (url.Values, error) {
 819	v, err := config.BaseEdit.values()
 820	if err != nil {
 821		return v, err
 822	}
 823
 824	v.Add("text", config.Text)
 825	v.Add("parse_mode", config.ParseMode)
 826	v.Add("disable_web_page_preview", strconv.FormatBool(config.DisableWebPagePreview))
 827
 828	return v, nil
 829}
 830
 831func (config EditMessageTextConfig) method() string {
 832	return "editMessageText"
 833}
 834
 835// EditMessageCaptionConfig allows you to modify the caption of a message.
 836type EditMessageCaptionConfig struct {
 837	BaseEdit
 838	Caption string
 839}
 840
 841func (config EditMessageCaptionConfig) values() (url.Values, error) {
 842	v, _ := config.BaseEdit.values()
 843
 844	v.Add("caption", config.Caption)
 845
 846	return v, nil
 847}
 848
 849func (config EditMessageCaptionConfig) method() string {
 850	return "editMessageCaption"
 851}
 852
 853// EditMessageReplyMarkupConfig allows you to modify the reply markup
 854// of a message.
 855type EditMessageReplyMarkupConfig struct {
 856	BaseEdit
 857}
 858
 859func (config EditMessageReplyMarkupConfig) values() (url.Values, error) {
 860	return config.BaseEdit.values()
 861}
 862
 863func (config EditMessageReplyMarkupConfig) method() string {
 864	return "editMessageReplyMarkup"
 865}
 866
 867// UserProfilePhotosConfig contains information about a
 868// GetUserProfilePhotos request.
 869type UserProfilePhotosConfig struct {
 870	UserID int
 871	Offset int
 872	Limit  int
 873}
 874
 875// FileConfig has information about a file hosted on Telegram.
 876type FileConfig struct {
 877	FileID string
 878}
 879
 880// UpdateConfig contains information about a GetUpdates request.
 881type UpdateConfig struct {
 882	Offset  int
 883	Limit   int
 884	Timeout int
 885}
 886
 887// WebhookConfig contains information about a SetWebhook request.
 888type WebhookConfig struct {
 889	URL            *url.URL
 890	Certificate    interface{}
 891	MaxConnections int
 892}
 893
 894func (config WebhookConfig) method() string {
 895	return "setWebhook"
 896}
 897
 898func (config WebhookConfig) values() (url.Values, error) {
 899	v := url.Values{}
 900
 901	if config.URL != nil {
 902		v.Add("url", config.URL.String())
 903	}
 904	if config.MaxConnections != 0 {
 905		v.Add("max_connections", strconv.Itoa(config.MaxConnections))
 906	}
 907
 908	return v, nil
 909}
 910
 911func (config WebhookConfig) params() (map[string]string, error) {
 912	params := make(map[string]string)
 913
 914	if config.URL != nil {
 915		params["url"] = config.URL.String()
 916	}
 917	if config.MaxConnections != 0 {
 918		params["max_connections"] = strconv.Itoa(config.MaxConnections)
 919	}
 920
 921	return params, nil
 922}
 923
 924func (config WebhookConfig) name() string {
 925	return "certificate"
 926}
 927
 928func (config WebhookConfig) getFile() interface{} {
 929	return config.Certificate
 930}
 931
 932func (config WebhookConfig) useExistingFile() bool {
 933	return config.URL != nil
 934}
 935
 936// RemoveWebhookConfig is a helper to remove a webhook.
 937type RemoveWebhookConfig struct {
 938}
 939
 940func (config RemoveWebhookConfig) method() string {
 941	return "setWebhook"
 942}
 943
 944func (config RemoveWebhookConfig) values() (url.Values, error) {
 945	return url.Values{}, nil
 946}
 947
 948// FileBytes contains information about a set of bytes to upload
 949// as a File.
 950type FileBytes struct {
 951	Name  string
 952	Bytes []byte
 953}
 954
 955// FileReader contains information about a reader to upload as a File.
 956// If Size is -1, it will read the entire Reader into memory to
 957// calculate a Size.
 958type FileReader struct {
 959	Name   string
 960	Reader io.Reader
 961	Size   int64
 962}
 963
 964// InlineConfig contains information on making an InlineQuery response.
 965type InlineConfig struct {
 966	InlineQueryID     string        `json:"inline_query_id"`
 967	Results           []interface{} `json:"results"`
 968	CacheTime         int           `json:"cache_time"`
 969	IsPersonal        bool          `json:"is_personal"`
 970	NextOffset        string        `json:"next_offset"`
 971	SwitchPMText      string        `json:"switch_pm_text"`
 972	SwitchPMParameter string        `json:"switch_pm_parameter"`
 973}
 974
 975func (config InlineConfig) method() string {
 976	return "answerInlineQuery"
 977}
 978
 979func (config InlineConfig) values() (url.Values, error) {
 980	v := url.Values{}
 981
 982	v.Add("inline_query_id", config.InlineQueryID)
 983	v.Add("cache_time", strconv.Itoa(config.CacheTime))
 984	v.Add("is_personal", strconv.FormatBool(config.IsPersonal))
 985	v.Add("next_offset", config.NextOffset)
 986	data, err := json.Marshal(config.Results)
 987	if err != nil {
 988		return v, err
 989	}
 990	v.Add("results", string(data))
 991	v.Add("switch_pm_text", config.SwitchPMText)
 992	v.Add("switch_pm_parameter", config.SwitchPMParameter)
 993
 994	return v, nil
 995}
 996
 997// CallbackConfig contains information on making a CallbackQuery response.
 998type CallbackConfig struct {
 999	CallbackQueryID string `json:"callback_query_id"`
1000	Text            string `json:"text"`
1001	ShowAlert       bool   `json:"show_alert"`
1002	URL             string `json:"url"`
1003	CacheTime       int    `json:"cache_time"`
1004}
1005
1006func (config CallbackConfig) method() string {
1007	return "answerCallbackQuery"
1008}
1009
1010func (config CallbackConfig) values() (url.Values, error) {
1011	v := url.Values{}
1012
1013	v.Add("callback_query_id", config.CallbackQueryID)
1014	if config.Text != "" {
1015		v.Add("text", config.Text)
1016	}
1017	v.Add("show_alert", strconv.FormatBool(config.ShowAlert))
1018	if config.URL != "" {
1019		v.Add("url", config.URL)
1020	}
1021	v.Add("cache_time", strconv.Itoa(config.CacheTime))
1022
1023	return v, nil
1024}
1025
1026// ChatMemberConfig contains information about a user in a chat for use
1027// with administrative functions such as kicking or unbanning a user.
1028type ChatMemberConfig struct {
1029	ChatID             int64
1030	SuperGroupUsername string
1031	ChannelUsername    string
1032	UserID             int
1033}
1034
1035// UnbanChatMemberConfig allows you to unban a user.
1036type UnbanChatMemberConfig struct {
1037	ChatMemberConfig
1038}
1039
1040func (config UnbanChatMemberConfig) method() string {
1041	return "unbanChatMember"
1042}
1043
1044func (config UnbanChatMemberConfig) values() (url.Values, error) {
1045	v := url.Values{}
1046
1047	if config.SuperGroupUsername != "" {
1048		v.Add("chat_id", config.SuperGroupUsername)
1049	} else if config.ChannelUsername != "" {
1050		v.Add("chat_id", config.ChannelUsername)
1051	} else {
1052		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1053	}
1054	v.Add("user_id", strconv.Itoa(config.UserID))
1055
1056	return v, nil
1057}
1058
1059// KickChatMemberConfig contains extra fields to kick user
1060type KickChatMemberConfig struct {
1061	ChatMemberConfig
1062	UntilDate int64
1063}
1064
1065func (config KickChatMemberConfig) method() string {
1066	return "kickChatMember"
1067}
1068
1069func (config KickChatMemberConfig) values() (url.Values, error) {
1070	v := url.Values{}
1071
1072	if config.SuperGroupUsername == "" {
1073		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1074	} else {
1075		v.Add("chat_id", config.SuperGroupUsername)
1076	}
1077	v.Add("user_id", strconv.Itoa(config.UserID))
1078
1079	if config.UntilDate != 0 {
1080		v.Add("until_date", strconv.FormatInt(config.UntilDate, 10))
1081	}
1082
1083	return v, nil
1084}
1085
1086// RestrictChatMemberConfig contains fields to restrict members of chat
1087type RestrictChatMemberConfig struct {
1088	ChatMemberConfig
1089	UntilDate             int64
1090	CanSendMessages       *bool
1091	CanSendMediaMessages  *bool
1092	CanSendOtherMessages  *bool
1093	CanAddWebPagePreviews *bool
1094}
1095
1096func (config RestrictChatMemberConfig) method() string {
1097	return "restrictChatMember"
1098}
1099
1100func (config RestrictChatMemberConfig) values() (url.Values, error) {
1101	v := url.Values{}
1102
1103	if config.SuperGroupUsername != "" {
1104		v.Add("chat_id", config.SuperGroupUsername)
1105	} else if config.ChannelUsername != "" {
1106		v.Add("chat_id", config.ChannelUsername)
1107	} else {
1108		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1109	}
1110	v.Add("user_id", strconv.Itoa(config.UserID))
1111
1112	if config.CanSendMessages != nil {
1113		v.Add("can_send_messages", strconv.FormatBool(*config.CanSendMessages))
1114	}
1115	if config.CanSendMediaMessages != nil {
1116		v.Add("can_send_media_messages", strconv.FormatBool(*config.CanSendMediaMessages))
1117	}
1118	if config.CanSendOtherMessages != nil {
1119		v.Add("can_send_other_messages", strconv.FormatBool(*config.CanSendOtherMessages))
1120	}
1121	if config.CanAddWebPagePreviews != nil {
1122		v.Add("can_add_web_page_previews", strconv.FormatBool(*config.CanAddWebPagePreviews))
1123	}
1124	if config.UntilDate != 0 {
1125		v.Add("until_date", strconv.FormatInt(config.UntilDate, 10))
1126	}
1127
1128	return v, nil
1129}
1130
1131// PromoteChatMemberConfig contains fields to promote members of chat
1132type PromoteChatMemberConfig struct {
1133	ChatMemberConfig
1134	CanChangeInfo      *bool
1135	CanPostMessages    *bool
1136	CanEditMessages    *bool
1137	CanDeleteMessages  *bool
1138	CanInviteUsers     *bool
1139	CanRestrictMembers *bool
1140	CanPinMessages     *bool
1141	CanPromoteMembers  *bool
1142}
1143
1144func (config PromoteChatMemberConfig) method() string {
1145	return "promoteChatMember"
1146}
1147
1148func (config PromoteChatMemberConfig) values() (url.Values, error) {
1149	v := url.Values{}
1150
1151	if config.SuperGroupUsername != "" {
1152		v.Add("chat_id", config.SuperGroupUsername)
1153	} else if config.ChannelUsername != "" {
1154		v.Add("chat_id", config.ChannelUsername)
1155	} else {
1156		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1157	}
1158	v.Add("user_id", strconv.Itoa(config.UserID))
1159
1160	if config.CanChangeInfo != nil {
1161		v.Add("can_change_info", strconv.FormatBool(*config.CanChangeInfo))
1162	}
1163	if config.CanPostMessages != nil {
1164		v.Add("can_post_messages", strconv.FormatBool(*config.CanPostMessages))
1165	}
1166	if config.CanEditMessages != nil {
1167		v.Add("can_edit_messages", strconv.FormatBool(*config.CanEditMessages))
1168	}
1169	if config.CanDeleteMessages != nil {
1170		v.Add("can_delete_messages", strconv.FormatBool(*config.CanDeleteMessages))
1171	}
1172	if config.CanInviteUsers != nil {
1173		v.Add("can_invite_users", strconv.FormatBool(*config.CanInviteUsers))
1174	}
1175	if config.CanRestrictMembers != nil {
1176		v.Add("can_restrict_members", strconv.FormatBool(*config.CanRestrictMembers))
1177	}
1178	if config.CanPinMessages != nil {
1179		v.Add("can_pin_messages", strconv.FormatBool(*config.CanPinMessages))
1180	}
1181	if config.CanPromoteMembers != nil {
1182		v.Add("can_promote_members", strconv.FormatBool(*config.CanPromoteMembers))
1183	}
1184
1185	return v, nil
1186}
1187
1188// ChatConfig contains information about getting information on a chat.
1189type ChatConfig struct {
1190	ChatID             int64
1191	SuperGroupUsername string
1192}
1193
1194// LeaveChatConfig allows you to leave a chat.
1195type LeaveChatConfig struct {
1196	ChatID          int64
1197	ChannelUsername string
1198}
1199
1200func (config LeaveChatConfig) method() string {
1201	return "leaveChat"
1202}
1203
1204func (config LeaveChatConfig) values() (url.Values, error) {
1205	v := url.Values{}
1206
1207	if config.ChannelUsername == "" {
1208		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1209	} else {
1210		v.Add("chat_id", config.ChannelUsername)
1211	}
1212
1213	return v, nil
1214}
1215
1216// ChatConfigWithUser contains information about getting information on
1217// a specific user within a chat.
1218type ChatConfigWithUser struct {
1219	ChatID             int64
1220	SuperGroupUsername string
1221	UserID             int
1222}
1223
1224// InvoiceConfig contains information for sendInvoice request.
1225type InvoiceConfig struct {
1226	BaseChat
1227	Title               string          // required
1228	Description         string          // required
1229	Payload             string          // required
1230	ProviderToken       string          // required
1231	StartParameter      string          // required
1232	Currency            string          // required
1233	Prices              *[]LabeledPrice // required
1234	ProviderData        string
1235	PhotoURL            string
1236	PhotoSize           int
1237	PhotoWidth          int
1238	PhotoHeight         int
1239	NeedName            bool
1240	NeedPhoneNumber     bool
1241	NeedEmail           bool
1242	NeedShippingAddress bool
1243	IsFlexible          bool
1244}
1245
1246func (config InvoiceConfig) values() (url.Values, error) {
1247	v, err := config.BaseChat.values()
1248	if err != nil {
1249		return v, err
1250	}
1251	v.Add("title", config.Title)
1252	v.Add("description", config.Description)
1253	v.Add("payload", config.Payload)
1254	v.Add("provider_token", config.ProviderToken)
1255	v.Add("start_parameter", config.StartParameter)
1256	v.Add("currency", config.Currency)
1257	data, err := json.Marshal(config.Prices)
1258	if err != nil {
1259		return v, err
1260	}
1261	v.Add("prices", string(data))
1262	if config.ProviderData != "" {
1263		v.Add("provider_data", config.ProviderData)
1264	}
1265	if config.PhotoURL != "" {
1266		v.Add("photo_url", config.PhotoURL)
1267	}
1268	if config.PhotoSize != 0 {
1269		v.Add("photo_size", strconv.Itoa(config.PhotoSize))
1270	}
1271	if config.PhotoWidth != 0 {
1272		v.Add("photo_width", strconv.Itoa(config.PhotoWidth))
1273	}
1274	if config.PhotoHeight != 0 {
1275		v.Add("photo_height", strconv.Itoa(config.PhotoHeight))
1276	}
1277	if config.NeedName != false {
1278		v.Add("need_name", strconv.FormatBool(config.NeedName))
1279	}
1280	if config.NeedPhoneNumber != false {
1281		v.Add("need_phone_number", strconv.FormatBool(config.NeedPhoneNumber))
1282	}
1283	if config.NeedEmail != false {
1284		v.Add("need_email", strconv.FormatBool(config.NeedEmail))
1285	}
1286	if config.NeedShippingAddress != false {
1287		v.Add("need_shipping_address", strconv.FormatBool(config.NeedShippingAddress))
1288	}
1289	if config.IsFlexible != false {
1290		v.Add("is_flexible", strconv.FormatBool(config.IsFlexible))
1291	}
1292
1293	return v, nil
1294}
1295
1296func (config InvoiceConfig) method() string {
1297	return "sendInvoice"
1298}
1299
1300// ShippingConfig contains information for answerShippingQuery request.
1301type ShippingConfig struct {
1302	ShippingQueryID string // required
1303	OK              bool   // required
1304	ShippingOptions *[]ShippingOption
1305	ErrorMessage    string
1306}
1307
1308// PreCheckoutConfig conatins information for answerPreCheckoutQuery request.
1309type PreCheckoutConfig struct {
1310	PreCheckoutQueryID string // required
1311	OK                 bool   // required
1312	ErrorMessage       string
1313}
1314
1315// DeleteMessageConfig contains information of a message in a chat to delete.
1316type DeleteMessageConfig struct {
1317	ChatID    int64
1318	MessageID int
1319}
1320
1321func (config DeleteMessageConfig) method() string {
1322	return "deleteMessage"
1323}
1324
1325func (config DeleteMessageConfig) values() (url.Values, error) {
1326	v := url.Values{}
1327
1328	v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1329	v.Add("message_id", strconv.Itoa(config.MessageID))
1330
1331	return v, nil
1332}
1333
1334// PinChatMessageConfig contains information of a message in a chat to pin.
1335type PinChatMessageConfig struct {
1336	ChatID              int64
1337	ChannelUsername     string
1338	MessageID           int
1339	DisableNotification bool
1340}
1341
1342func (config PinChatMessageConfig) method() string {
1343	return "pinChatMessage"
1344}
1345
1346func (config PinChatMessageConfig) values() (url.Values, error) {
1347	v := url.Values{}
1348
1349	if config.ChannelUsername == "" {
1350		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1351	} else {
1352		v.Add("chat_id", config.ChannelUsername)
1353	}
1354	v.Add("message_id", strconv.Itoa(config.MessageID))
1355	v.Add("disable_notification", strconv.FormatBool(config.DisableNotification))
1356
1357	return v, nil
1358}
1359
1360// UnpinChatMessageConfig contains information of chat to unpin.
1361type UnpinChatMessageConfig struct {
1362	ChatID          int64
1363	ChannelUsername string
1364}
1365
1366func (config UnpinChatMessageConfig) method() string {
1367	return "unpinChatMessage"
1368}
1369
1370func (config UnpinChatMessageConfig) values() (url.Values, error) {
1371	v := url.Values{}
1372
1373	if config.ChannelUsername == "" {
1374		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1375	} else {
1376		v.Add("chat_id", config.ChannelUsername)
1377	}
1378
1379	return v, nil
1380}
1381
1382// SetChatPhotoConfig allows you to set a group, supergroup, or channel's photo.
1383type SetChatPhotoConfig struct {
1384	ChatID          int64
1385	ChannelUsername string
1386
1387	Photo interface{}
1388}
1389
1390func (config SetChatPhotoConfig) method() string {
1391	return "setChatPhoto"
1392}
1393
1394func (config SetChatPhotoConfig) name() string {
1395	return "photo"
1396}
1397
1398func (config SetChatPhotoConfig) values() (url.Values, error) {
1399	v := url.Values{}
1400
1401	if config.ChannelUsername == "" {
1402		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1403	} else {
1404		v.Add("chat_id", config.ChannelUsername)
1405	}
1406
1407	return v, nil
1408}
1409
1410func (config SetChatPhotoConfig) params() map[string]string {
1411	params := make(map[string]string)
1412
1413	if config.ChannelUsername == "" {
1414		params["chat_id"] = strconv.FormatInt(config.ChatID, 10)
1415	} else {
1416		params["chat_id"] = config.ChannelUsername
1417	}
1418
1419	return params
1420}
1421
1422func (config SetChatPhotoConfig) getFile() interface{} {
1423	return config.Photo
1424}
1425
1426func (config SetChatPhotoConfig) useExistingFile() bool {
1427	return false
1428}
1429
1430// DeleteChatPhotoConfig allows you to delete a group, supergroup, or channel's photo.
1431type DeleteChatPhotoConfig struct {
1432	ChatID          int64
1433	ChannelUsername string
1434}
1435
1436func (config DeleteChatPhotoConfig) method() string {
1437	return "deleteChatPhoto"
1438}
1439
1440func (config DeleteChatPhotoConfig) values() (url.Values, error) {
1441	v := url.Values{}
1442
1443	if config.ChannelUsername == "" {
1444		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1445	} else {
1446		v.Add("chat_id", config.ChannelUsername)
1447	}
1448
1449	return v, nil
1450}
1451
1452// SetChatTitleConfig allows you to set the title of something other than a private chat.
1453type SetChatTitleConfig struct {
1454	ChatID          int64
1455	ChannelUsername string
1456
1457	Title string
1458}
1459
1460func (config SetChatTitleConfig) method() string {
1461	return "setChatTitle"
1462}
1463
1464func (config SetChatTitleConfig) values() (url.Values, error) {
1465	v := url.Values{}
1466
1467	if config.ChannelUsername == "" {
1468		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1469	} else {
1470		v.Add("chat_id", config.ChannelUsername)
1471	}
1472
1473	v.Add("title", config.Title)
1474
1475	return v, nil
1476}
1477
1478// SetChatDescriptionConfig allows you to set the description of a supergroup or channel.
1479type SetChatDescriptionConfig struct {
1480	ChatID          int64
1481	ChannelUsername string
1482
1483	Description string
1484}
1485
1486func (config SetChatDescriptionConfig) method() string {
1487	return "setChatDescription"
1488}
1489
1490func (config SetChatDescriptionConfig) values() (url.Values, error) {
1491	v := url.Values{}
1492
1493	if config.ChannelUsername == "" {
1494		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1495	} else {
1496		v.Add("chat_id", config.ChannelUsername)
1497	}
1498
1499	v.Add("description", config.Description)
1500
1501	return v, nil
1502}
1503
1504// GetStickerSetConfig allows you to get the stickers in a set.
1505type GetStickerSetConfig struct {
1506	Name string
1507}
1508
1509func (config GetStickerSetConfig) method() string {
1510	return "getStickerSet"
1511}
1512
1513func (config GetStickerSetConfig) values() (url.Values, error) {
1514	v := url.Values{}
1515
1516	v.Add("name", config.Name)
1517
1518	return v, nil
1519}
1520
1521// UploadStickerConfig allows you to upload a sticker for use in a set later.
1522type UploadStickerConfig struct {
1523	UserID     int64
1524	PNGSticker interface{}
1525}
1526
1527func (config UploadStickerConfig) method() string {
1528	return "uploadStickerFile"
1529}
1530
1531func (config UploadStickerConfig) values() (url.Values, error) {
1532	v := url.Values{}
1533
1534	v.Add("user_id", strconv.FormatInt(config.UserID, 10))
1535
1536	return v, nil
1537}
1538
1539func (config UploadStickerConfig) params() (map[string]string, error) {
1540	params := make(map[string]string)
1541
1542	params["user_id"] = strconv.FormatInt(config.UserID, 10)
1543
1544	return params, nil
1545}
1546
1547func (config UploadStickerConfig) name() string {
1548	return "png_sticker"
1549}
1550
1551func (config UploadStickerConfig) getFile() interface{} {
1552	return config.PNGSticker
1553}
1554
1555func (config UploadStickerConfig) useExistingFile() bool {
1556	return false
1557}
1558
1559// NewStickerSetConfig allows creating a new sticker set.
1560type NewStickerSetConfig struct {
1561	UserID        int64
1562	Name          string
1563	Title         string
1564	PNGSticker    interface{}
1565	Emojis        string
1566	ContainsMasks bool
1567	MaskPosition  *MaskPosition
1568}
1569
1570func (config NewStickerSetConfig) method() string {
1571	return "createNewStickerSet"
1572}
1573
1574func (config NewStickerSetConfig) values() (url.Values, error) {
1575	v := url.Values{}
1576
1577	v.Add("user_id", strconv.FormatInt(config.UserID, 10))
1578	v.Add("name", config.Name)
1579	v.Add("title", config.Title)
1580	if sticker, ok := config.PNGSticker.(string); ok {
1581		v.Add("png_sticker", sticker)
1582	}
1583	v.Add("emojis", config.Emojis)
1584	if config.ContainsMasks {
1585		v.Add("contains_masks", strconv.FormatBool(config.ContainsMasks))
1586
1587		data, err := json.Marshal(config.MaskPosition)
1588		if err != nil {
1589			return v, err
1590		}
1591
1592		v.Add("mask_position", string(data))
1593	}
1594
1595	return v, nil
1596}
1597
1598func (config NewStickerSetConfig) params() (map[string]string, error) {
1599	params := make(map[string]string)
1600
1601	params["user_id"] = strconv.FormatInt(config.UserID, 10)
1602	params["name"] = config.Name
1603	params["title"] = config.Title
1604	params["emojis"] = config.Emojis
1605	if config.ContainsMasks {
1606		params["contains_masks"] = strconv.FormatBool(config.ContainsMasks)
1607
1608		data, err := json.Marshal(config.MaskPosition)
1609		if err != nil {
1610			return params, err
1611		}
1612
1613		params["mask_position"] = string(data)
1614	}
1615
1616	return params, nil
1617}
1618
1619func (config NewStickerSetConfig) getFile() interface{} {
1620	return config.PNGSticker
1621}
1622
1623func (config NewStickerSetConfig) name() string {
1624	return "png_sticker"
1625}
1626
1627func (config NewStickerSetConfig) useExistingFile() bool {
1628	_, ok := config.PNGSticker.(string)
1629
1630	return ok
1631}
1632
1633// AddStickerConfig allows you to add a sticker to a set.
1634type AddStickerConfig struct {
1635	UserID       int64
1636	Name         string
1637	PNGSticker   interface{}
1638	Emojis       string
1639	MaskPosition *MaskPosition
1640}
1641
1642func (config AddStickerConfig) method() string {
1643	return "addStickerToSet"
1644}
1645
1646func (config AddStickerConfig) values() (url.Values, error) {
1647	v := url.Values{}
1648
1649	v.Add("user_id", strconv.FormatInt(config.UserID, 10))
1650	v.Add("name", config.Name)
1651	if sticker, ok := config.PNGSticker.(string); ok {
1652		v.Add("png_sticker", sticker)
1653	}
1654	v.Add("emojis", config.Emojis)
1655	if config.MaskPosition != nil {
1656		data, err := json.Marshal(config.MaskPosition)
1657		if err != nil {
1658			return v, err
1659		}
1660
1661		v.Add("mask_position", string(data))
1662	}
1663
1664	return v, nil
1665}
1666
1667func (config AddStickerConfig) params() (map[string]string, error) {
1668	params := make(map[string]string)
1669
1670	params["user_id"] = strconv.FormatInt(config.UserID, 10)
1671	params["name"] = config.Name
1672	params["emojis"] = config.Emojis
1673	if config.MaskPosition != nil {
1674		data, err := json.Marshal(config.MaskPosition)
1675		if err != nil {
1676			return params, err
1677		}
1678
1679		params["mask_position"] = string(data)
1680	}
1681
1682	return params, nil
1683}
1684
1685func (config AddStickerConfig) name() string {
1686	return "png_sticker"
1687}
1688
1689func (config AddStickerConfig) getFile() interface{} {
1690	return config.PNGSticker
1691}
1692
1693func (config AddStickerConfig) useExistingFile() bool {
1694	return false
1695}
1696
1697// SetStickerPositionConfig allows you to change the position of a sticker in a set.
1698type SetStickerPositionConfig struct {
1699	Sticker  string
1700	Position int
1701}
1702
1703func (config SetStickerPositionConfig) method() string {
1704	return "setStickerPositionInSet"
1705}
1706
1707func (config SetStickerPositionConfig) values() (url.Values, error) {
1708	v := url.Values{}
1709
1710	v.Add("sticker", config.Sticker)
1711	v.Add("position", strconv.Itoa(config.Position))
1712
1713	return v, nil
1714}
1715
1716// DeleteStickerConfig allows you to delete a sticker from a set.
1717type DeleteStickerConfig struct {
1718	Sticker string
1719}
1720
1721func (config DeleteStickerConfig) method() string {
1722	return "deleteStickerFromSet"
1723}
1724
1725func (config DeleteStickerConfig) values() (url.Values, error) {
1726	v := url.Values{}
1727
1728	v.Add("sticker", config.Sticker)
1729
1730	return v, nil
1731}
1732
1733// SetChatStickerSetConfig allows you to set the sticker set for a supergroup.
1734type SetChatStickerSetConfig struct {
1735	ChatID             int64
1736	SuperGroupUsername string
1737
1738	StickerSetName string
1739}
1740
1741func (config SetChatStickerSetConfig) method() string {
1742	return "setChatStickerSet"
1743}
1744
1745func (config SetChatStickerSetConfig) values() (url.Values, error) {
1746	v := url.Values{}
1747
1748	if config.SuperGroupUsername == "" {
1749		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1750	} else {
1751		v.Add("chat_id", config.SuperGroupUsername)
1752	}
1753
1754	v.Add("sticker_set_name", config.StickerSetName)
1755
1756	return v, nil
1757}
1758
1759// DeleteChatStickerSetConfig allows you to remove a supergroup's sticker set.
1760type DeleteChatStickerSetConfig struct {
1761	ChatID             int64
1762	SuperGroupUsername string
1763}
1764
1765func (config DeleteChatStickerSetConfig) method() string {
1766	return "deleteChatStickerSet"
1767}
1768
1769func (config DeleteChatStickerSetConfig) values() (url.Values, error) {
1770	v := url.Values{}
1771
1772	if config.SuperGroupUsername == "" {
1773		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1774	} else {
1775		v.Add("chat_id", config.SuperGroupUsername)
1776	}
1777
1778	return v, nil
1779}
1780
1781// MediaGroupConfig allows you to send a group of media.
1782//
1783// Media consist of InputMedia items (InputMediaPhoto, InputMediaVideo).
1784type MediaGroupConfig struct {
1785	ChatID          int64
1786	ChannelUsername string
1787
1788	Media               []interface{}
1789	DisableNotification bool
1790	ReplyToMessageID    int
1791}
1792
1793func (config MediaGroupConfig) method() string {
1794	return "sendMediaGroup"
1795}
1796
1797func (config MediaGroupConfig) values() (url.Values, error) {
1798	v := url.Values{}
1799
1800	if config.ChannelUsername == "" {
1801		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1802	} else {
1803		v.Add("chat_id", config.ChannelUsername)
1804	}
1805	bytes, err := json.Marshal(config.Media)
1806	if err != nil {
1807		return v, err
1808	}
1809	v.Add("media", string(bytes))
1810	if config.DisableNotification {
1811		v.Add("disable_notification", strconv.FormatBool(config.DisableNotification))
1812	}
1813	if config.ReplyToMessageID != 0 {
1814		v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageID))
1815	}
1816
1817	return v, nil
1818}