all repos — telegram-bot-api @ 1aef8c8c45f5d2ab2c7b556d5b2445ac35daf48f

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// EditMessageLiveLocationConfig allows you to update a live location.
 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// StopMessageLiveLocationConfig stops updating a live location.
 626type StopMessageLiveLocationConfig struct {
 627	BaseEdit
 628}
 629
 630// values returns a url.Values representation of StopMessageLiveLocationConfig.
 631func (config StopMessageLiveLocationConfig) values() (url.Values, error) {
 632	return config.BaseEdit.values()
 633}
 634
 635// method returns Telegram API method name for stop message Live Location.
 636func (config StopMessageLiveLocationConfig) method() string {
 637	return "stopMessageLiveLocation"
 638}
 639
 640// VenueConfig contains information about a SendVenue request.
 641type VenueConfig struct {
 642	BaseChat
 643	Latitude     float64 // required
 644	Longitude    float64 // required
 645	Title        string  // required
 646	Address      string  // required
 647	FoursquareID string
 648}
 649
 650func (config VenueConfig) values() (url.Values, error) {
 651	v, err := config.BaseChat.values()
 652	if err != nil {
 653		return v, err
 654	}
 655
 656	v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
 657	v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
 658	v.Add("title", config.Title)
 659	v.Add("address", config.Address)
 660	if config.FoursquareID != "" {
 661		v.Add("foursquare_id", config.FoursquareID)
 662	}
 663
 664	return v, nil
 665}
 666
 667func (config VenueConfig) method() string {
 668	return "sendVenue"
 669}
 670
 671// ContactConfig allows you to send a contact.
 672type ContactConfig struct {
 673	BaseChat
 674	PhoneNumber string
 675	FirstName   string
 676	LastName    string
 677}
 678
 679func (config ContactConfig) values() (url.Values, error) {
 680	v, err := config.BaseChat.values()
 681	if err != nil {
 682		return v, err
 683	}
 684
 685	v.Add("phone_number", config.PhoneNumber)
 686	v.Add("first_name", config.FirstName)
 687	v.Add("last_name", config.LastName)
 688
 689	return v, nil
 690}
 691
 692func (config ContactConfig) method() string {
 693	return "sendContact"
 694}
 695
 696// GameConfig allows you to send a game.
 697type GameConfig struct {
 698	BaseChat
 699	GameShortName string
 700}
 701
 702func (config GameConfig) values() (url.Values, error) {
 703	v, err := config.BaseChat.values()
 704	if err != nil {
 705		return v, err
 706	}
 707
 708	v.Add("game_short_name", config.GameShortName)
 709
 710	return v, nil
 711}
 712
 713func (config GameConfig) method() string {
 714	return "sendGame"
 715}
 716
 717// SetGameScoreConfig allows you to update the game score in a chat.
 718type SetGameScoreConfig struct {
 719	UserID             int
 720	Score              int
 721	Force              bool
 722	DisableEditMessage bool
 723	ChatID             int64
 724	ChannelUsername    string
 725	MessageID          int
 726	InlineMessageID    string
 727}
 728
 729func (config SetGameScoreConfig) values() (url.Values, error) {
 730	v := url.Values{}
 731
 732	v.Add("user_id", strconv.Itoa(config.UserID))
 733	v.Add("score", strconv.Itoa(config.Score))
 734	if config.InlineMessageID == "" {
 735		if config.ChannelUsername == "" {
 736			v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
 737		} else {
 738			v.Add("chat_id", config.ChannelUsername)
 739		}
 740		v.Add("message_id", strconv.Itoa(config.MessageID))
 741	} else {
 742		v.Add("inline_message_id", config.InlineMessageID)
 743	}
 744	v.Add("disable_edit_message", strconv.FormatBool(config.DisableEditMessage))
 745
 746	return v, nil
 747}
 748
 749func (config SetGameScoreConfig) method() string {
 750	return "setGameScore"
 751}
 752
 753// GetGameHighScoresConfig allows you to fetch the high scores for a game.
 754type GetGameHighScoresConfig struct {
 755	UserID          int
 756	ChatID          int
 757	ChannelUsername string
 758	MessageID       int
 759	InlineMessageID string
 760}
 761
 762func (config GetGameHighScoresConfig) values() (url.Values, error) {
 763	v := url.Values{}
 764
 765	v.Add("user_id", strconv.Itoa(config.UserID))
 766	if config.InlineMessageID == "" {
 767		if config.ChannelUsername == "" {
 768			v.Add("chat_id", strconv.Itoa(config.ChatID))
 769		} else {
 770			v.Add("chat_id", config.ChannelUsername)
 771		}
 772		v.Add("message_id", strconv.Itoa(config.MessageID))
 773	} else {
 774		v.Add("inline_message_id", config.InlineMessageID)
 775	}
 776
 777	return v, nil
 778}
 779
 780func (config GetGameHighScoresConfig) method() string {
 781	return "getGameHighScores"
 782}
 783
 784// ChatActionConfig contains information about a SendChatAction request.
 785type ChatActionConfig struct {
 786	BaseChat
 787	Action string // required
 788}
 789
 790// values returns a url.Values representation of ChatActionConfig.
 791func (config ChatActionConfig) values() (url.Values, error) {
 792	v, err := config.BaseChat.values()
 793	if err != nil {
 794		return v, err
 795	}
 796	v.Add("action", config.Action)
 797	return v, nil
 798}
 799
 800// method returns Telegram API method name for sending ChatAction.
 801func (config ChatActionConfig) method() string {
 802	return "sendChatAction"
 803}
 804
 805// EditMessageTextConfig allows you to modify the text in a message.
 806type EditMessageTextConfig struct {
 807	BaseEdit
 808	Text                  string
 809	ParseMode             string
 810	DisableWebPagePreview bool
 811}
 812
 813func (config EditMessageTextConfig) values() (url.Values, error) {
 814	v, err := config.BaseEdit.values()
 815	if err != nil {
 816		return v, err
 817	}
 818
 819	v.Add("text", config.Text)
 820	v.Add("parse_mode", config.ParseMode)
 821	v.Add("disable_web_page_preview", strconv.FormatBool(config.DisableWebPagePreview))
 822
 823	return v, nil
 824}
 825
 826func (config EditMessageTextConfig) method() string {
 827	return "editMessageText"
 828}
 829
 830// EditMessageCaptionConfig allows you to modify the caption of a message.
 831type EditMessageCaptionConfig struct {
 832	BaseEdit
 833	Caption string
 834}
 835
 836func (config EditMessageCaptionConfig) values() (url.Values, error) {
 837	v, _ := config.BaseEdit.values()
 838
 839	v.Add("caption", config.Caption)
 840
 841	return v, nil
 842}
 843
 844func (config EditMessageCaptionConfig) method() string {
 845	return "editMessageCaption"
 846}
 847
 848// EditMessageReplyMarkupConfig allows you to modify the reply markup
 849// of a message.
 850type EditMessageReplyMarkupConfig struct {
 851	BaseEdit
 852}
 853
 854func (config EditMessageReplyMarkupConfig) values() (url.Values, error) {
 855	return config.BaseEdit.values()
 856}
 857
 858func (config EditMessageReplyMarkupConfig) method() string {
 859	return "editMessageReplyMarkup"
 860}
 861
 862// UserProfilePhotosConfig contains information about a
 863// GetUserProfilePhotos request.
 864type UserProfilePhotosConfig struct {
 865	UserID int
 866	Offset int
 867	Limit  int
 868}
 869
 870// FileConfig has information about a file hosted on Telegram.
 871type FileConfig struct {
 872	FileID string
 873}
 874
 875// UpdateConfig contains information about a GetUpdates request.
 876type UpdateConfig struct {
 877	Offset  int
 878	Limit   int
 879	Timeout int
 880}
 881
 882// WebhookConfig contains information about a SetWebhook request.
 883type WebhookConfig struct {
 884	URL            *url.URL
 885	Certificate    interface{}
 886	MaxConnections int
 887}
 888
 889func (config WebhookConfig) method() string {
 890	return "setWebhook"
 891}
 892
 893func (config WebhookConfig) values() (url.Values, error) {
 894	v := url.Values{}
 895
 896	if config.URL != nil {
 897		v.Add("url", config.URL.String())
 898	}
 899	if config.MaxConnections != 0 {
 900		v.Add("max_connections", strconv.Itoa(config.MaxConnections))
 901	}
 902
 903	return v, nil
 904}
 905
 906func (config WebhookConfig) params() (map[string]string, error) {
 907	params := make(map[string]string)
 908
 909	if config.URL != nil {
 910		params["url"] = config.URL.String()
 911	}
 912	if config.MaxConnections != 0 {
 913		params["max_connections"] = strconv.Itoa(config.MaxConnections)
 914	}
 915
 916	return params, nil
 917}
 918
 919func (config WebhookConfig) name() string {
 920	return "certificate"
 921}
 922
 923func (config WebhookConfig) getFile() interface{} {
 924	return config.Certificate
 925}
 926
 927func (config WebhookConfig) useExistingFile() bool {
 928	return config.URL != nil
 929}
 930
 931// RemoveWebhookConfig is a helper to remove a webhook.
 932type RemoveWebhookConfig struct {
 933}
 934
 935func (config RemoveWebhookConfig) method() string {
 936	return "setWebhook"
 937}
 938
 939func (config RemoveWebhookConfig) values() (url.Values, error) {
 940	return url.Values{}, nil
 941}
 942
 943// FileBytes contains information about a set of bytes to upload
 944// as a File.
 945type FileBytes struct {
 946	Name  string
 947	Bytes []byte
 948}
 949
 950// FileReader contains information about a reader to upload as a File.
 951// If Size is -1, it will read the entire Reader into memory to
 952// calculate a Size.
 953type FileReader struct {
 954	Name   string
 955	Reader io.Reader
 956	Size   int64
 957}
 958
 959// InlineConfig contains information on making an InlineQuery response.
 960type InlineConfig struct {
 961	InlineQueryID     string        `json:"inline_query_id"`
 962	Results           []interface{} `json:"results"`
 963	CacheTime         int           `json:"cache_time"`
 964	IsPersonal        bool          `json:"is_personal"`
 965	NextOffset        string        `json:"next_offset"`
 966	SwitchPMText      string        `json:"switch_pm_text"`
 967	SwitchPMParameter string        `json:"switch_pm_parameter"`
 968}
 969
 970func (config InlineConfig) method() string {
 971	return "answerInlineQuery"
 972}
 973
 974func (config InlineConfig) values() (url.Values, error) {
 975	v := url.Values{}
 976
 977	v.Add("inline_query_id", config.InlineQueryID)
 978	v.Add("cache_time", strconv.Itoa(config.CacheTime))
 979	v.Add("is_personal", strconv.FormatBool(config.IsPersonal))
 980	v.Add("next_offset", config.NextOffset)
 981	data, err := json.Marshal(config.Results)
 982	if err != nil {
 983		return v, err
 984	}
 985	v.Add("results", string(data))
 986	v.Add("switch_pm_text", config.SwitchPMText)
 987	v.Add("switch_pm_parameter", config.SwitchPMParameter)
 988
 989	return v, nil
 990}
 991
 992// CallbackConfig contains information on making a CallbackQuery response.
 993type CallbackConfig struct {
 994	CallbackQueryID string `json:"callback_query_id"`
 995	Text            string `json:"text"`
 996	ShowAlert       bool   `json:"show_alert"`
 997	URL             string `json:"url"`
 998	CacheTime       int    `json:"cache_time"`
 999}
1000
1001func (config CallbackConfig) method() string {
1002	return "answerCallbackQuery"
1003}
1004
1005func (config CallbackConfig) values() (url.Values, error) {
1006	v := url.Values{}
1007
1008	v.Add("callback_query_id", config.CallbackQueryID)
1009	if config.Text != "" {
1010		v.Add("text", config.Text)
1011	}
1012	v.Add("show_alert", strconv.FormatBool(config.ShowAlert))
1013	if config.URL != "" {
1014		v.Add("url", config.URL)
1015	}
1016	v.Add("cache_time", strconv.Itoa(config.CacheTime))
1017
1018	return v, nil
1019}
1020
1021// ChatMemberConfig contains information about a user in a chat for use
1022// with administrative functions such as kicking or unbanning a user.
1023type ChatMemberConfig struct {
1024	ChatID             int64
1025	SuperGroupUsername string
1026	ChannelUsername    string
1027	UserID             int
1028}
1029
1030// UnbanChatMemberConfig allows you to unban a user.
1031type UnbanChatMemberConfig struct {
1032	ChatMemberConfig
1033}
1034
1035func (config UnbanChatMemberConfig) method() string {
1036	return "unbanChatMember"
1037}
1038
1039func (config UnbanChatMemberConfig) values() (url.Values, error) {
1040	v := url.Values{}
1041
1042	if config.SuperGroupUsername != "" {
1043		v.Add("chat_id", config.SuperGroupUsername)
1044	} else if config.ChannelUsername != "" {
1045		v.Add("chat_id", config.ChannelUsername)
1046	} else {
1047		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1048	}
1049	v.Add("user_id", strconv.Itoa(config.UserID))
1050
1051	return v, nil
1052}
1053
1054// KickChatMemberConfig contains extra fields to kick user
1055type KickChatMemberConfig struct {
1056	ChatMemberConfig
1057	UntilDate int64
1058}
1059
1060func (config KickChatMemberConfig) method() string {
1061	return "kickChatMember"
1062}
1063
1064func (config KickChatMemberConfig) values() (url.Values, error) {
1065	v := url.Values{}
1066
1067	if config.SuperGroupUsername == "" {
1068		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1069	} else {
1070		v.Add("chat_id", config.SuperGroupUsername)
1071	}
1072	v.Add("user_id", strconv.Itoa(config.UserID))
1073
1074	if config.UntilDate != 0 {
1075		v.Add("until_date", strconv.FormatInt(config.UntilDate, 10))
1076	}
1077
1078	return v, nil
1079}
1080
1081// RestrictChatMemberConfig contains fields to restrict members of chat
1082type RestrictChatMemberConfig struct {
1083	ChatMemberConfig
1084	UntilDate             int64
1085	CanSendMessages       *bool
1086	CanSendMediaMessages  *bool
1087	CanSendOtherMessages  *bool
1088	CanAddWebPagePreviews *bool
1089}
1090
1091func (config RestrictChatMemberConfig) method() string {
1092	return "restrictChatMember"
1093}
1094
1095func (config RestrictChatMemberConfig) values() (url.Values, error) {
1096	v := url.Values{}
1097
1098	if config.SuperGroupUsername != "" {
1099		v.Add("chat_id", config.SuperGroupUsername)
1100	} else if config.ChannelUsername != "" {
1101		v.Add("chat_id", config.ChannelUsername)
1102	} else {
1103		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1104	}
1105	v.Add("user_id", strconv.Itoa(config.UserID))
1106
1107	if config.CanSendMessages != nil {
1108		v.Add("can_send_messages", strconv.FormatBool(*config.CanSendMessages))
1109	}
1110	if config.CanSendMediaMessages != nil {
1111		v.Add("can_send_media_messages", strconv.FormatBool(*config.CanSendMediaMessages))
1112	}
1113	if config.CanSendOtherMessages != nil {
1114		v.Add("can_send_other_messages", strconv.FormatBool(*config.CanSendOtherMessages))
1115	}
1116	if config.CanAddWebPagePreviews != nil {
1117		v.Add("can_add_web_page_previews", strconv.FormatBool(*config.CanAddWebPagePreviews))
1118	}
1119	if config.UntilDate != 0 {
1120		v.Add("until_date", strconv.FormatInt(config.UntilDate, 10))
1121	}
1122
1123	return v, nil
1124}
1125
1126// PromoteChatMemberConfig contains fields to promote members of chat
1127type PromoteChatMemberConfig struct {
1128	ChatMemberConfig
1129	CanChangeInfo      *bool
1130	CanPostMessages    *bool
1131	CanEditMessages    *bool
1132	CanDeleteMessages  *bool
1133	CanInviteUsers     *bool
1134	CanRestrictMembers *bool
1135	CanPinMessages     *bool
1136	CanPromoteMembers  *bool
1137}
1138
1139func (config PromoteChatMemberConfig) method() string {
1140	return "promoteChatMember"
1141}
1142
1143func (config PromoteChatMemberConfig) values() (url.Values, error) {
1144	v := url.Values{}
1145
1146	if config.SuperGroupUsername != "" {
1147		v.Add("chat_id", config.SuperGroupUsername)
1148	} else if config.ChannelUsername != "" {
1149		v.Add("chat_id", config.ChannelUsername)
1150	} else {
1151		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1152	}
1153	v.Add("user_id", strconv.Itoa(config.UserID))
1154
1155	if config.CanChangeInfo != nil {
1156		v.Add("can_change_info", strconv.FormatBool(*config.CanChangeInfo))
1157	}
1158	if config.CanPostMessages != nil {
1159		v.Add("can_post_messages", strconv.FormatBool(*config.CanPostMessages))
1160	}
1161	if config.CanEditMessages != nil {
1162		v.Add("can_edit_messages", strconv.FormatBool(*config.CanEditMessages))
1163	}
1164	if config.CanDeleteMessages != nil {
1165		v.Add("can_delete_messages", strconv.FormatBool(*config.CanDeleteMessages))
1166	}
1167	if config.CanInviteUsers != nil {
1168		v.Add("can_invite_users", strconv.FormatBool(*config.CanInviteUsers))
1169	}
1170	if config.CanRestrictMembers != nil {
1171		v.Add("can_restrict_members", strconv.FormatBool(*config.CanRestrictMembers))
1172	}
1173	if config.CanPinMessages != nil {
1174		v.Add("can_pin_messages", strconv.FormatBool(*config.CanPinMessages))
1175	}
1176	if config.CanPromoteMembers != nil {
1177		v.Add("can_promote_members", strconv.FormatBool(*config.CanPromoteMembers))
1178	}
1179
1180	return v, nil
1181}
1182
1183// ChatConfig contains information about getting information on a chat.
1184type ChatConfig struct {
1185	ChatID             int64
1186	SuperGroupUsername string
1187}
1188
1189// LeaveChatConfig allows you to leave a chat.
1190type LeaveChatConfig struct {
1191	ChatID          int64
1192	ChannelUsername string
1193}
1194
1195func (config LeaveChatConfig) method() string {
1196	return "leaveChat"
1197}
1198
1199func (config LeaveChatConfig) values() (url.Values, error) {
1200	v := url.Values{}
1201
1202	if config.ChannelUsername == "" {
1203		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1204	} else {
1205		v.Add("chat_id", config.ChannelUsername)
1206	}
1207
1208	return v, nil
1209}
1210
1211// ChatConfigWithUser contains information about getting information on
1212// a specific user within a chat.
1213type ChatConfigWithUser struct {
1214	ChatID             int64
1215	SuperGroupUsername string
1216	UserID             int
1217}
1218
1219// InvoiceConfig contains information for sendInvoice request.
1220type InvoiceConfig struct {
1221	BaseChat
1222	Title               string          // required
1223	Description         string          // required
1224	Payload             string          // required
1225	ProviderToken       string          // required
1226	StartParameter      string          // required
1227	Currency            string          // required
1228	Prices              *[]LabeledPrice // required
1229	ProviderData        string
1230	PhotoURL            string
1231	PhotoSize           int
1232	PhotoWidth          int
1233	PhotoHeight         int
1234	NeedName            bool
1235	NeedPhoneNumber     bool
1236	NeedEmail           bool
1237	NeedShippingAddress bool
1238	IsFlexible          bool
1239}
1240
1241func (config InvoiceConfig) values() (url.Values, error) {
1242	v, err := config.BaseChat.values()
1243	if err != nil {
1244		return v, err
1245	}
1246	v.Add("title", config.Title)
1247	v.Add("description", config.Description)
1248	v.Add("payload", config.Payload)
1249	v.Add("provider_token", config.ProviderToken)
1250	v.Add("start_parameter", config.StartParameter)
1251	v.Add("currency", config.Currency)
1252	data, err := json.Marshal(config.Prices)
1253	if err != nil {
1254		return v, err
1255	}
1256	v.Add("prices", string(data))
1257	if config.ProviderData != "" {
1258		v.Add("provider_data", config.ProviderData)
1259	}
1260	if config.PhotoURL != "" {
1261		v.Add("photo_url", config.PhotoURL)
1262	}
1263	if config.PhotoSize != 0 {
1264		v.Add("photo_size", strconv.Itoa(config.PhotoSize))
1265	}
1266	if config.PhotoWidth != 0 {
1267		v.Add("photo_width", strconv.Itoa(config.PhotoWidth))
1268	}
1269	if config.PhotoHeight != 0 {
1270		v.Add("photo_height", strconv.Itoa(config.PhotoHeight))
1271	}
1272	if config.NeedName != false {
1273		v.Add("need_name", strconv.FormatBool(config.NeedName))
1274	}
1275	if config.NeedPhoneNumber != false {
1276		v.Add("need_phone_number", strconv.FormatBool(config.NeedPhoneNumber))
1277	}
1278	if config.NeedEmail != false {
1279		v.Add("need_email", strconv.FormatBool(config.NeedEmail))
1280	}
1281	if config.NeedShippingAddress != false {
1282		v.Add("need_shipping_address", strconv.FormatBool(config.NeedShippingAddress))
1283	}
1284	if config.IsFlexible != false {
1285		v.Add("is_flexible", strconv.FormatBool(config.IsFlexible))
1286	}
1287
1288	return v, nil
1289}
1290
1291func (config InvoiceConfig) method() string {
1292	return "sendInvoice"
1293}
1294
1295// ShippingConfig contains information for answerShippingQuery request.
1296type ShippingConfig struct {
1297	ShippingQueryID string // required
1298	OK              bool   // required
1299	ShippingOptions *[]ShippingOption
1300	ErrorMessage    string
1301}
1302
1303// PreCheckoutConfig conatins information for answerPreCheckoutQuery request.
1304type PreCheckoutConfig struct {
1305	PreCheckoutQueryID string // required
1306	OK                 bool   // required
1307	ErrorMessage       string
1308}
1309
1310// DeleteMessageConfig contains information of a message in a chat to delete.
1311type DeleteMessageConfig struct {
1312	ChatID    int64
1313	MessageID int
1314}
1315
1316func (config DeleteMessageConfig) method() string {
1317	return "deleteMessage"
1318}
1319
1320func (config DeleteMessageConfig) values() (url.Values, error) {
1321	v := url.Values{}
1322
1323	v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1324	v.Add("message_id", strconv.Itoa(config.MessageID))
1325
1326	return v, nil
1327}
1328
1329// PinChatMessageConfig contains information of a message in a chat to pin.
1330type PinChatMessageConfig struct {
1331	ChatID              int64
1332	ChannelUsername     string
1333	MessageID           int
1334	DisableNotification bool
1335}
1336
1337func (config PinChatMessageConfig) method() string {
1338	return "pinChatMessage"
1339}
1340
1341func (config PinChatMessageConfig) values() (url.Values, error) {
1342	v := url.Values{}
1343
1344	if config.ChannelUsername == "" {
1345		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1346	} else {
1347		v.Add("chat_id", config.ChannelUsername)
1348	}
1349	v.Add("message_id", strconv.Itoa(config.MessageID))
1350	v.Add("disable_notification", strconv.FormatBool(config.DisableNotification))
1351
1352	return v, nil
1353}
1354
1355// UnpinChatMessageConfig contains information of chat to unpin.
1356type UnpinChatMessageConfig struct {
1357	ChatID          int64
1358	ChannelUsername string
1359}
1360
1361func (config UnpinChatMessageConfig) method() string {
1362	return "unpinChatMessage"
1363}
1364
1365func (config UnpinChatMessageConfig) values() (url.Values, error) {
1366	v := url.Values{}
1367
1368	if config.ChannelUsername == "" {
1369		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1370	} else {
1371		v.Add("chat_id", config.ChannelUsername)
1372	}
1373
1374	return v, nil
1375}
1376
1377// SetChatPhotoConfig allows you to set a group, supergroup, or channel's photo.
1378type SetChatPhotoConfig struct {
1379	BaseFile
1380}
1381
1382func (config SetChatPhotoConfig) method() string {
1383	return "setChatPhoto"
1384}
1385
1386func (config SetChatPhotoConfig) name() string {
1387	return "photo"
1388}
1389
1390func (config SetChatPhotoConfig) getFile() interface{} {
1391	return config.File
1392}
1393
1394func (config SetChatPhotoConfig) useExistingFile() bool {
1395	return config.UseExisting
1396}
1397
1398// DeleteChatPhotoConfig allows you to delete a group, supergroup, or channel's photo.
1399type DeleteChatPhotoConfig struct {
1400	ChatID          int64
1401	ChannelUsername string
1402}
1403
1404func (config DeleteChatPhotoConfig) method() string {
1405	return "deleteChatPhoto"
1406}
1407
1408func (config DeleteChatPhotoConfig) values() (url.Values, error) {
1409	v := url.Values{}
1410
1411	if config.ChannelUsername == "" {
1412		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1413	} else {
1414		v.Add("chat_id", config.ChannelUsername)
1415	}
1416
1417	return v, nil
1418}
1419
1420// SetChatTitleConfig allows you to set the title of something other than a private chat.
1421type SetChatTitleConfig struct {
1422	ChatID          int64
1423	ChannelUsername string
1424
1425	Title string
1426}
1427
1428func (config SetChatTitleConfig) method() string {
1429	return "setChatTitle"
1430}
1431
1432func (config SetChatTitleConfig) values() (url.Values, error) {
1433	v := url.Values{}
1434
1435	if config.ChannelUsername == "" {
1436		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1437	} else {
1438		v.Add("chat_id", config.ChannelUsername)
1439	}
1440
1441	v.Add("title", config.Title)
1442
1443	return v, nil
1444}
1445
1446// SetChatDescriptionConfig allows you to set the description of a supergroup or channel.
1447type SetChatDescriptionConfig struct {
1448	ChatID          int64
1449	ChannelUsername string
1450
1451	Description string
1452}
1453
1454func (config SetChatDescriptionConfig) method() string {
1455	return "setChatDescription"
1456}
1457
1458func (config SetChatDescriptionConfig) values() (url.Values, error) {
1459	v := url.Values{}
1460
1461	if config.ChannelUsername == "" {
1462		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1463	} else {
1464		v.Add("chat_id", config.ChannelUsername)
1465	}
1466
1467	v.Add("description", config.Description)
1468
1469	return v, nil
1470}
1471
1472// GetStickerSetConfig allows you to get the stickers in a set.
1473type GetStickerSetConfig struct {
1474	Name string
1475}
1476
1477func (config GetStickerSetConfig) method() string {
1478	return "getStickerSet"
1479}
1480
1481func (config GetStickerSetConfig) values() (url.Values, error) {
1482	v := url.Values{}
1483
1484	v.Add("name", config.Name)
1485
1486	return v, nil
1487}
1488
1489// UploadStickerConfig allows you to upload a sticker for use in a set later.
1490type UploadStickerConfig struct {
1491	UserID     int64
1492	PNGSticker interface{}
1493}
1494
1495func (config UploadStickerConfig) method() string {
1496	return "uploadStickerFile"
1497}
1498
1499func (config UploadStickerConfig) values() (url.Values, error) {
1500	v := url.Values{}
1501
1502	v.Add("user_id", strconv.FormatInt(config.UserID, 10))
1503
1504	return v, nil
1505}
1506
1507func (config UploadStickerConfig) params() (map[string]string, error) {
1508	params := make(map[string]string)
1509
1510	params["user_id"] = strconv.FormatInt(config.UserID, 10)
1511
1512	return params, nil
1513}
1514
1515func (config UploadStickerConfig) name() string {
1516	return "png_sticker"
1517}
1518
1519func (config UploadStickerConfig) getFile() interface{} {
1520	return config.PNGSticker
1521}
1522
1523func (config UploadStickerConfig) useExistingFile() bool {
1524	return false
1525}
1526
1527// NewStickerSetConfig allows creating a new sticker set.
1528type NewStickerSetConfig struct {
1529	UserID        int64
1530	Name          string
1531	Title         string
1532	PNGSticker    interface{}
1533	Emojis        string
1534	ContainsMasks bool
1535	MaskPosition  *MaskPosition
1536}
1537
1538func (config NewStickerSetConfig) method() string {
1539	return "createNewStickerSet"
1540}
1541
1542func (config NewStickerSetConfig) values() (url.Values, error) {
1543	v := url.Values{}
1544
1545	v.Add("user_id", strconv.FormatInt(config.UserID, 10))
1546	v.Add("name", config.Name)
1547	v.Add("title", config.Title)
1548	if sticker, ok := config.PNGSticker.(string); ok {
1549		v.Add("png_sticker", sticker)
1550	}
1551	v.Add("emojis", config.Emojis)
1552	if config.ContainsMasks {
1553		v.Add("contains_masks", strconv.FormatBool(config.ContainsMasks))
1554
1555		data, err := json.Marshal(config.MaskPosition)
1556		if err != nil {
1557			return v, err
1558		}
1559
1560		v.Add("mask_position", string(data))
1561	}
1562
1563	return v, nil
1564}
1565
1566func (config NewStickerSetConfig) params() (map[string]string, error) {
1567	params := make(map[string]string)
1568
1569	params["user_id"] = strconv.FormatInt(config.UserID, 10)
1570	params["name"] = config.Name
1571	params["title"] = config.Title
1572	params["emojis"] = config.Emojis
1573	if config.ContainsMasks {
1574		params["contains_masks"] = strconv.FormatBool(config.ContainsMasks)
1575
1576		data, err := json.Marshal(config.MaskPosition)
1577		if err != nil {
1578			return params, err
1579		}
1580
1581		params["mask_position"] = string(data)
1582	}
1583
1584	return params, nil
1585}
1586
1587func (config NewStickerSetConfig) getFile() interface{} {
1588	return config.PNGSticker
1589}
1590
1591func (config NewStickerSetConfig) name() string {
1592	return "png_sticker"
1593}
1594
1595func (config NewStickerSetConfig) useExistingFile() bool {
1596	_, ok := config.PNGSticker.(string)
1597
1598	return ok
1599}
1600
1601// AddStickerConfig allows you to add a sticker to a set.
1602type AddStickerConfig struct {
1603	UserID       int64
1604	Name         string
1605	PNGSticker   interface{}
1606	Emojis       string
1607	MaskPosition *MaskPosition
1608}
1609
1610func (config AddStickerConfig) method() string {
1611	return "addStickerToSet"
1612}
1613
1614func (config AddStickerConfig) values() (url.Values, error) {
1615	v := url.Values{}
1616
1617	v.Add("user_id", strconv.FormatInt(config.UserID, 10))
1618	v.Add("name", config.Name)
1619	if sticker, ok := config.PNGSticker.(string); ok {
1620		v.Add("png_sticker", sticker)
1621	}
1622	v.Add("emojis", config.Emojis)
1623	if config.MaskPosition != nil {
1624		data, err := json.Marshal(config.MaskPosition)
1625		if err != nil {
1626			return v, err
1627		}
1628
1629		v.Add("mask_position", string(data))
1630	}
1631
1632	return v, nil
1633}
1634
1635func (config AddStickerConfig) params() (map[string]string, error) {
1636	params := make(map[string]string)
1637
1638	params["user_id"] = strconv.FormatInt(config.UserID, 10)
1639	params["name"] = config.Name
1640	params["emojis"] = config.Emojis
1641	if config.MaskPosition != nil {
1642		data, err := json.Marshal(config.MaskPosition)
1643		if err != nil {
1644			return params, err
1645		}
1646
1647		params["mask_position"] = string(data)
1648	}
1649
1650	return params, nil
1651}
1652
1653func (config AddStickerConfig) name() string {
1654	return "png_sticker"
1655}
1656
1657func (config AddStickerConfig) getFile() interface{} {
1658	return config.PNGSticker
1659}
1660
1661func (config AddStickerConfig) useExistingFile() bool {
1662	return false
1663}
1664
1665// SetStickerPositionConfig allows you to change the position of a sticker in a set.
1666type SetStickerPositionConfig struct {
1667	Sticker  string
1668	Position int
1669}
1670
1671func (config SetStickerPositionConfig) method() string {
1672	return "setStickerPositionInSet"
1673}
1674
1675func (config SetStickerPositionConfig) values() (url.Values, error) {
1676	v := url.Values{}
1677
1678	v.Add("sticker", config.Sticker)
1679	v.Add("position", strconv.Itoa(config.Position))
1680
1681	return v, nil
1682}
1683
1684// DeleteStickerConfig allows you to delete a sticker from a set.
1685type DeleteStickerConfig struct {
1686	Sticker string
1687}
1688
1689func (config DeleteStickerConfig) method() string {
1690	return "deleteStickerFromSet"
1691}
1692
1693func (config DeleteStickerConfig) values() (url.Values, error) {
1694	v := url.Values{}
1695
1696	v.Add("sticker", config.Sticker)
1697
1698	return v, nil
1699}
1700
1701// SetChatStickerSetConfig allows you to set the sticker set for a supergroup.
1702type SetChatStickerSetConfig struct {
1703	ChatID             int64
1704	SuperGroupUsername string
1705
1706	StickerSetName string
1707}
1708
1709func (config SetChatStickerSetConfig) method() string {
1710	return "setChatStickerSet"
1711}
1712
1713func (config SetChatStickerSetConfig) values() (url.Values, error) {
1714	v := url.Values{}
1715
1716	if config.SuperGroupUsername == "" {
1717		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1718	} else {
1719		v.Add("chat_id", config.SuperGroupUsername)
1720	}
1721
1722	v.Add("sticker_set_name", config.StickerSetName)
1723
1724	return v, nil
1725}
1726
1727// DeleteChatStickerSetConfig allows you to remove a supergroup's sticker set.
1728type DeleteChatStickerSetConfig struct {
1729	ChatID             int64
1730	SuperGroupUsername string
1731}
1732
1733func (config DeleteChatStickerSetConfig) method() string {
1734	return "deleteChatStickerSet"
1735}
1736
1737func (config DeleteChatStickerSetConfig) values() (url.Values, error) {
1738	v := url.Values{}
1739
1740	if config.SuperGroupUsername == "" {
1741		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1742	} else {
1743		v.Add("chat_id", config.SuperGroupUsername)
1744	}
1745
1746	return v, nil
1747}
1748
1749// MediaGroupConfig allows you to send a group of media.
1750//
1751// Media consist of InputMedia items (InputMediaPhoto, InputMediaVideo).
1752type MediaGroupConfig struct {
1753	ChatID          int64
1754	ChannelUsername string
1755
1756	Media               []interface{}
1757	DisableNotification bool
1758	ReplyToMessageID    int
1759}
1760
1761func (config MediaGroupConfig) method() string {
1762	return "sendMediaGroup"
1763}
1764
1765func (config MediaGroupConfig) values() (url.Values, error) {
1766	v := url.Values{}
1767
1768	if config.ChannelUsername == "" {
1769		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1770	} else {
1771		v.Add("chat_id", config.ChannelUsername)
1772	}
1773	bytes, err := json.Marshal(config.Media)
1774	if err != nil {
1775		return v, err
1776	}
1777	v.Add("media", string(bytes))
1778	if config.DisableNotification {
1779		v.Add("disable_notification", strconv.FormatBool(config.DisableNotification))
1780	}
1781	if config.ReplyToMessageID != 0 {
1782		v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageID))
1783	}
1784
1785	return v, nil
1786}