all repos — telegram-bot-api @ 23ed97b145bdc331428d0e094fdc973627293a89

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