all repos — telegram-bot-api @ 0343f9ec270a847ed4d276e3ba2ce88e7b1282b9

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}
 666
 667// values returns a url.Values representation of LocationConfig.
 668func (config LocationConfig) values() (url.Values, error) {
 669	v, err := config.BaseChat.values()
 670	if err != nil {
 671		return v, err
 672	}
 673
 674	v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
 675	v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
 676
 677	return v, nil
 678}
 679
 680// method returns Telegram API method name for sending Location.
 681func (config LocationConfig) method() string {
 682	return "sendLocation"
 683}
 684
 685// VenueConfig contains information about a SendVenue request.
 686type VenueConfig struct {
 687	BaseChat
 688	Latitude     float64 // required
 689	Longitude    float64 // required
 690	Title        string  // required
 691	Address      string  // required
 692	FoursquareID string
 693}
 694
 695func (config VenueConfig) values() (url.Values, error) {
 696	v, err := config.BaseChat.values()
 697	if err != nil {
 698		return v, err
 699	}
 700
 701	v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
 702	v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
 703	v.Add("title", config.Title)
 704	v.Add("address", config.Address)
 705	if config.FoursquareID != "" {
 706		v.Add("foursquare_id", config.FoursquareID)
 707	}
 708
 709	return v, nil
 710}
 711
 712func (config VenueConfig) method() string {
 713	return "sendVenue"
 714}
 715
 716// ContactConfig allows you to send a contact.
 717type ContactConfig struct {
 718	BaseChat
 719	PhoneNumber string
 720	FirstName   string
 721	LastName    string
 722}
 723
 724func (config ContactConfig) values() (url.Values, error) {
 725	v, err := config.BaseChat.values()
 726	if err != nil {
 727		return v, err
 728	}
 729
 730	v.Add("phone_number", config.PhoneNumber)
 731	v.Add("first_name", config.FirstName)
 732	v.Add("last_name", config.LastName)
 733
 734	return v, nil
 735}
 736
 737func (config ContactConfig) method() string {
 738	return "sendContact"
 739}
 740
 741// GameConfig allows you to send a game.
 742type GameConfig struct {
 743	BaseChat
 744	GameShortName string
 745}
 746
 747func (config GameConfig) values() (url.Values, error) {
 748	v, err := config.BaseChat.values()
 749	if err != nil {
 750		return v, err
 751	}
 752
 753	v.Add("game_short_name", config.GameShortName)
 754
 755	return v, nil
 756}
 757
 758func (config GameConfig) method() string {
 759	return "sendGame"
 760}
 761
 762// SetGameScoreConfig allows you to update the game score in a chat.
 763type SetGameScoreConfig struct {
 764	UserID             int
 765	Score              int
 766	Force              bool
 767	DisableEditMessage bool
 768	ChatID             int64
 769	ChannelUsername    string
 770	MessageID          int
 771	InlineMessageID    string
 772}
 773
 774func (config SetGameScoreConfig) values() (url.Values, error) {
 775	v := url.Values{}
 776
 777	v.Add("user_id", strconv.Itoa(config.UserID))
 778	v.Add("score", strconv.Itoa(config.Score))
 779	if config.InlineMessageID == "" {
 780		if config.ChannelUsername == "" {
 781			v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
 782		} else {
 783			v.Add("chat_id", config.ChannelUsername)
 784		}
 785		v.Add("message_id", strconv.Itoa(config.MessageID))
 786	} else {
 787		v.Add("inline_message_id", config.InlineMessageID)
 788	}
 789	v.Add("disable_edit_message", strconv.FormatBool(config.DisableEditMessage))
 790
 791	return v, nil
 792}
 793
 794func (config SetGameScoreConfig) method() string {
 795	return "setGameScore"
 796}
 797
 798// GetGameHighScoresConfig allows you to fetch the high scores for a game.
 799type GetGameHighScoresConfig struct {
 800	UserID          int
 801	ChatID          int
 802	ChannelUsername string
 803	MessageID       int
 804	InlineMessageID string
 805}
 806
 807func (config GetGameHighScoresConfig) values() (url.Values, error) {
 808	v := url.Values{}
 809
 810	v.Add("user_id", strconv.Itoa(config.UserID))
 811	if config.InlineMessageID == "" {
 812		if config.ChannelUsername == "" {
 813			v.Add("chat_id", strconv.Itoa(config.ChatID))
 814		} else {
 815			v.Add("chat_id", config.ChannelUsername)
 816		}
 817		v.Add("message_id", strconv.Itoa(config.MessageID))
 818	} else {
 819		v.Add("inline_message_id", config.InlineMessageID)
 820	}
 821
 822	return v, nil
 823}
 824
 825func (config GetGameHighScoresConfig) method() string {
 826	return "getGameHighScores"
 827}
 828
 829// ChatActionConfig contains information about a SendChatAction request.
 830type ChatActionConfig struct {
 831	BaseChat
 832	Action string // required
 833}
 834
 835// values returns a url.Values representation of ChatActionConfig.
 836func (config ChatActionConfig) values() (url.Values, error) {
 837	v, err := config.BaseChat.values()
 838	if err != nil {
 839		return v, err
 840	}
 841	v.Add("action", config.Action)
 842	return v, nil
 843}
 844
 845// method returns Telegram API method name for sending ChatAction.
 846func (config ChatActionConfig) method() string {
 847	return "sendChatAction"
 848}
 849
 850// EditMessageTextConfig allows you to modify the text in a message.
 851type EditMessageTextConfig struct {
 852	BaseEdit
 853	Text                  string
 854	ParseMode             string
 855	DisableWebPagePreview bool
 856}
 857
 858func (config EditMessageTextConfig) values() (url.Values, error) {
 859	v, err := config.BaseEdit.values()
 860	if err != nil {
 861		return v, err
 862	}
 863
 864	v.Add("text", config.Text)
 865	v.Add("parse_mode", config.ParseMode)
 866	v.Add("disable_web_page_preview", strconv.FormatBool(config.DisableWebPagePreview))
 867
 868	return v, nil
 869}
 870
 871func (config EditMessageTextConfig) method() string {
 872	return "editMessageText"
 873}
 874
 875// EditMessageCaptionConfig allows you to modify the caption of a message.
 876type EditMessageCaptionConfig struct {
 877	BaseEdit
 878	Caption   string
 879	ParseMode string
 880}
 881
 882func (config EditMessageCaptionConfig) values() (url.Values, error) {
 883	v, _ := config.BaseEdit.values()
 884
 885	v.Add("caption", config.Caption)
 886	if config.ParseMode != "" {
 887		v.Add("parse_mode", config.ParseMode)
 888	}
 889
 890	return v, nil
 891}
 892
 893func (config EditMessageCaptionConfig) method() string {
 894	return "editMessageCaption"
 895}
 896
 897// EditMessageReplyMarkupConfig allows you to modify the reply markup
 898// of a message.
 899type EditMessageReplyMarkupConfig struct {
 900	BaseEdit
 901}
 902
 903func (config EditMessageReplyMarkupConfig) values() (url.Values, error) {
 904	return config.BaseEdit.values()
 905}
 906
 907func (config EditMessageReplyMarkupConfig) method() string {
 908	return "editMessageReplyMarkup"
 909}
 910
 911// UserProfilePhotosConfig contains information about a
 912// GetUserProfilePhotos request.
 913type UserProfilePhotosConfig struct {
 914	UserID int
 915	Offset int
 916	Limit  int
 917}
 918
 919// FileConfig has information about a file hosted on Telegram.
 920type FileConfig struct {
 921	FileID string
 922}
 923
 924// UpdateConfig contains information about a GetUpdates request.
 925type UpdateConfig struct {
 926	Offset  int
 927	Limit   int
 928	Timeout int
 929}
 930
 931// WebhookConfig contains information about a SetWebhook request.
 932type WebhookConfig struct {
 933	URL            *url.URL
 934	Certificate    interface{}
 935	MaxConnections int
 936}
 937
 938// FileBytes contains information about a set of bytes to upload
 939// as a File.
 940type FileBytes struct {
 941	Name  string
 942	Bytes []byte
 943}
 944
 945// FileReader contains information about a reader to upload as a File.
 946// If Size is -1, it will read the entire Reader into memory to
 947// calculate a Size.
 948type FileReader struct {
 949	Name   string
 950	Reader io.Reader
 951	Size   int64
 952}
 953
 954// InlineConfig contains information on making an InlineQuery response.
 955type InlineConfig struct {
 956	InlineQueryID     string        `json:"inline_query_id"`
 957	Results           []interface{} `json:"results"`
 958	CacheTime         int           `json:"cache_time"`
 959	IsPersonal        bool          `json:"is_personal"`
 960	NextOffset        string        `json:"next_offset"`
 961	SwitchPMText      string        `json:"switch_pm_text"`
 962	SwitchPMParameter string        `json:"switch_pm_parameter"`
 963}
 964
 965// CallbackConfig contains information on making a CallbackQuery response.
 966type CallbackConfig struct {
 967	CallbackQueryID string `json:"callback_query_id"`
 968	Text            string `json:"text"`
 969	ShowAlert       bool   `json:"show_alert"`
 970	URL             string `json:"url"`
 971	CacheTime       int    `json:"cache_time"`
 972}
 973
 974// ChatMemberConfig contains information about a user in a chat for use
 975// with administrative functions such as kicking or unbanning a user.
 976type ChatMemberConfig struct {
 977	ChatID             int64
 978	SuperGroupUsername string
 979	ChannelUsername    string
 980	UserID             int
 981}
 982
 983// KickChatMemberConfig contains extra fields to kick user
 984type KickChatMemberConfig struct {
 985	ChatMemberConfig
 986	UntilDate int64
 987}
 988
 989// RestrictChatMemberConfig contains fields to restrict members of chat
 990type RestrictChatMemberConfig struct {
 991	ChatMemberConfig
 992	UntilDate             int64
 993	CanSendMessages       *bool
 994	CanSendMediaMessages  *bool
 995	CanSendOtherMessages  *bool
 996	CanAddWebPagePreviews *bool
 997}
 998
 999// PromoteChatMemberConfig contains fields to promote members of chat
1000type PromoteChatMemberConfig struct {
1001	ChatMemberConfig
1002	CanChangeInfo      *bool
1003	CanPostMessages    *bool
1004	CanEditMessages    *bool
1005	CanDeleteMessages  *bool
1006	CanInviteUsers     *bool
1007	CanRestrictMembers *bool
1008	CanPinMessages     *bool
1009	CanPromoteMembers  *bool
1010}
1011
1012// ChatConfig contains information about getting information on a chat.
1013type ChatConfig struct {
1014	ChatID             int64
1015	SuperGroupUsername string
1016}
1017
1018// ChatConfigWithUser contains information about getting information on
1019// a specific user within a chat.
1020type ChatConfigWithUser struct {
1021	ChatID             int64
1022	SuperGroupUsername string
1023	UserID             int
1024}
1025
1026// InvoiceConfig contains information for sendInvoice request.
1027type InvoiceConfig struct {
1028	BaseChat
1029	Title               string          // required
1030	Description         string          // required
1031	Payload             string          // required
1032	ProviderToken       string          // required
1033	StartParameter      string          // required
1034	Currency            string          // required
1035	Prices              *[]LabeledPrice // required
1036	PhotoURL            string
1037	PhotoSize           int
1038	PhotoWidth          int
1039	PhotoHeight         int
1040	NeedName            bool
1041	NeedPhoneNumber     bool
1042	NeedEmail           bool
1043	NeedShippingAddress bool
1044	IsFlexible          bool
1045}
1046
1047func (config InvoiceConfig) values() (url.Values, error) {
1048	v, err := config.BaseChat.values()
1049	if err != nil {
1050		return v, err
1051	}
1052	v.Add("title", config.Title)
1053	v.Add("description", config.Description)
1054	v.Add("payload", config.Payload)
1055	v.Add("provider_token", config.ProviderToken)
1056	v.Add("start_parameter", config.StartParameter)
1057	v.Add("currency", config.Currency)
1058	data, err := json.Marshal(config.Prices)
1059	if err != nil {
1060		return v, err
1061	}
1062	v.Add("prices", string(data))
1063	if config.PhotoURL != "" {
1064		v.Add("photo_url", config.PhotoURL)
1065	}
1066	if config.PhotoSize != 0 {
1067		v.Add("photo_size", strconv.Itoa(config.PhotoSize))
1068	}
1069	if config.PhotoWidth != 0 {
1070		v.Add("photo_width", strconv.Itoa(config.PhotoWidth))
1071	}
1072	if config.PhotoHeight != 0 {
1073		v.Add("photo_height", strconv.Itoa(config.PhotoHeight))
1074	}
1075	if config.NeedName != false {
1076		v.Add("need_name", strconv.FormatBool(config.NeedName))
1077	}
1078	if config.NeedPhoneNumber != false {
1079		v.Add("need_phone_number", strconv.FormatBool(config.NeedPhoneNumber))
1080	}
1081	if config.NeedEmail != false {
1082		v.Add("need_email", strconv.FormatBool(config.NeedEmail))
1083	}
1084	if config.NeedShippingAddress != false {
1085		v.Add("need_shipping_address", strconv.FormatBool(config.NeedShippingAddress))
1086	}
1087	if config.IsFlexible != false {
1088		v.Add("is_flexible", strconv.FormatBool(config.IsFlexible))
1089	}
1090
1091	return v, nil
1092}
1093
1094func (config InvoiceConfig) method() string {
1095	return "sendInvoice"
1096}
1097
1098// ShippingConfig contains information for answerShippingQuery request.
1099type ShippingConfig struct {
1100	ShippingQueryID string // required
1101	OK              bool   // required
1102	ShippingOptions *[]ShippingOption
1103	ErrorMessage    string
1104}
1105
1106// PreCheckoutConfig conatins information for answerPreCheckoutQuery request.
1107type PreCheckoutConfig struct {
1108	PreCheckoutQueryID string // required
1109	OK                 bool   // required
1110	ErrorMessage       string
1111}
1112
1113// DeleteMessageConfig contains information of a message in a chat to delete.
1114type DeleteMessageConfig struct {
1115	ChatID    int64
1116	MessageID int
1117}
1118
1119func (config DeleteMessageConfig) method() string {
1120	return "deleteMessage"
1121}
1122
1123func (config DeleteMessageConfig) values() (url.Values, error) {
1124	v := url.Values{}
1125
1126	v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1127	v.Add("message_id", strconv.Itoa(config.MessageID))
1128
1129	return v, nil
1130}
1131
1132// PinChatMessageConfig contains information of a message in a chat to pin.
1133type PinChatMessageConfig struct {
1134	ChatID              int64
1135	MessageID           int
1136	DisableNotification bool
1137}
1138
1139func (config PinChatMessageConfig) method() string {
1140	return "pinChatMessage"
1141}
1142
1143func (config PinChatMessageConfig) values() (url.Values, error) {
1144	v := url.Values{}
1145
1146	v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1147	v.Add("message_id", strconv.Itoa(config.MessageID))
1148	v.Add("disable_notification", strconv.FormatBool(config.DisableNotification))
1149
1150	return v, nil
1151}
1152
1153// UnpinChatMessageConfig contains information of chat to unpin.
1154type UnpinChatMessageConfig struct {
1155	ChatID int64
1156}
1157
1158func (config UnpinChatMessageConfig) method() string {
1159	return "unpinChatMessage"
1160}
1161
1162func (config UnpinChatMessageConfig) values() (url.Values, error) {
1163	v := url.Values{}
1164
1165	v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1166
1167	return v, nil
1168}
1169
1170// SetChatTitleConfig contains information for change chat title.
1171type SetChatTitleConfig struct {
1172	ChatID int64
1173	Title  string
1174}
1175
1176func (config SetChatTitleConfig) method() string {
1177	return "setChatTitle"
1178}
1179
1180func (config SetChatTitleConfig) values() (url.Values, error) {
1181	v := url.Values{}
1182
1183	v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1184	v.Add("title", config.Title)
1185
1186	return v, nil
1187}
1188
1189// SetChatDescriptionConfig contains information for change chat description.
1190type SetChatDescriptionConfig struct {
1191	ChatID      int64
1192	Description string
1193}
1194
1195func (config SetChatDescriptionConfig) method() string {
1196	return "setChatDescription"
1197}
1198
1199func (config SetChatDescriptionConfig) values() (url.Values, error) {
1200	v := url.Values{}
1201
1202	v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1203	v.Add("description", config.Description)
1204
1205	return v, nil
1206}
1207
1208// SetChatPhotoConfig contains information for change chat photo
1209type SetChatPhotoConfig struct {
1210	BaseFile
1211}
1212
1213// name returns the field name for the Photo.
1214func (config SetChatPhotoConfig) name() string {
1215	return "photo"
1216}
1217
1218// method returns Telegram API method name for sending Photo.
1219func (config SetChatPhotoConfig) method() string {
1220	return "setChatPhoto"
1221}
1222
1223// DeleteChatPhotoConfig contains information for delete chat photo.
1224type DeleteChatPhotoConfig struct {
1225	ChatID int64
1226}
1227
1228func (config DeleteChatPhotoConfig) method() string {
1229	return "deleteChatPhoto"
1230}
1231
1232func (config DeleteChatPhotoConfig) values() (url.Values, error) {
1233	v := url.Values{}
1234
1235	v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1236
1237	return v, nil
1238}