all repos — telegram-bot-api @ 9653a4aad4bed727a828034c0ed5c371aada90af

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             int
 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.Itoa(config.ChatID))
 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	ChatID          int64
1380	ChannelUsername string
1381
1382	Photo interface{}
1383}
1384
1385func (config SetChatPhotoConfig) method() string {
1386	return "setChatPhoto"
1387}
1388
1389func (config SetChatPhotoConfig) name() string {
1390	return "photo"
1391}
1392
1393func (config SetChatPhotoConfig) values() (url.Values, error) {
1394	v := url.Values{}
1395
1396	if config.ChannelUsername == "" {
1397		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1398	} else {
1399		v.Add("chat_id", config.ChannelUsername)
1400	}
1401
1402	return v, nil
1403}
1404
1405func (config SetChatPhotoConfig) params() map[string]string {
1406	params := make(map[string]string)
1407
1408	if config.ChannelUsername == "" {
1409		params["chat_id"] = strconv.FormatInt(config.ChatID, 10)
1410	} else {
1411		params["chat_id"] = config.ChannelUsername
1412	}
1413
1414	return params
1415}
1416
1417func (config SetChatPhotoConfig) getFile() interface{} {
1418	return config.Photo
1419}
1420
1421func (config SetChatPhotoConfig) useExistingFile() bool {
1422	return false
1423}
1424
1425// DeleteChatPhotoConfig allows you to delete a group, supergroup, or channel's photo.
1426type DeleteChatPhotoConfig struct {
1427	ChatID          int64
1428	ChannelUsername string
1429}
1430
1431func (config DeleteChatPhotoConfig) method() string {
1432	return "deleteChatPhoto"
1433}
1434
1435func (config DeleteChatPhotoConfig) values() (url.Values, error) {
1436	v := url.Values{}
1437
1438	if config.ChannelUsername == "" {
1439		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1440	} else {
1441		v.Add("chat_id", config.ChannelUsername)
1442	}
1443
1444	return v, nil
1445}
1446
1447// SetChatTitleConfig allows you to set the title of something other than a private chat.
1448type SetChatTitleConfig struct {
1449	ChatID          int64
1450	ChannelUsername string
1451
1452	Title string
1453}
1454
1455func (config SetChatTitleConfig) method() string {
1456	return "setChatTitle"
1457}
1458
1459func (config SetChatTitleConfig) values() (url.Values, error) {
1460	v := url.Values{}
1461
1462	if config.ChannelUsername == "" {
1463		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1464	} else {
1465		v.Add("chat_id", config.ChannelUsername)
1466	}
1467
1468	v.Add("title", config.Title)
1469
1470	return v, nil
1471}
1472
1473// SetChatDescriptionConfig allows you to set the description of a supergroup or channel.
1474type SetChatDescriptionConfig struct {
1475	ChatID          int64
1476	ChannelUsername string
1477
1478	Description string
1479}
1480
1481func (config SetChatDescriptionConfig) method() string {
1482	return "setChatDescription"
1483}
1484
1485func (config SetChatDescriptionConfig) values() (url.Values, error) {
1486	v := url.Values{}
1487
1488	if config.ChannelUsername == "" {
1489		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1490	} else {
1491		v.Add("chat_id", config.ChannelUsername)
1492	}
1493
1494	v.Add("description", config.Description)
1495
1496	return v, nil
1497}
1498
1499// GetStickerSetConfig allows you to get the stickers in a set.
1500type GetStickerSetConfig struct {
1501	Name string
1502}
1503
1504func (config GetStickerSetConfig) method() string {
1505	return "getStickerSet"
1506}
1507
1508func (config GetStickerSetConfig) values() (url.Values, error) {
1509	v := url.Values{}
1510
1511	v.Add("name", config.Name)
1512
1513	return v, nil
1514}
1515
1516// UploadStickerConfig allows you to upload a sticker for use in a set later.
1517type UploadStickerConfig struct {
1518	UserID     int64
1519	PNGSticker interface{}
1520}
1521
1522func (config UploadStickerConfig) method() string {
1523	return "uploadStickerFile"
1524}
1525
1526func (config UploadStickerConfig) values() (url.Values, error) {
1527	v := url.Values{}
1528
1529	v.Add("user_id", strconv.FormatInt(config.UserID, 10))
1530
1531	return v, nil
1532}
1533
1534func (config UploadStickerConfig) params() (map[string]string, error) {
1535	params := make(map[string]string)
1536
1537	params["user_id"] = strconv.FormatInt(config.UserID, 10)
1538
1539	return params, nil
1540}
1541
1542func (config UploadStickerConfig) name() string {
1543	return "png_sticker"
1544}
1545
1546func (config UploadStickerConfig) getFile() interface{} {
1547	return config.PNGSticker
1548}
1549
1550func (config UploadStickerConfig) useExistingFile() bool {
1551	return false
1552}
1553
1554// NewStickerSetConfig allows creating a new sticker set.
1555type NewStickerSetConfig struct {
1556	UserID        int64
1557	Name          string
1558	Title         string
1559	PNGSticker    interface{}
1560	Emojis        string
1561	ContainsMasks bool
1562	MaskPosition  *MaskPosition
1563}
1564
1565func (config NewStickerSetConfig) method() string {
1566	return "createNewStickerSet"
1567}
1568
1569func (config NewStickerSetConfig) values() (url.Values, error) {
1570	v := url.Values{}
1571
1572	v.Add("user_id", strconv.FormatInt(config.UserID, 10))
1573	v.Add("name", config.Name)
1574	v.Add("title", config.Title)
1575	if sticker, ok := config.PNGSticker.(string); ok {
1576		v.Add("png_sticker", sticker)
1577	}
1578	v.Add("emojis", config.Emojis)
1579	if config.ContainsMasks {
1580		v.Add("contains_masks", strconv.FormatBool(config.ContainsMasks))
1581
1582		data, err := json.Marshal(config.MaskPosition)
1583		if err != nil {
1584			return v, err
1585		}
1586
1587		v.Add("mask_position", string(data))
1588	}
1589
1590	return v, nil
1591}
1592
1593func (config NewStickerSetConfig) params() (map[string]string, error) {
1594	params := make(map[string]string)
1595
1596	params["user_id"] = strconv.FormatInt(config.UserID, 10)
1597	params["name"] = config.Name
1598	params["title"] = config.Title
1599	params["emojis"] = config.Emojis
1600	if config.ContainsMasks {
1601		params["contains_masks"] = strconv.FormatBool(config.ContainsMasks)
1602
1603		data, err := json.Marshal(config.MaskPosition)
1604		if err != nil {
1605			return params, err
1606		}
1607
1608		params["mask_position"] = string(data)
1609	}
1610
1611	return params, nil
1612}
1613
1614func (config NewStickerSetConfig) getFile() interface{} {
1615	return config.PNGSticker
1616}
1617
1618func (config NewStickerSetConfig) name() string {
1619	return "png_sticker"
1620}
1621
1622func (config NewStickerSetConfig) useExistingFile() bool {
1623	_, ok := config.PNGSticker.(string)
1624
1625	return ok
1626}
1627
1628// AddStickerConfig allows you to add a sticker to a set.
1629type AddStickerConfig struct {
1630	UserID       int64
1631	Name         string
1632	PNGSticker   interface{}
1633	Emojis       string
1634	MaskPosition *MaskPosition
1635}
1636
1637func (config AddStickerConfig) method() string {
1638	return "addStickerToSet"
1639}
1640
1641func (config AddStickerConfig) values() (url.Values, error) {
1642	v := url.Values{}
1643
1644	v.Add("user_id", strconv.FormatInt(config.UserID, 10))
1645	v.Add("name", config.Name)
1646	if sticker, ok := config.PNGSticker.(string); ok {
1647		v.Add("png_sticker", sticker)
1648	}
1649	v.Add("emojis", config.Emojis)
1650	if config.MaskPosition != nil {
1651		data, err := json.Marshal(config.MaskPosition)
1652		if err != nil {
1653			return v, err
1654		}
1655
1656		v.Add("mask_position", string(data))
1657	}
1658
1659	return v, nil
1660}
1661
1662func (config AddStickerConfig) params() (map[string]string, error) {
1663	params := make(map[string]string)
1664
1665	params["user_id"] = strconv.FormatInt(config.UserID, 10)
1666	params["name"] = config.Name
1667	params["emojis"] = config.Emojis
1668	if config.MaskPosition != nil {
1669		data, err := json.Marshal(config.MaskPosition)
1670		if err != nil {
1671			return params, err
1672		}
1673
1674		params["mask_position"] = string(data)
1675	}
1676
1677	return params, nil
1678}
1679
1680func (config AddStickerConfig) name() string {
1681	return "png_sticker"
1682}
1683
1684func (config AddStickerConfig) getFile() interface{} {
1685	return config.PNGSticker
1686}
1687
1688func (config AddStickerConfig) useExistingFile() bool {
1689	return false
1690}
1691
1692// SetStickerPositionConfig allows you to change the position of a sticker in a set.
1693type SetStickerPositionConfig struct {
1694	Sticker  string
1695	Position int
1696}
1697
1698func (config SetStickerPositionConfig) method() string {
1699	return "setStickerPositionInSet"
1700}
1701
1702func (config SetStickerPositionConfig) values() (url.Values, error) {
1703	v := url.Values{}
1704
1705	v.Add("sticker", config.Sticker)
1706	v.Add("position", strconv.Itoa(config.Position))
1707
1708	return v, nil
1709}
1710
1711// DeleteStickerConfig allows you to delete a sticker from a set.
1712type DeleteStickerConfig struct {
1713	Sticker string
1714}
1715
1716func (config DeleteStickerConfig) method() string {
1717	return "deleteStickerFromSet"
1718}
1719
1720func (config DeleteStickerConfig) values() (url.Values, error) {
1721	v := url.Values{}
1722
1723	v.Add("sticker", config.Sticker)
1724
1725	return v, nil
1726}
1727
1728// SetChatStickerSetConfig allows you to set the sticker set for a supergroup.
1729type SetChatStickerSetConfig struct {
1730	ChatID             int64
1731	SuperGroupUsername string
1732
1733	StickerSetName string
1734}
1735
1736func (config SetChatStickerSetConfig) method() string {
1737	return "setChatStickerSet"
1738}
1739
1740func (config SetChatStickerSetConfig) values() (url.Values, error) {
1741	v := url.Values{}
1742
1743	if config.SuperGroupUsername == "" {
1744		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1745	} else {
1746		v.Add("chat_id", config.SuperGroupUsername)
1747	}
1748
1749	v.Add("sticker_set_name", config.StickerSetName)
1750
1751	return v, nil
1752}
1753
1754// DeleteChatStickerSetConfig allows you to remove a supergroup's sticker set.
1755type DeleteChatStickerSetConfig struct {
1756	ChatID             int64
1757	SuperGroupUsername string
1758}
1759
1760func (config DeleteChatStickerSetConfig) method() string {
1761	return "deleteChatStickerSet"
1762}
1763
1764func (config DeleteChatStickerSetConfig) values() (url.Values, error) {
1765	v := url.Values{}
1766
1767	if config.SuperGroupUsername == "" {
1768		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1769	} else {
1770		v.Add("chat_id", config.SuperGroupUsername)
1771	}
1772
1773	return v, nil
1774}
1775
1776// MediaGroupConfig allows you to send a group of media.
1777//
1778// Media consist of InputMedia items (InputMediaPhoto, InputMediaVideo).
1779type MediaGroupConfig struct {
1780	ChatID          int64
1781	ChannelUsername string
1782
1783	Media               []interface{}
1784	DisableNotification bool
1785	ReplyToMessageID    int
1786}
1787
1788func (config MediaGroupConfig) method() string {
1789	return "sendMediaGroup"
1790}
1791
1792func (config MediaGroupConfig) values() (url.Values, error) {
1793	v := url.Values{}
1794
1795	if config.ChannelUsername == "" {
1796		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1797	} else {
1798		v.Add("chat_id", config.ChannelUsername)
1799	}
1800	bytes, err := json.Marshal(config.Media)
1801	if err != nil {
1802		return v, err
1803	}
1804	v.Add("media", string(bytes))
1805	if config.DisableNotification {
1806		v.Add("disable_notification", strconv.FormatBool(config.DisableNotification))
1807	}
1808	if config.ReplyToMessageID != 0 {
1809		v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageID))
1810	}
1811
1812	return v, nil
1813}