all repos — telegram-bot-api @ 515002232befb8ad10c86f31de61daa91f81fe29

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	ModeMarkdownV2 = "MarkdownV2"
  41	ModeHTML       = "HTML"
  42)
  43
  44// Library errors
  45const (
  46	// ErrBadFileType happens when you pass an unknown type
  47	ErrBadFileType = "bad file type"
  48	ErrBadURL      = "bad or empty url"
  49)
  50
  51// Chattable is any config type that can be sent.
  52type Chattable interface {
  53	values() (url.Values, error)
  54	method() string
  55}
  56
  57// Fileable is any config type that can be sent that includes a file.
  58type Fileable interface {
  59	Chattable
  60	params() (map[string]string, error)
  61	name() string
  62	getFile() interface{}
  63	useExistingFile() bool
  64}
  65
  66// BaseChat is base type for all chat config types.
  67type BaseChat struct {
  68	ChatID              int64 // required
  69	ChannelUsername     string
  70	ReplyToMessageID    int
  71	ReplyMarkup         interface{}
  72	DisableNotification bool
  73}
  74
  75func (chat *BaseChat) params() (Params, error) {
  76	params := make(Params)
  77
  78	params.AddFirstValid("chat_id", chat.ChatID, chat.ChannelUsername)
  79	params.AddNonZero("reply_to_message_id", chat.ReplyToMessageID)
  80	params.AddBool("disable_notification", chat.DisableNotification)
  81
  82	err := params.AddInterface("reply_markup", chat.ReplyMarkup)
  83
  84	return params, err
  85}
  86
  87// values returns url.Values representation of BaseChat
  88func (chat *BaseChat) values() (url.Values, error) {
  89	v := url.Values{}
  90	if chat.ChannelUsername != "" {
  91		v.Add("chat_id", chat.ChannelUsername)
  92	} else {
  93		v.Add("chat_id", strconv.FormatInt(chat.ChatID, 10))
  94	}
  95
  96	if chat.ReplyToMessageID != 0 {
  97		v.Add("reply_to_message_id", strconv.Itoa(chat.ReplyToMessageID))
  98	}
  99
 100	if chat.ReplyMarkup != nil {
 101		data, err := json.Marshal(chat.ReplyMarkup)
 102		if err != nil {
 103			return v, err
 104		}
 105
 106		v.Add("reply_markup", string(data))
 107	}
 108
 109	v.Add("disable_notification", strconv.FormatBool(chat.DisableNotification))
 110
 111	return v, nil
 112}
 113
 114// BaseFile is a base type for all file config types.
 115type BaseFile struct {
 116	BaseChat
 117	File        interface{}
 118	FileID      string
 119	UseExisting bool
 120	MimeType    string
 121	FileSize    int
 122}
 123
 124// params returns a map[string]string representation of BaseFile.
 125func (file BaseFile) params() (map[string]string, error) {
 126	params := make(map[string]string)
 127
 128	if file.ChannelUsername != "" {
 129		params["chat_id"] = file.ChannelUsername
 130	} else {
 131		params["chat_id"] = strconv.FormatInt(file.ChatID, 10)
 132	}
 133
 134	if file.ReplyToMessageID != 0 {
 135		params["reply_to_message_id"] = strconv.Itoa(file.ReplyToMessageID)
 136	}
 137
 138	if file.ReplyMarkup != nil {
 139		data, err := json.Marshal(file.ReplyMarkup)
 140		if err != nil {
 141			return params, err
 142		}
 143
 144		params["reply_markup"] = string(data)
 145	}
 146
 147	if file.MimeType != "" {
 148		params["mime_type"] = file.MimeType
 149	}
 150
 151	if file.FileSize > 0 {
 152		params["file_size"] = strconv.Itoa(file.FileSize)
 153	}
 154
 155	params["disable_notification"] = strconv.FormatBool(file.DisableNotification)
 156
 157	return params, nil
 158}
 159
 160// getFile returns the file.
 161func (file BaseFile) getFile() interface{} {
 162	return file.File
 163}
 164
 165// useExistingFile returns if the BaseFile has already been uploaded.
 166func (file BaseFile) useExistingFile() bool {
 167	return file.UseExisting
 168}
 169
 170// BaseEdit is base type of all chat edits.
 171type BaseEdit struct {
 172	ChatID          int64
 173	ChannelUsername string
 174	MessageID       int
 175	InlineMessageID string
 176	ReplyMarkup     *InlineKeyboardMarkup
 177}
 178
 179func (edit BaseEdit) values() (url.Values, error) {
 180	v := url.Values{}
 181
 182	if edit.InlineMessageID == "" {
 183		if edit.ChannelUsername != "" {
 184			v.Add("chat_id", edit.ChannelUsername)
 185		} else {
 186			v.Add("chat_id", strconv.FormatInt(edit.ChatID, 10))
 187		}
 188		v.Add("message_id", strconv.Itoa(edit.MessageID))
 189	} else {
 190		v.Add("inline_message_id", edit.InlineMessageID)
 191	}
 192
 193	if edit.ReplyMarkup != nil {
 194		data, err := json.Marshal(edit.ReplyMarkup)
 195		if err != nil {
 196			return v, err
 197		}
 198		v.Add("reply_markup", string(data))
 199	}
 200
 201	return v, nil
 202}
 203
 204// MessageConfig contains information about a SendMessage request.
 205type MessageConfig struct {
 206	BaseChat
 207	Text                  string
 208	ParseMode             string
 209	DisableWebPagePreview bool
 210}
 211
 212// values returns a url.Values representation of MessageConfig.
 213func (config MessageConfig) values() (url.Values, error) {
 214	v, err := config.BaseChat.values()
 215	if err != nil {
 216		return v, err
 217	}
 218	v.Add("text", config.Text)
 219	v.Add("disable_web_page_preview", strconv.FormatBool(config.DisableWebPagePreview))
 220	if config.ParseMode != "" {
 221		v.Add("parse_mode", config.ParseMode)
 222	}
 223
 224	return v, nil
 225}
 226
 227// method returns Telegram API method name for sending Message.
 228func (config MessageConfig) method() string {
 229	return "sendMessage"
 230}
 231
 232// ForwardConfig contains information about a ForwardMessage request.
 233type ForwardConfig struct {
 234	BaseChat
 235	FromChatID          int64 // required
 236	FromChannelUsername string
 237	MessageID           int // required
 238}
 239
 240// values returns a url.Values representation of ForwardConfig.
 241func (config ForwardConfig) values() (url.Values, error) {
 242	v, err := config.BaseChat.values()
 243	if err != nil {
 244		return v, err
 245	}
 246	v.Add("from_chat_id", strconv.FormatInt(config.FromChatID, 10))
 247	v.Add("message_id", strconv.Itoa(config.MessageID))
 248	return v, nil
 249}
 250
 251// method returns Telegram API method name for sending Forward.
 252func (config ForwardConfig) method() string {
 253	return "forwardMessage"
 254}
 255
 256// PhotoConfig contains information about a SendPhoto request.
 257type PhotoConfig struct {
 258	BaseFile
 259	Caption   string
 260	ParseMode string
 261}
 262
 263// Params returns a map[string]string representation of PhotoConfig.
 264func (config PhotoConfig) params() (map[string]string, error) {
 265	params, _ := config.BaseFile.params()
 266
 267	if config.Caption != "" {
 268		params["caption"] = config.Caption
 269		if config.ParseMode != "" {
 270			params["parse_mode"] = config.ParseMode
 271		}
 272	}
 273
 274	return params, nil
 275}
 276
 277// Values returns a url.Values representation of PhotoConfig.
 278func (config PhotoConfig) values() (url.Values, error) {
 279	v, err := config.BaseChat.values()
 280	if err != nil {
 281		return v, err
 282	}
 283
 284	v.Add(config.name(), config.FileID)
 285	if config.Caption != "" {
 286		v.Add("caption", config.Caption)
 287		if config.ParseMode != "" {
 288			v.Add("parse_mode", config.ParseMode)
 289		}
 290	}
 291
 292	return v, nil
 293}
 294
 295// name returns the field name for the Photo.
 296func (config PhotoConfig) name() string {
 297	return "photo"
 298}
 299
 300// method returns Telegram API method name for sending Photo.
 301func (config PhotoConfig) method() string {
 302	return "sendPhoto"
 303}
 304
 305// AudioConfig contains information about a SendAudio request.
 306type AudioConfig struct {
 307	BaseFile
 308	Caption   string
 309	ParseMode string
 310	Duration  int
 311	Performer string
 312	Title     string
 313}
 314
 315// values returns a url.Values representation of AudioConfig.
 316func (config AudioConfig) values() (url.Values, error) {
 317	v, err := config.BaseChat.values()
 318	if err != nil {
 319		return v, err
 320	}
 321
 322	v.Add(config.name(), config.FileID)
 323	if config.Duration != 0 {
 324		v.Add("duration", strconv.Itoa(config.Duration))
 325	}
 326
 327	if config.Performer != "" {
 328		v.Add("performer", config.Performer)
 329	}
 330	if config.Title != "" {
 331		v.Add("title", config.Title)
 332	}
 333	if config.Caption != "" {
 334		v.Add("caption", config.Caption)
 335		if config.ParseMode != "" {
 336			v.Add("parse_mode", config.ParseMode)
 337		}
 338	}
 339
 340	return v, nil
 341}
 342
 343// params returns a map[string]string representation of AudioConfig.
 344func (config AudioConfig) params() (map[string]string, error) {
 345	params, _ := config.BaseFile.params()
 346
 347	if config.Duration != 0 {
 348		params["duration"] = strconv.Itoa(config.Duration)
 349	}
 350
 351	if config.Performer != "" {
 352		params["performer"] = config.Performer
 353	}
 354	if config.Title != "" {
 355		params["title"] = config.Title
 356	}
 357	if config.Caption != "" {
 358		params["caption"] = config.Caption
 359		if config.ParseMode != "" {
 360			params["parse_mode"] = config.ParseMode
 361		}
 362	}
 363
 364	return params, nil
 365}
 366
 367// name returns the field name for the Audio.
 368func (config AudioConfig) name() string {
 369	return "audio"
 370}
 371
 372// method returns Telegram API method name for sending Audio.
 373func (config AudioConfig) method() string {
 374	return "sendAudio"
 375}
 376
 377// DocumentConfig contains information about a SendDocument request.
 378type DocumentConfig struct {
 379	BaseFile
 380	Caption   string
 381	ParseMode string
 382}
 383
 384// values returns a url.Values representation of DocumentConfig.
 385func (config DocumentConfig) values() (url.Values, error) {
 386	v, err := config.BaseChat.values()
 387	if err != nil {
 388		return v, err
 389	}
 390
 391	v.Add(config.name(), config.FileID)
 392	if config.Caption != "" {
 393		v.Add("caption", config.Caption)
 394		if config.ParseMode != "" {
 395			v.Add("parse_mode", config.ParseMode)
 396		}
 397	}
 398
 399	return v, nil
 400}
 401
 402// params returns a map[string]string representation of DocumentConfig.
 403func (config DocumentConfig) params() (map[string]string, error) {
 404	params, _ := config.BaseFile.params()
 405
 406	if config.Caption != "" {
 407		params["caption"] = config.Caption
 408		if config.ParseMode != "" {
 409			params["parse_mode"] = config.ParseMode
 410		}
 411	}
 412
 413	return params, nil
 414}
 415
 416// name returns the field name for the Document.
 417func (config DocumentConfig) name() string {
 418	return "document"
 419}
 420
 421// method returns Telegram API method name for sending Document.
 422func (config DocumentConfig) method() string {
 423	return "sendDocument"
 424}
 425
 426// StickerConfig contains information about a SendSticker request.
 427type StickerConfig struct {
 428	BaseFile
 429}
 430
 431// values returns a url.Values representation of StickerConfig.
 432func (config StickerConfig) values() (url.Values, error) {
 433	v, err := config.BaseChat.values()
 434	if err != nil {
 435		return v, err
 436	}
 437
 438	v.Add(config.name(), config.FileID)
 439
 440	return v, nil
 441}
 442
 443// params returns a map[string]string representation of StickerConfig.
 444func (config StickerConfig) params() (map[string]string, error) {
 445	params, _ := config.BaseFile.params()
 446
 447	return params, nil
 448}
 449
 450// name returns the field name for the Sticker.
 451func (config StickerConfig) name() string {
 452	return "sticker"
 453}
 454
 455// method returns Telegram API method name for sending Sticker.
 456func (config StickerConfig) method() string {
 457	return "sendSticker"
 458}
 459
 460// VideoConfig contains information about a SendVideo request.
 461type VideoConfig struct {
 462	BaseFile
 463	Duration  int
 464	Caption   string
 465	ParseMode string
 466}
 467
 468// values returns a url.Values representation of VideoConfig.
 469func (config VideoConfig) values() (url.Values, error) {
 470	v, err := config.BaseChat.values()
 471	if err != nil {
 472		return v, err
 473	}
 474
 475	v.Add(config.name(), config.FileID)
 476	if config.Duration != 0 {
 477		v.Add("duration", strconv.Itoa(config.Duration))
 478	}
 479	if config.Caption != "" {
 480		v.Add("caption", config.Caption)
 481		if config.ParseMode != "" {
 482			v.Add("parse_mode", config.ParseMode)
 483		}
 484	}
 485
 486	return v, nil
 487}
 488
 489// params returns a map[string]string representation of VideoConfig.
 490func (config VideoConfig) params() (map[string]string, error) {
 491	params, _ := config.BaseFile.params()
 492
 493	if config.Caption != "" {
 494		params["caption"] = config.Caption
 495		if config.ParseMode != "" {
 496			params["parse_mode"] = config.ParseMode
 497		}
 498	}
 499
 500	return params, nil
 501}
 502
 503// name returns the field name for the Video.
 504func (config VideoConfig) name() string {
 505	return "video"
 506}
 507
 508// method returns Telegram API method name for sending Video.
 509func (config VideoConfig) method() string {
 510	return "sendVideo"
 511}
 512
 513// AnimationConfig contains information about a SendAnimation request.
 514type AnimationConfig struct {
 515	BaseFile
 516	Duration  int
 517	Caption   string
 518	ParseMode string
 519}
 520
 521// values returns a url.Values representation of AnimationConfig.
 522func (config AnimationConfig) values() (url.Values, error) {
 523	v, err := config.BaseChat.values()
 524	if err != nil {
 525		return v, err
 526	}
 527
 528	v.Add(config.name(), config.FileID)
 529	if config.Duration != 0 {
 530		v.Add("duration", strconv.Itoa(config.Duration))
 531	}
 532	if config.Caption != "" {
 533		v.Add("caption", config.Caption)
 534		if config.ParseMode != "" {
 535			v.Add("parse_mode", config.ParseMode)
 536		}
 537	}
 538
 539	return v, nil
 540}
 541
 542// params returns a map[string]string representation of AnimationConfig.
 543func (config AnimationConfig) params() (map[string]string, error) {
 544	params, _ := config.BaseFile.params()
 545
 546	if config.Caption != "" {
 547		params["caption"] = config.Caption
 548		if config.ParseMode != "" {
 549			params["parse_mode"] = config.ParseMode
 550		}
 551	}
 552
 553	return params, nil
 554}
 555
 556// name returns the field name for the Animation.
 557func (config AnimationConfig) name() string {
 558	return "animation"
 559}
 560
 561// method returns Telegram API method name for sending Animation.
 562func (config AnimationConfig) method() string {
 563	return "sendAnimation"
 564}
 565
 566// VideoNoteConfig contains information about a SendVideoNote request.
 567type VideoNoteConfig struct {
 568	BaseFile
 569	Duration int
 570	Length   int
 571}
 572
 573// values returns a url.Values representation of VideoNoteConfig.
 574func (config VideoNoteConfig) values() (url.Values, error) {
 575	v, err := config.BaseChat.values()
 576	if err != nil {
 577		return v, err
 578	}
 579
 580	v.Add(config.name(), config.FileID)
 581	if config.Duration != 0 {
 582		v.Add("duration", strconv.Itoa(config.Duration))
 583	}
 584
 585	// Telegram API seems to have a bug, if no length is provided or it is 0, it will send an error response
 586	if config.Length != 0 {
 587		v.Add("length", strconv.Itoa(config.Length))
 588	}
 589
 590	return v, nil
 591}
 592
 593// params returns a map[string]string representation of VideoNoteConfig.
 594func (config VideoNoteConfig) params() (map[string]string, error) {
 595	params, _ := config.BaseFile.params()
 596
 597	if config.Length != 0 {
 598		params["length"] = strconv.Itoa(config.Length)
 599	}
 600	if config.Duration != 0 {
 601		params["duration"] = strconv.Itoa(config.Duration)
 602	}
 603
 604	return params, nil
 605}
 606
 607// name returns the field name for the VideoNote.
 608func (config VideoNoteConfig) name() string {
 609	return "video_note"
 610}
 611
 612// method returns Telegram API method name for sending VideoNote.
 613func (config VideoNoteConfig) method() string {
 614	return "sendVideoNote"
 615}
 616
 617// VoiceConfig contains information about a SendVoice request.
 618type VoiceConfig struct {
 619	BaseFile
 620	Caption   string
 621	ParseMode string
 622	Duration  int
 623}
 624
 625// values returns a url.Values representation of VoiceConfig.
 626func (config VoiceConfig) values() (url.Values, error) {
 627	v, err := config.BaseChat.values()
 628	if err != nil {
 629		return v, err
 630	}
 631
 632	v.Add(config.name(), config.FileID)
 633	if config.Duration != 0 {
 634		v.Add("duration", strconv.Itoa(config.Duration))
 635	}
 636	if config.Caption != "" {
 637		v.Add("caption", config.Caption)
 638		if config.ParseMode != "" {
 639			v.Add("parse_mode", config.ParseMode)
 640		}
 641	}
 642
 643	return v, nil
 644}
 645
 646// params returns a map[string]string representation of VoiceConfig.
 647func (config VoiceConfig) params() (map[string]string, error) {
 648	params, _ := config.BaseFile.params()
 649
 650	if config.Duration != 0 {
 651		params["duration"] = strconv.Itoa(config.Duration)
 652	}
 653	if config.Caption != "" {
 654		params["caption"] = config.Caption
 655		if config.ParseMode != "" {
 656			params["parse_mode"] = config.ParseMode
 657		}
 658	}
 659
 660	return params, nil
 661}
 662
 663// name returns the field name for the Voice.
 664func (config VoiceConfig) name() string {
 665	return "voice"
 666}
 667
 668// method returns Telegram API method name for sending Voice.
 669func (config VoiceConfig) method() string {
 670	return "sendVoice"
 671}
 672
 673// MediaGroupConfig contains information about a sendMediaGroup request.
 674type MediaGroupConfig struct {
 675	BaseChat
 676	InputMedia []interface{}
 677}
 678
 679func (config MediaGroupConfig) values() (url.Values, error) {
 680	v, err := config.BaseChat.values()
 681	if err != nil {
 682		return v, err
 683	}
 684
 685	data, err := json.Marshal(config.InputMedia)
 686	if err != nil {
 687		return v, err
 688	}
 689
 690	v.Add("media", string(data))
 691
 692	return v, nil
 693}
 694
 695func (config MediaGroupConfig) method() string {
 696	return "sendMediaGroup"
 697}
 698
 699// LocationConfig contains information about a SendLocation request.
 700type LocationConfig struct {
 701	BaseChat
 702	Latitude  float64 // required
 703	Longitude float64 // required
 704}
 705
 706// values returns a url.Values representation of LocationConfig.
 707func (config LocationConfig) values() (url.Values, error) {
 708	v, err := config.BaseChat.values()
 709	if err != nil {
 710		return v, err
 711	}
 712
 713	v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
 714	v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
 715
 716	return v, nil
 717}
 718
 719// method returns Telegram API method name for sending Location.
 720func (config LocationConfig) method() string {
 721	return "sendLocation"
 722}
 723
 724// VenueConfig contains information about a SendVenue request.
 725type VenueConfig struct {
 726	BaseChat
 727	Latitude     float64 // required
 728	Longitude    float64 // required
 729	Title        string  // required
 730	Address      string  // required
 731	FoursquareID string
 732}
 733
 734func (config VenueConfig) values() (url.Values, error) {
 735	v, err := config.BaseChat.values()
 736	if err != nil {
 737		return v, err
 738	}
 739
 740	v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
 741	v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
 742	v.Add("title", config.Title)
 743	v.Add("address", config.Address)
 744	if config.FoursquareID != "" {
 745		v.Add("foursquare_id", config.FoursquareID)
 746	}
 747
 748	return v, nil
 749}
 750
 751func (config VenueConfig) method() string {
 752	return "sendVenue"
 753}
 754
 755// ContactConfig allows you to send a contact.
 756type ContactConfig struct {
 757	BaseChat
 758	PhoneNumber string
 759	FirstName   string
 760	LastName    string
 761}
 762
 763func (config ContactConfig) values() (url.Values, error) {
 764	v, err := config.BaseChat.values()
 765	if err != nil {
 766		return v, err
 767	}
 768
 769	v.Add("phone_number", config.PhoneNumber)
 770	v.Add("first_name", config.FirstName)
 771	v.Add("last_name", config.LastName)
 772
 773	return v, nil
 774}
 775
 776func (config ContactConfig) method() string {
 777	return "sendContact"
 778}
 779
 780// SendPollConfig allows you to send a poll.
 781type SendPollConfig struct {
 782	BaseChat
 783	Question              string
 784	Options               []string
 785	IsAnonymous           bool
 786	Type                  string
 787	AllowsMultipleAnswers bool
 788	CorrectOptionID       int64
 789	Explanation           string
 790	ExplanationParseMode  string
 791	OpenPeriod            int
 792	CloseDate             int
 793	IsClosed              bool
 794}
 795
 796func (config SendPollConfig) values() (url.Values, error) {
 797	params, err := config.BaseChat.params()
 798	if err != nil {
 799		return params.toValues(), err
 800	}
 801
 802	params["question"] = config.Question
 803	err = params.AddInterface("options", config.Options)
 804	params["is_anonymous"] = strconv.FormatBool(config.IsAnonymous)
 805	params.AddNonEmpty("type", config.Type)
 806	params["allows_multiple_answers"] = strconv.FormatBool(config.AllowsMultipleAnswers)
 807	params["correct_option_id"] = strconv.FormatInt(config.CorrectOptionID, 10)
 808	params.AddBool("is_closed", config.IsClosed)
 809	params.AddNonEmpty("explanation", config.Explanation)
 810	params.AddNonEmpty("explanation_parse_mode", config.ExplanationParseMode)
 811	params.AddNonZero("open_period", config.OpenPeriod)
 812	params.AddNonZero("close_date", config.CloseDate)
 813
 814	return params.toValues(), err
 815}
 816
 817func (SendPollConfig) method() string {
 818	return "sendPoll"
 819}
 820
 821// GameConfig allows you to send a game.
 822type GameConfig struct {
 823	BaseChat
 824	GameShortName string
 825}
 826
 827func (config GameConfig) values() (url.Values, error) {
 828	v, err := config.BaseChat.values()
 829	if err != nil {
 830		return v, err
 831	}
 832
 833	v.Add("game_short_name", config.GameShortName)
 834
 835	return v, nil
 836}
 837
 838func (config GameConfig) method() string {
 839	return "sendGame"
 840}
 841
 842// SetGameScoreConfig allows you to update the game score in a chat.
 843type SetGameScoreConfig struct {
 844	UserID             int
 845	Score              int
 846	Force              bool
 847	DisableEditMessage bool
 848	ChatID             int64
 849	ChannelUsername    string
 850	MessageID          int
 851	InlineMessageID    string
 852}
 853
 854func (config SetGameScoreConfig) values() (url.Values, error) {
 855	v := url.Values{}
 856
 857	v.Add("user_id", strconv.Itoa(config.UserID))
 858	v.Add("score", strconv.Itoa(config.Score))
 859	if config.InlineMessageID == "" {
 860		if config.ChannelUsername == "" {
 861			v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
 862		} else {
 863			v.Add("chat_id", config.ChannelUsername)
 864		}
 865		v.Add("message_id", strconv.Itoa(config.MessageID))
 866	} else {
 867		v.Add("inline_message_id", config.InlineMessageID)
 868	}
 869	v.Add("disable_edit_message", strconv.FormatBool(config.DisableEditMessage))
 870
 871	return v, nil
 872}
 873
 874func (config SetGameScoreConfig) method() string {
 875	return "setGameScore"
 876}
 877
 878// GetGameHighScoresConfig allows you to fetch the high scores for a game.
 879type GetGameHighScoresConfig struct {
 880	UserID          int
 881	ChatID          int
 882	ChannelUsername string
 883	MessageID       int
 884	InlineMessageID string
 885}
 886
 887func (config GetGameHighScoresConfig) values() (url.Values, error) {
 888	v := url.Values{}
 889
 890	v.Add("user_id", strconv.Itoa(config.UserID))
 891	if config.InlineMessageID == "" {
 892		if config.ChannelUsername == "" {
 893			v.Add("chat_id", strconv.Itoa(config.ChatID))
 894		} else {
 895			v.Add("chat_id", config.ChannelUsername)
 896		}
 897		v.Add("message_id", strconv.Itoa(config.MessageID))
 898	} else {
 899		v.Add("inline_message_id", config.InlineMessageID)
 900	}
 901
 902	return v, nil
 903}
 904
 905func (config GetGameHighScoresConfig) method() string {
 906	return "getGameHighScores"
 907}
 908
 909// ChatActionConfig contains information about a SendChatAction request.
 910type ChatActionConfig struct {
 911	BaseChat
 912	Action string // required
 913}
 914
 915// values returns a url.Values representation of ChatActionConfig.
 916func (config ChatActionConfig) values() (url.Values, error) {
 917	v, err := config.BaseChat.values()
 918	if err != nil {
 919		return v, err
 920	}
 921	v.Add("action", config.Action)
 922	return v, nil
 923}
 924
 925// method returns Telegram API method name for sending ChatAction.
 926func (config ChatActionConfig) method() string {
 927	return "sendChatAction"
 928}
 929
 930// EditMessageTextConfig allows you to modify the text in a message.
 931type EditMessageTextConfig struct {
 932	BaseEdit
 933	Text                  string
 934	ParseMode             string
 935	DisableWebPagePreview bool
 936}
 937
 938func (config EditMessageTextConfig) values() (url.Values, error) {
 939	v, err := config.BaseEdit.values()
 940	if err != nil {
 941		return v, err
 942	}
 943
 944	v.Add("text", config.Text)
 945	v.Add("parse_mode", config.ParseMode)
 946	v.Add("disable_web_page_preview", strconv.FormatBool(config.DisableWebPagePreview))
 947
 948	return v, nil
 949}
 950
 951func (config EditMessageTextConfig) method() string {
 952	return "editMessageText"
 953}
 954
 955// EditMessageCaptionConfig allows you to modify the caption of a message.
 956type EditMessageCaptionConfig struct {
 957	BaseEdit
 958	Caption   string
 959	ParseMode string
 960}
 961
 962func (config EditMessageCaptionConfig) values() (url.Values, error) {
 963	v, _ := config.BaseEdit.values()
 964
 965	v.Add("caption", config.Caption)
 966	if config.ParseMode != "" {
 967		v.Add("parse_mode", config.ParseMode)
 968	}
 969
 970	return v, nil
 971}
 972
 973func (config EditMessageCaptionConfig) method() string {
 974	return "editMessageCaption"
 975}
 976
 977// EditMessageReplyMarkupConfig allows you to modify the reply markup
 978// of a message.
 979type EditMessageReplyMarkupConfig struct {
 980	BaseEdit
 981}
 982
 983func (config EditMessageReplyMarkupConfig) values() (url.Values, error) {
 984	return config.BaseEdit.values()
 985}
 986
 987func (config EditMessageReplyMarkupConfig) method() string {
 988	return "editMessageReplyMarkup"
 989}
 990
 991// UserProfilePhotosConfig contains information about a
 992// GetUserProfilePhotos request.
 993type UserProfilePhotosConfig struct {
 994	UserID int
 995	Offset int
 996	Limit  int
 997}
 998
 999// FileConfig has information about a file hosted on Telegram.
1000type FileConfig struct {
1001	FileID string
1002}
1003
1004// UpdateConfig contains information about a GetUpdates request.
1005type UpdateConfig struct {
1006	Offset  int
1007	Limit   int
1008	Timeout int
1009}
1010
1011// WebhookConfig contains information about a SetWebhook request.
1012type WebhookConfig struct {
1013	URL            *url.URL
1014	Certificate    interface{}
1015	MaxConnections int
1016}
1017
1018// FileBytes contains information about a set of bytes to upload
1019// as a File.
1020type FileBytes struct {
1021	Name  string
1022	Bytes []byte
1023}
1024
1025// FileReader contains information about a reader to upload as a File.
1026// If Size is -1, it will read the entire Reader into memory to
1027// calculate a Size.
1028type FileReader struct {
1029	Name   string
1030	Reader io.Reader
1031	Size   int64
1032}
1033
1034// InlineConfig contains information on making an InlineQuery response.
1035type InlineConfig struct {
1036	InlineQueryID     string        `json:"inline_query_id"`
1037	Results           []interface{} `json:"results"`
1038	CacheTime         int           `json:"cache_time"`
1039	IsPersonal        bool          `json:"is_personal"`
1040	NextOffset        string        `json:"next_offset"`
1041	SwitchPMText      string        `json:"switch_pm_text"`
1042	SwitchPMParameter string        `json:"switch_pm_parameter"`
1043}
1044
1045// CallbackConfig contains information on making a CallbackQuery response.
1046type CallbackConfig struct {
1047	CallbackQueryID string `json:"callback_query_id"`
1048	Text            string `json:"text"`
1049	ShowAlert       bool   `json:"show_alert"`
1050	URL             string `json:"url"`
1051	CacheTime       int    `json:"cache_time"`
1052}
1053
1054// ChatMemberConfig contains information about a user in a chat for use
1055// with administrative functions such as kicking or unbanning a user.
1056type ChatMemberConfig struct {
1057	ChatID             int64
1058	SuperGroupUsername string
1059	ChannelUsername    string
1060	UserID             int
1061}
1062
1063// KickChatMemberConfig contains extra fields to kick user
1064type KickChatMemberConfig struct {
1065	ChatMemberConfig
1066	UntilDate int64
1067}
1068
1069// RestrictChatMemberConfig contains fields to restrict members of chat
1070type RestrictChatMemberConfig struct {
1071	ChatMemberConfig
1072	UntilDate             int64
1073	CanSendMessages       *bool
1074	CanSendMediaMessages  *bool
1075	CanSendOtherMessages  *bool
1076	CanAddWebPagePreviews *bool
1077}
1078
1079// PromoteChatMemberConfig contains fields to promote members of chat
1080type PromoteChatMemberConfig struct {
1081	ChatMemberConfig
1082	CanChangeInfo      *bool
1083	CanPostMessages    *bool
1084	CanEditMessages    *bool
1085	CanDeleteMessages  *bool
1086	CanInviteUsers     *bool
1087	CanRestrictMembers *bool
1088	CanPinMessages     *bool
1089	CanPromoteMembers  *bool
1090}
1091
1092// ChatConfig contains information about getting information on a chat.
1093type ChatConfig struct {
1094	ChatID             int64
1095	SuperGroupUsername string
1096}
1097
1098// ChatConfigWithUser contains information about getting information on
1099// a specific user within a chat.
1100type ChatConfigWithUser struct {
1101	ChatID             int64
1102	SuperGroupUsername string
1103	UserID             int
1104}
1105
1106// InvoiceConfig contains information for sendInvoice request.
1107type InvoiceConfig struct {
1108	BaseChat
1109	Title               string          // required
1110	Description         string          // required
1111	Payload             string          // required
1112	ProviderToken       string          // required
1113	StartParameter      string          // required
1114	Currency            string          // required
1115	Prices              *[]LabeledPrice // required
1116	PhotoURL            string
1117	PhotoSize           int
1118	PhotoWidth          int
1119	PhotoHeight         int
1120	NeedName            bool
1121	NeedPhoneNumber     bool
1122	NeedEmail           bool
1123	NeedShippingAddress bool
1124	IsFlexible          bool
1125}
1126
1127func (config InvoiceConfig) values() (url.Values, error) {
1128	v, err := config.BaseChat.values()
1129	if err != nil {
1130		return v, err
1131	}
1132	v.Add("title", config.Title)
1133	v.Add("description", config.Description)
1134	v.Add("payload", config.Payload)
1135	v.Add("provider_token", config.ProviderToken)
1136	v.Add("start_parameter", config.StartParameter)
1137	v.Add("currency", config.Currency)
1138	data, err := json.Marshal(config.Prices)
1139	if err != nil {
1140		return v, err
1141	}
1142	v.Add("prices", string(data))
1143	if config.PhotoURL != "" {
1144		v.Add("photo_url", config.PhotoURL)
1145	}
1146	if config.PhotoSize != 0 {
1147		v.Add("photo_size", strconv.Itoa(config.PhotoSize))
1148	}
1149	if config.PhotoWidth != 0 {
1150		v.Add("photo_width", strconv.Itoa(config.PhotoWidth))
1151	}
1152	if config.PhotoHeight != 0 {
1153		v.Add("photo_height", strconv.Itoa(config.PhotoHeight))
1154	}
1155	if config.NeedName != false {
1156		v.Add("need_name", strconv.FormatBool(config.NeedName))
1157	}
1158	if config.NeedPhoneNumber != false {
1159		v.Add("need_phone_number", strconv.FormatBool(config.NeedPhoneNumber))
1160	}
1161	if config.NeedEmail != false {
1162		v.Add("need_email", strconv.FormatBool(config.NeedEmail))
1163	}
1164	if config.NeedShippingAddress != false {
1165		v.Add("need_shipping_address", strconv.FormatBool(config.NeedShippingAddress))
1166	}
1167	if config.IsFlexible != false {
1168		v.Add("is_flexible", strconv.FormatBool(config.IsFlexible))
1169	}
1170
1171	return v, nil
1172}
1173
1174func (config InvoiceConfig) method() string {
1175	return "sendInvoice"
1176}
1177
1178// ShippingConfig contains information for answerShippingQuery request.
1179type ShippingConfig struct {
1180	ShippingQueryID string // required
1181	OK              bool   // required
1182	ShippingOptions *[]ShippingOption
1183	ErrorMessage    string
1184}
1185
1186// PreCheckoutConfig conatins information for answerPreCheckoutQuery request.
1187type PreCheckoutConfig struct {
1188	PreCheckoutQueryID string // required
1189	OK                 bool   // required
1190	ErrorMessage       string
1191}
1192
1193// DeleteMessageConfig contains information of a message in a chat to delete.
1194type DeleteMessageConfig struct {
1195	ChannelUsername string
1196	ChatID          int64
1197	MessageID       int
1198}
1199
1200func (config DeleteMessageConfig) method() string {
1201	return "deleteMessage"
1202}
1203
1204func (config DeleteMessageConfig) values() (url.Values, error) {
1205	v := url.Values{}
1206
1207	if config.ChannelUsername == "" {
1208		v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1209	} else {
1210		v.Add("chat_id", config.ChannelUsername)
1211	}
1212
1213	v.Add("message_id", strconv.Itoa(config.MessageID))
1214
1215	return v, nil
1216}
1217
1218// PinChatMessageConfig contains information of a message in a chat to pin.
1219type PinChatMessageConfig struct {
1220	ChatID              int64
1221	MessageID           int
1222	DisableNotification bool
1223}
1224
1225func (config PinChatMessageConfig) method() string {
1226	return "pinChatMessage"
1227}
1228
1229func (config PinChatMessageConfig) values() (url.Values, error) {
1230	v := url.Values{}
1231
1232	v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1233	v.Add("message_id", strconv.Itoa(config.MessageID))
1234	v.Add("disable_notification", strconv.FormatBool(config.DisableNotification))
1235
1236	return v, nil
1237}
1238
1239// UnpinChatMessageConfig contains information of chat to unpin.
1240type UnpinChatMessageConfig struct {
1241	ChatID int64
1242}
1243
1244func (config UnpinChatMessageConfig) method() string {
1245	return "unpinChatMessage"
1246}
1247
1248func (config UnpinChatMessageConfig) values() (url.Values, error) {
1249	v := url.Values{}
1250
1251	v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1252
1253	return v, nil
1254}
1255
1256// SetChatTitleConfig contains information for change chat title.
1257type SetChatTitleConfig struct {
1258	ChatID int64
1259	Title  string
1260}
1261
1262func (config SetChatTitleConfig) method() string {
1263	return "setChatTitle"
1264}
1265
1266func (config SetChatTitleConfig) values() (url.Values, error) {
1267	v := url.Values{}
1268
1269	v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1270	v.Add("title", config.Title)
1271
1272	return v, nil
1273}
1274
1275// SetChatDescriptionConfig contains information for change chat description.
1276type SetChatDescriptionConfig struct {
1277	ChatID      int64
1278	Description string
1279}
1280
1281func (config SetChatDescriptionConfig) method() string {
1282	return "setChatDescription"
1283}
1284
1285func (config SetChatDescriptionConfig) values() (url.Values, error) {
1286	v := url.Values{}
1287
1288	v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1289	v.Add("description", config.Description)
1290
1291	return v, nil
1292}
1293
1294// SetChatPhotoConfig contains information for change chat photo
1295type SetChatPhotoConfig struct {
1296	BaseFile
1297}
1298
1299// name returns the field name for the Photo.
1300func (config SetChatPhotoConfig) name() string {
1301	return "photo"
1302}
1303
1304// method returns Telegram API method name for sending Photo.
1305func (config SetChatPhotoConfig) method() string {
1306	return "setChatPhoto"
1307}
1308
1309// DeleteChatPhotoConfig contains information for delete chat photo.
1310type DeleteChatPhotoConfig struct {
1311	ChatID int64
1312}
1313
1314func (config DeleteChatPhotoConfig) method() string {
1315	return "deleteChatPhoto"
1316}
1317
1318func (config DeleteChatPhotoConfig) values() (url.Values, error) {
1319	v := url.Values{}
1320
1321	v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
1322
1323	return v, nil
1324}
1325
1326// GetStickerSetConfig contains information for get sticker set.
1327type GetStickerSetConfig struct {
1328	Name string
1329}
1330
1331func (config GetStickerSetConfig) method() string {
1332	return "getStickerSet"
1333}
1334
1335func (config GetStickerSetConfig) values() (url.Values, error) {
1336	v := url.Values{}
1337	v.Add("name", config.Name)
1338	return v, nil
1339}
1340
1341// DiceConfig contains information about a sendDice request.
1342type DiceConfig struct {
1343	BaseChat
1344	// Emoji on which the dice throw animation is based.
1345	// Currently, must be one of “🎲”, “🎯”, or “🏀”.
1346	// Dice can have values 1-6 for “🎲” and “🎯”, and values 1-5 for “🏀”.
1347	// Defaults to “🎲”
1348	Emoji string
1349}
1350
1351// values returns a url.Values representation of DiceConfig.
1352func (config DiceConfig) values() (url.Values, error) {
1353	v, err := config.BaseChat.values()
1354	if err != nil {
1355		return v, err
1356	}
1357	if config.Emoji != "" {
1358		v.Add("emoji", config.Emoji)
1359	}
1360	return v, nil
1361}
1362
1363// method returns Telegram API method name for sending Dice.
1364func (config DiceConfig) method() string {
1365	return "sendDice"
1366}