all repos — telegram-bot-api @ bf143a9e9ba8a9e9e6265acc862c1f54fe1d87b7

Golang bindings for the Telegram Bot API

types.go (view raw)

   1package tgbotapi
   2
   3import (
   4	"encoding/json"
   5	"errors"
   6	"fmt"
   7	"net/url"
   8	"strings"
   9	"time"
  10)
  11
  12// APIResponse is a response from the Telegram API with the result
  13// stored raw.
  14type APIResponse struct {
  15	Ok          bool                `json:"ok"`
  16	Result      json.RawMessage     `json:"result"`
  17	ErrorCode   int                 `json:"error_code"`
  18	Description string              `json:"description"`
  19	Parameters  *ResponseParameters `json:"parameters"`
  20}
  21
  22// ResponseParameters are various errors that can be returned in APIResponse.
  23type ResponseParameters struct {
  24	MigrateToChatID int64 `json:"migrate_to_chat_id"` // optional
  25	RetryAfter      int   `json:"retry_after"`        // optional
  26}
  27
  28// Update is an update response, from GetUpdates.
  29type Update struct {
  30	UpdateID           int                 `json:"update_id"`
  31	Message            *Message            `json:"message"`
  32	EditedMessage      *Message            `json:"edited_message"`
  33	ChannelPost        *Message            `json:"channel_post"`
  34	EditedChannelPost  *Message            `json:"edited_channel_post"`
  35	InlineQuery        *InlineQuery        `json:"inline_query"`
  36	ChosenInlineResult *ChosenInlineResult `json:"chosen_inline_result"`
  37	CallbackQuery      *CallbackQuery      `json:"callback_query"`
  38	ShippingQuery      *ShippingQuery      `json:"shipping_query"`
  39	PreCheckoutQuery   *PreCheckoutQuery   `json:"pre_checkout_query"`
  40}
  41
  42// UpdatesChannel is the channel for getting updates.
  43type UpdatesChannel <-chan Update
  44
  45// Clear discards all unprocessed incoming updates.
  46func (ch UpdatesChannel) Clear() {
  47	for len(ch) != 0 {
  48		<-ch
  49	}
  50}
  51
  52// User is a user on Telegram.
  53type User struct {
  54	ID           int    `json:"id"`
  55	FirstName    string `json:"first_name"`
  56	LastName     string `json:"last_name"`     // optional
  57	UserName     string `json:"username"`      // optional
  58	LanguageCode string `json:"language_code"` // optional
  59	IsBot        bool   `json:"is_bot"`        // optional
  60}
  61
  62// String displays a simple text version of a user.
  63//
  64// It is normally a user's username, but falls back to a first/last
  65// name as available.
  66func (u *User) String() string {
  67	if u == nil {
  68		return ""
  69	}
  70	if u.UserName != "" {
  71		return u.UserName
  72	}
  73
  74	name := u.FirstName
  75	if u.LastName != "" {
  76		name += " " + u.LastName
  77	}
  78
  79	return name
  80}
  81
  82// GroupChat is a group chat.
  83type GroupChat struct {
  84	ID    int    `json:"id"`
  85	Title string `json:"title"`
  86}
  87
  88// ChatPhoto represents a chat photo.
  89type ChatPhoto struct {
  90	SmallFileID string `json:"small_file_id"`
  91	BigFileID   string `json:"big_file_id"`
  92}
  93
  94// Chat contains information about the place a message was sent.
  95type Chat struct {
  96	ID                  int64      `json:"id"`
  97	Type                string     `json:"type"`
  98	Title               string     `json:"title"`                          // optional
  99	UserName            string     `json:"username"`                       // optional
 100	FirstName           string     `json:"first_name"`                     // optional
 101	LastName            string     `json:"last_name"`                      // optional
 102	AllMembersAreAdmins bool       `json:"all_members_are_administrators"` // optional
 103	Photo               *ChatPhoto `json:"photo"`
 104	Description         string     `json:"description,omitempty"` // optional
 105	InviteLink          string     `json:"invite_link,omitempty"` // optional
 106	PinnedMessage       *Message   `json:"pinned_message"`        // optional
 107}
 108
 109// IsPrivate returns if the Chat is a private conversation.
 110func (c Chat) IsPrivate() bool {
 111	return c.Type == "private"
 112}
 113
 114// IsGroup returns if the Chat is a group.
 115func (c Chat) IsGroup() bool {
 116	return c.Type == "group"
 117}
 118
 119// IsSuperGroup returns if the Chat is a supergroup.
 120func (c Chat) IsSuperGroup() bool {
 121	return c.Type == "supergroup"
 122}
 123
 124// IsChannel returns if the Chat is a channel.
 125func (c Chat) IsChannel() bool {
 126	return c.Type == "channel"
 127}
 128
 129// ChatConfig returns a ChatConfig struct for chat related methods.
 130func (c Chat) ChatConfig() ChatConfig {
 131	return ChatConfig{ChatID: c.ID}
 132}
 133
 134// Message is returned by almost every request, and contains data about
 135// almost anything.
 136type Message struct {
 137	// MessageID is a unique message identifier inside this chat
 138	MessageID int `json:"message_id"`
 139	// From is a sender, empty for messages sent to channels;
 140	//
 141	// optional
 142	From *User `json:"from"`
 143	// Date of the message was sent in Unix time
 144	Date int `json:"date"`
 145	// Chat is the conversation the message belongs to
 146	Chat *Chat `json:"chat"`
 147	// ForwardFrom for forwarded messages, sender of the original message;
 148	//
 149	// optional
 150	ForwardFrom *User `json:"forward_from"`
 151	// ForwardFromChat for messages forwarded from channels,
 152	// information about the original channel;
 153	//
 154	// optional
 155	ForwardFromChat *Chat `json:"forward_from_chat"`
 156	// ForwardFromMessageID for messages forwarded from channels,
 157	// identifier of the original message in the channel;
 158	//
 159	// optional
 160	ForwardFromMessageID int `json:"forward_from_message_id"`
 161	// ForwardDate for forwarded messages, date the original message was sent in Unix time;
 162	//
 163	// optional
 164	ForwardDate int `json:"forward_date"`
 165	// ReplyToMessage for replies, the original message.
 166	// Note that the Message object in this field will not contain further ReplyToMessage fields
 167	// even if it itself is a reply;
 168	//
 169	// optional
 170	ReplyToMessage *Message `json:"reply_to_message"`
 171	// ViaBot through which the message was sent;
 172	//
 173	// optional
 174	ViaBot *User `json:"via_bot"`
 175	// EditDate of the message was last edited in Unix time;
 176	//
 177	// optional
 178	EditDate int `json:"edit_date"`
 179	// MediaGroupID is the unique identifier of a media message group this message belongs to;
 180	//
 181	// optional
 182	MediaGroupID string `json:"media_group_id"`
 183	// AuthorSignature is the signature of the post author for messages in channels;
 184	//
 185	// optional
 186	AuthorSignature string `json:"author_signature"`
 187	// Text is for text messages, the actual UTF-8 text of the message, 0-4096 characters;
 188	//
 189	// optional
 190	Text string `json:"text"`
 191	// Entities is for text messages, special entities like usernames,
 192	// URLs, bot commands, etc. that appear in the text;
 193	//
 194	// optional
 195	Entities *[]MessageEntity `json:"entities"`
 196	// CaptionEntities;
 197	//
 198	// optional
 199	CaptionEntities *[]MessageEntity `json:"caption_entities"`
 200	// Audio message is an audio file, information about the file;
 201	//
 202	// optional
 203	Audio *Audio `json:"audio"`
 204	// Document message is a general file, information about the file;
 205	//
 206	// optional
 207	Document *Document `json:"document"`
 208	// Animation message is an animation, information about the animation.
 209	// For backward compatibility, when this field is set, the document field will also be set;
 210	//
 211	// optional
 212	Animation *ChatAnimation `json:"animation"`
 213	// Game message is a game, information about the game;
 214	//
 215	// optional
 216	Game *Game `json:"game"`
 217	// Photo message is a photo, available sizes of the photo;
 218	//
 219	// optional
 220	Photo *[]PhotoSize `json:"photo"`
 221	// Sticker message is a sticker, information about the sticker;
 222	//
 223	// optional
 224	Sticker *Sticker `json:"sticker"`
 225	// Video message is a video, information about the video;
 226	//
 227	// optional
 228	Video *Video `json:"video"`
 229	// VideoNote message is a video note, information about the video message;
 230	//
 231	// optional
 232	VideoNote *VideoNote `json:"video_note"`
 233	// Voice message is a voice message, information about the file;
 234	//
 235	// optional
 236	Voice *Voice `json:"voice"`
 237	// Caption for the animation, audio, document, photo, video or voice, 0-1024 characters;
 238	//
 239	// optional
 240	Caption string `json:"caption"`
 241	// Contact message is a shared contact, information about the contact;
 242	//
 243	// optional
 244	Contact *Contact `json:"contact"`
 245	// Location message is a shared location, information about the location;
 246	//
 247	// optional
 248	Location *Location `json:"location"`
 249	// Venue message is a venue, information about the venue.
 250	// For backward compatibility, when this field is set, the location field will also be set;
 251	//
 252	// optional
 253	Venue *Venue `json:"venue"`
 254	// NewChatMembers that were added to the group or supergroup
 255	// and information about them (the bot itself may be one of these members);
 256	//
 257	// optional
 258	NewChatMembers *[]User `json:"new_chat_members"`
 259	// LeftChatMember is a member was removed from the group,
 260	// information about them (this member may be the bot itself);
 261	//
 262	// optional
 263	LeftChatMember *User `json:"left_chat_member"`
 264	// NewChatTitle is a chat title was changed to this value;
 265	//
 266	// optional
 267	NewChatTitle string `json:"new_chat_title"`
 268	// NewChatPhoto is a chat photo was change to this value;
 269	//
 270	// optional
 271	NewChatPhoto *[]PhotoSize `json:"new_chat_photo"`
 272	// DeleteChatPhoto is a service message: the chat photo was deleted;
 273	//
 274	// optional
 275	DeleteChatPhoto bool `json:"delete_chat_photo"`
 276	// GroupChatCreated is a service message: the group has been created;
 277	//
 278	// optional
 279	GroupChatCreated bool `json:"group_chat_created"`
 280	// SuperGroupChatCreated is a service message: the supergroup has been created.
 281	// This field can't be received in a message coming through updates,
 282	// because bot can't be a member of a supergroup when it is created.
 283	// It can only be found in ReplyToMessage if someone replies to a very first message
 284	// in a directly created supergroup;
 285	//
 286	// optional
 287	SuperGroupChatCreated bool `json:"supergroup_chat_created"`
 288	// ChannelChatCreated is a service message: the channel has been created.
 289	// This field can't be received in a message coming through updates,
 290	// because bot can't be a member of a channel when it is created.
 291	// It can only be found in ReplyToMessage
 292	// if someone replies to a very first message in a channel;
 293	//
 294	// optional
 295	ChannelChatCreated bool `json:"channel_chat_created"`
 296	// MigrateToChatID is the group has been migrated to a supergroup with the specified identifier.
 297	// This number may be greater than 32 bits and some programming languages
 298	// may have difficulty/silent defects in interpreting it.
 299	// But it is smaller than 52 bits, so a signed 64 bit integer
 300	// or double-precision float type are safe for storing this identifier;
 301	//
 302	// optional
 303	MigrateToChatID int64 `json:"migrate_to_chat_id"`
 304	// MigrateFromChatID is the supergroup has been migrated from a group with the specified identifier.
 305	// This number may be greater than 32 bits and some programming languages
 306	// may have difficulty/silent defects in interpreting it.
 307	// But it is smaller than 52 bits, so a signed 64 bit integer
 308	// or double-precision float type are safe for storing this identifier;
 309	//
 310	// optional
 311	MigrateFromChatID int64 `json:"migrate_from_chat_id"`
 312	// PinnedMessage is a specified message was pinned.
 313	// Note that the Message object in this field will not contain further ReplyToMessage
 314	// fields even if it is itself a reply;
 315	//
 316	// optional
 317	PinnedMessage *Message `json:"pinned_message"`
 318	// Invoice message is an invoice for a payment;
 319	//
 320	// optional
 321	Invoice *Invoice `json:"invoice"`
 322	// SuccessfulPayment message is a service message about a successful payment,
 323	// information about the payment;
 324	//
 325	// optional
 326	SuccessfulPayment *SuccessfulPayment `json:"successful_payment"`
 327	// PassportData is a Telegram Passport data;
 328	//
 329	// optional
 330	PassportData *PassportData `json:"passport_data,omitempty"`
 331}
 332
 333// Time converts the message timestamp into a Time.
 334func (m *Message) Time() time.Time {
 335	return time.Unix(int64(m.Date), 0)
 336}
 337
 338// IsCommand returns true if message starts with a "bot_command" entity.
 339func (m *Message) IsCommand() bool {
 340	if m.Entities == nil || len(*m.Entities) == 0 {
 341		return false
 342	}
 343
 344	entity := (*m.Entities)[0]
 345	return entity.Offset == 0 && entity.IsCommand()
 346}
 347
 348// Command checks if the message was a command and if it was, returns the
 349// command. If the Message was not a command, it returns an empty string.
 350//
 351// If the command contains the at name syntax, it is removed. Use
 352// CommandWithAt() if you do not want that.
 353func (m *Message) Command() string {
 354	command := m.CommandWithAt()
 355
 356	if i := strings.Index(command, "@"); i != -1 {
 357		command = command[:i]
 358	}
 359
 360	return command
 361}
 362
 363// CommandWithAt checks if the message was a command and if it was, returns the
 364// command. If the Message was not a command, it returns an empty string.
 365//
 366// If the command contains the at name syntax, it is not removed. Use Command()
 367// if you want that.
 368func (m *Message) CommandWithAt() string {
 369	if !m.IsCommand() {
 370		return ""
 371	}
 372
 373	// IsCommand() checks that the message begins with a bot_command entity
 374	entity := (*m.Entities)[0]
 375	return m.Text[1:entity.Length]
 376}
 377
 378// CommandArguments checks if the message was a command and if it was,
 379// returns all text after the command name. If the Message was not a
 380// command, it returns an empty string.
 381//
 382// Note: The first character after the command name is omitted:
 383// - "/foo bar baz" yields "bar baz", not " bar baz"
 384// - "/foo-bar baz" yields "bar baz", too
 385// Even though the latter is not a command conforming to the spec, the API
 386// marks "/foo" as command entity.
 387func (m *Message) CommandArguments() string {
 388	if !m.IsCommand() {
 389		return ""
 390	}
 391
 392	// IsCommand() checks that the message begins with a bot_command entity
 393	entity := (*m.Entities)[0]
 394	if len(m.Text) == entity.Length {
 395		return "" // The command makes up the whole message
 396	}
 397
 398	return m.Text[entity.Length+1:]
 399}
 400
 401// MessageEntity contains information about data in a Message.
 402type MessageEntity struct {
 403	Type   string `json:"type"`
 404	Offset int    `json:"offset"`
 405	Length int    `json:"length"`
 406	URL    string `json:"url"`  // optional
 407	User   *User  `json:"user"` // optional
 408}
 409
 410// ParseURL attempts to parse a URL contained within a MessageEntity.
 411func (e MessageEntity) ParseURL() (*url.URL, error) {
 412	if e.URL == "" {
 413		return nil, errors.New(ErrBadURL)
 414	}
 415
 416	return url.Parse(e.URL)
 417}
 418
 419// IsMention returns true if the type of the message entity is "mention" (@username).
 420func (e MessageEntity) IsMention() bool {
 421	return e.Type == "mention"
 422}
 423
 424// IsHashtag returns true if the type of the message entity is "hashtag".
 425func (e MessageEntity) IsHashtag() bool {
 426	return e.Type == "hashtag"
 427}
 428
 429// IsCommand returns true if the type of the message entity is "bot_command".
 430func (e MessageEntity) IsCommand() bool {
 431	return e.Type == "bot_command"
 432}
 433
 434// IsUrl returns true if the type of the message entity is "url".
 435func (e MessageEntity) IsUrl() bool {
 436	return e.Type == "url"
 437}
 438
 439// IsEmail returns true if the type of the message entity is "email".
 440func (e MessageEntity) IsEmail() bool {
 441	return e.Type == "email"
 442}
 443
 444// IsBold returns true if the type of the message entity is "bold" (bold text).
 445func (e MessageEntity) IsBold() bool {
 446	return e.Type == "bold"
 447}
 448
 449// IsItalic returns true if the type of the message entity is "italic" (italic text).
 450func (e MessageEntity) IsItalic() bool {
 451	return e.Type == "italic"
 452}
 453
 454// IsCode returns true if the type of the message entity is "code" (monowidth string).
 455func (e MessageEntity) IsCode() bool {
 456	return e.Type == "code"
 457}
 458
 459// IsPre returns true if the type of the message entity is "pre" (monowidth block).
 460func (e MessageEntity) IsPre() bool {
 461	return e.Type == "pre"
 462}
 463
 464// IsTextLink returns true if the type of the message entity is "text_link" (clickable text URL).
 465func (e MessageEntity) IsTextLink() bool {
 466	return e.Type == "text_link"
 467}
 468
 469// PhotoSize contains information about photos.
 470type PhotoSize struct {
 471	// FileID identifier for this file, which can be used to download or reuse the file
 472	FileID string `json:"file_id"`
 473	// Width photo width
 474	Width int `json:"width"`
 475	// Height photo height
 476	Height int `json:"height"`
 477	// FileSize file size
 478	//
 479	// optional
 480	FileSize int `json:"file_size"`
 481}
 482
 483// Audio contains information about audio.
 484type Audio struct {
 485	// FileID is an identifier for this file, which can be used to download or reuse the file
 486	FileID string `json:"file_id"`
 487	// Duration of the audio in seconds as defined by sender
 488	Duration int `json:"duration"`
 489	// Performer of the audio as defined by sender or by audio tags
 490	//
 491	// optional
 492	Performer string `json:"performer"`
 493	// Title of the audio as defined by sender or by audio tags
 494	//
 495	// optional
 496	Title string `json:"title"`
 497	// MimeType of the file as defined by sender
 498	//
 499	// optional
 500	MimeType string `json:"mime_type"`
 501	// FileSize file size
 502	//
 503	// optional
 504	FileSize int `json:"file_size"`
 505}
 506
 507// Document contains information about a document.
 508type Document struct {
 509	// FileID is a identifier for this file, which can be used to download or reuse the file
 510	FileID string `json:"file_id"`
 511	// Thumbnail document thumbnail as defined by sender
 512	//
 513	// optional
 514	Thumbnail *PhotoSize `json:"thumb"`
 515	// FileName original filename as defined by sender
 516	//
 517	// optional
 518	FileName string `json:"file_name"`
 519	// MimeType  of the file as defined by sender
 520	//
 521	// optional
 522	MimeType string `json:"mime_type"`
 523	// FileSize file size
 524	//
 525	// optional
 526	FileSize int `json:"file_size"`
 527}
 528
 529// Sticker contains information about a sticker.
 530type Sticker struct {
 531	// FileUniqueID is an unique identifier for this file,
 532	// which is supposed to be the same over time and for different bots.
 533	// Can't be used to download or reuse the file.
 534	FileUniqueID string `json:"file_unique_id"`
 535	// FileID is an identifier for this file, which can be used to download or reuse the file
 536	FileID string `json:"file_id"`
 537	// Width sticker width
 538	Width int `json:"width"`
 539	// Height sticker height
 540	Height int `json:"height"`
 541	// Thumbnail sticker thumbnail in the .WEBP or .JPG format
 542	//
 543	// optional
 544	Thumbnail *PhotoSize `json:"thumb"`
 545	// Emoji associated with the sticker
 546	//
 547	// optional
 548	Emoji string `json:"emoji"`
 549	// FileSize
 550	//
 551	// optional
 552	FileSize int `json:"file_size"`
 553	// SetName of the sticker set to which the sticker belongs
 554	//
 555	// optional
 556	SetName string `json:"set_name"`
 557	// IsAnimated true, if the sticker is animated
 558	//
 559	// optional
 560	IsAnimated bool `json:"is_animated"`
 561}
 562
 563// StickerSet contains information about an sticker set.
 564type StickerSet struct {
 565	// Name sticker set name
 566	Name string `json:"name"`
 567	// Title sticker set title
 568	Title string `json:"title"`
 569	// IsAnimated true, if the sticker set contains animated stickers
 570	IsAnimated bool `json:"is_animated"`
 571	// ContainsMasks true, if the sticker set contains masks
 572	ContainsMasks bool `json:"contains_masks"`
 573	// Stickers list of all set stickers
 574	Stickers []Sticker `json:"stickers"`
 575}
 576
 577// ChatAnimation contains information about an animation.
 578type ChatAnimation struct {
 579	// FileID odentifier for this file, which can be used to download or reuse the file
 580	FileID string `json:"file_id"`
 581	// Width video width as defined by sender
 582	Width int `json:"width"`
 583	// Height video height as defined by sender
 584	Height int `json:"height"`
 585	// Duration of the video in seconds as defined by sender
 586	Duration int `json:"duration"`
 587	// Thumbnail animation thumbnail as defined by sender
 588	//
 589	// optional
 590	Thumbnail *PhotoSize `json:"thumb"`
 591	// FileName original animation filename as defined by sender
 592	//
 593	// optional
 594	FileName string `json:"file_name"`
 595	// MimeType of the file as defined by sender
 596	//
 597	// optional
 598	MimeType string `json:"mime_type"`
 599	// FileSize file size
 600	//
 601	// optional
 602	FileSize int `json:"file_size"`
 603}
 604
 605// Video contains information about a video.
 606type Video struct {
 607	// FileID identifier for this file, which can be used to download or reuse the file
 608	FileID string `json:"file_id"`
 609	// Width video width as defined by sender
 610	Width int `json:"width"`
 611	// Height video height as defined by sender
 612	Height int `json:"height"`
 613	// Duration of the video in seconds as defined by sender
 614	Duration int `json:"duration"`
 615	// Thumbnail video thumbnail
 616	//
 617	// optional
 618	Thumbnail *PhotoSize `json:"thumb"`
 619	// MimeType of a file as defined by sender
 620	//
 621	// optional
 622	MimeType string `json:"mime_type"`
 623	// FileSize file size
 624	//
 625	// optional
 626	FileSize int `json:"file_size"`
 627}
 628
 629// VideoNote contains information about a video.
 630type VideoNote struct {
 631	// FileID identifier for this file, which can be used to download or reuse the file
 632	FileID string `json:"file_id"`
 633	// Length video width and height (diameter of the video message) as defined by sender
 634	Length int `json:"length"`
 635	// Duration of the video in seconds as defined by sender
 636	Duration int `json:"duration"`
 637	// Thumbnail video thumbnail
 638	//
 639	// optional
 640	Thumbnail *PhotoSize `json:"thumb"`
 641	// FileSize file size
 642	//
 643	// optional
 644	FileSize int `json:"file_size"`
 645}
 646
 647// Voice contains information about a voice.
 648type Voice struct {
 649	// FileID identifier for this file, which can be used to download or reuse the file
 650	FileID string `json:"file_id"`
 651	// Duration of the audio in seconds as defined by sender
 652	Duration int `json:"duration"`
 653	// MimeType of the file as defined by sender
 654	//
 655	// optional
 656	MimeType string `json:"mime_type"`
 657	// FileSize file size
 658	//
 659	// optional
 660	FileSize int `json:"file_size"`
 661}
 662
 663// Contact contains information about a contact.
 664//
 665// Note that LastName and UserID may be empty.
 666type Contact struct {
 667	// PhoneNumber contact's phone number
 668	PhoneNumber string `json:"phone_number"`
 669	// FirstName contact's first name
 670	FirstName string `json:"first_name"`
 671	// LastName contact's last name
 672	//
 673	// optional
 674	LastName string `json:"last_name"`
 675	// UserID contact's user identifier in Telegram
 676	//
 677	// optional
 678	UserID int `json:"user_id"`
 679}
 680
 681// Location contains information about a place.
 682type Location struct {
 683	// Longitude as defined by sender
 684	Longitude float64 `json:"longitude"`
 685	// Latitude as defined by sender
 686	Latitude float64 `json:"latitude"`
 687}
 688
 689// Venue contains information about a venue, including its Location.
 690type Venue struct {
 691	// Location venue location
 692	Location Location `json:"location"`
 693	// Title name of the venue
 694	Title string `json:"title"`
 695	// Address of the venue
 696	Address string `json:"address"`
 697	// FoursquareID foursquare identifier of the venue
 698	//
 699	// optional
 700	FoursquareID string `json:"foursquare_id"`
 701}
 702
 703// UserProfilePhotos contains a set of user profile photos.
 704type UserProfilePhotos struct {
 705	// TotalCount total number of profile pictures the target user has
 706	TotalCount int `json:"total_count"`
 707	// Photos requested profile pictures (in up to 4 sizes each)
 708	Photos [][]PhotoSize `json:"photos"`
 709}
 710
 711// File contains information about a file to download from Telegram.
 712type File struct {
 713	// FileID identifier for this file, which can be used to download or reuse the file
 714	FileID string `json:"file_id"`
 715	// FileSize file size, if known
 716	//
 717	// optional
 718	FileSize int `json:"file_size"`
 719	// FilePath file path
 720	//
 721	// optional
 722	FilePath string `json:"file_path"`
 723}
 724
 725// Link returns a full path to the download URL for a File.
 726//
 727// It requires the Bot Token to create the link.
 728func (f *File) Link(token string) string {
 729	return fmt.Sprintf(FileEndpoint, token, f.FilePath)
 730}
 731
 732// ReplyKeyboardMarkup allows the Bot to set a custom keyboard.
 733type ReplyKeyboardMarkup struct {
 734	// Keyboard is an array of button rows, each represented by an Array of KeyboardButton objects
 735	Keyboard [][]KeyboardButton `json:"keyboard"`
 736	// ResizeKeyboard requests clients to resize the keyboard vertically for optimal fit
 737	// (e.g., make the keyboard smaller if there are just two rows of buttons).
 738	// Defaults to false, in which case the custom keyboard
 739	// is always of the same height as the app's standard keyboard.
 740	//
 741	// optional
 742	ResizeKeyboard bool `json:"resize_keyboard"`
 743	// OneTimeKeyboard requests clients to hide the keyboard as soon as it's been used.
 744	// The keyboard will still be available, but clients will automatically display
 745	// the usual letter-keyboard in the chat – the user can press a special button
 746	// in the input field to see the custom keyboard again.
 747	// Defaults to false.
 748	//
 749	// optional
 750	OneTimeKeyboard bool `json:"one_time_keyboard"`
 751	// Selective use this parameter if you want to show the keyboard to specific users only.
 752	// Targets:
 753	//  1) users that are @mentioned in the text of the Message object;
 754	//  2) if the bot's message is a reply (has Message.ReplyToMessage not nil), sender of the original message.
 755	//
 756	// Example: A user requests to change the bot's language,
 757	// bot replies to the request with a keyboard to select the new language.
 758	// Other users in the group don't see the keyboard.
 759	//
 760	// optional
 761	Selective bool `json:"selective"`
 762}
 763
 764// KeyboardButton is a button within a custom keyboard.
 765type KeyboardButton struct {
 766	// Text of the button. If none of the optional fields are used,
 767	// it will be sent as a message when the button is pressed.
 768	Text string `json:"text"`
 769	// RequestContact if True, the user's phone number will be sent
 770	// as a contact when the button is pressed.
 771	// Available in private chats only.
 772	//
 773	// optional
 774	RequestContact bool `json:"request_contact"`
 775	// RequestLocation if True, the user's current location will be sent when the button is pressed.
 776	// Available in private chats only.
 777	//
 778	// optional
 779	RequestLocation bool `json:"request_location"`
 780}
 781
 782// ReplyKeyboardHide allows the Bot to hide a custom keyboard.
 783type ReplyKeyboardHide struct {
 784	HideKeyboard bool `json:"hide_keyboard"`
 785	Selective    bool `json:"selective"` // optional
 786}
 787
 788// ReplyKeyboardRemove allows the Bot to hide a custom keyboard.
 789type ReplyKeyboardRemove struct {
 790	// RemoveKeyboard requests clients to remove the custom keyboard
 791	// (user will not be able to summon this keyboard;
 792	// if you want to hide the keyboard from sight but keep it accessible,
 793	// use one_time_keyboard in ReplyKeyboardMarkup).
 794	RemoveKeyboard bool `json:"remove_keyboard"`
 795	// Selective use this parameter if you want to remove the keyboard for specific users only.
 796	// Targets:
 797	//  1) users that are @mentioned in the text of the Message object;
 798	//  2) if the bot's message is a reply (has Message.ReplyToMessage not nil), sender of the original message.
 799	//
 800	// Example: A user votes in a poll, bot returns confirmation message
 801	// in reply to the vote and removes the keyboard for that user,
 802	// while still showing the keyboard with poll options to users who haven't voted yet.
 803	//
 804	// optional
 805	Selective bool `json:"selective"`
 806}
 807
 808// InlineKeyboardMarkup is a custom keyboard presented for an inline bot.
 809type InlineKeyboardMarkup struct {
 810	// InlineKeyboard array of button rows, each represented by an Array of InlineKeyboardButton objects
 811	InlineKeyboard [][]InlineKeyboardButton `json:"inline_keyboard"`
 812}
 813
 814// InlineKeyboardButton is a button within a custom keyboard for
 815// inline query responses.
 816//
 817// Note that some values are references as even an empty string
 818// will change behavior.
 819//
 820// CallbackGame, if set, MUST be first button in first row.
 821type InlineKeyboardButton struct {
 822	// Text label text on the button
 823	Text string `json:"text"`
 824	// URL HTTP or tg:// url to be opened when button is pressed.
 825	//
 826	// optional
 827	URL *string `json:"url,omitempty"`
 828	// CallbackData data to be sent in a callback query to the bot when button is pressed, 1-64 bytes.
 829	//
 830	// optional
 831	CallbackData *string `json:"callback_data,omitempty"`
 832	// SwitchInlineQuery if set, pressing the button will prompt the user to select one of their chats,
 833	// open that chat and insert the bot's username and the specified inline query in the input field.
 834	// Can be empty, in which case just the bot's username will be inserted.
 835	//
 836	// This offers an easy way for users to start using your bot
 837	// in inline mode when they are currently in a private chat with it.
 838	// Especially useful when combined with switch_pm… actions – in this case
 839	// the user will be automatically returned to the chat they switched from,
 840	// skipping the chat selection screen.
 841	//
 842	// optional
 843	SwitchInlineQuery *string `json:"switch_inline_query,omitempty"`
 844	// SwitchInlineQueryCurrentChat if set, pressing the button will insert the bot's username
 845	// and the specified inline query in the current chat's input field.
 846	// Can be empty, in which case only the bot's username will be inserted.
 847	//
 848	// This offers a quick way for the user to open your bot in inline mode
 849	// in the same chat – good for selecting something from multiple options.
 850	//
 851	// optional
 852	SwitchInlineQueryCurrentChat *string `json:"switch_inline_query_current_chat,omitempty"`
 853	// CallbackGame description of the game that will be launched when the user presses the button.
 854	//
 855	// optional
 856	CallbackGame *CallbackGame `json:"callback_game,omitempty"`
 857	// Pay specify True, to send a Pay button.
 858	//
 859	// NOTE: This type of button must always be the first button in the first row.
 860	//
 861	// optional
 862	Pay bool `json:"pay,omitempty"`
 863}
 864
 865// CallbackQuery is data sent when a keyboard button with callback data
 866// is clicked.
 867type CallbackQuery struct {
 868	ID              string   `json:"id"`
 869	From            *User    `json:"from"`
 870	Message         *Message `json:"message"`           // optional
 871	InlineMessageID string   `json:"inline_message_id"` // optional
 872	ChatInstance    string   `json:"chat_instance"`
 873	Data            string   `json:"data"`            // optional
 874	GameShortName   string   `json:"game_short_name"` // optional
 875}
 876
 877// ForceReply allows the Bot to have users directly reply to it without
 878// additional interaction.
 879type ForceReply struct {
 880	ForceReply bool `json:"force_reply"`
 881	Selective  bool `json:"selective"` // optional
 882}
 883
 884// ChatMember is information about a member in a chat.
 885type ChatMember struct {
 886	User                  *User  `json:"user"`
 887	Status                string `json:"status"`
 888	CustomTitle           string `json:"custom_title,omitempty"`              // optional
 889	UntilDate             int64  `json:"until_date,omitempty"`                // optional
 890	CanBeEdited           bool   `json:"can_be_edited,omitempty"`             // optional
 891	CanChangeInfo         bool   `json:"can_change_info,omitempty"`           // optional
 892	CanPostMessages       bool   `json:"can_post_messages,omitempty"`         // optional
 893	CanEditMessages       bool   `json:"can_edit_messages,omitempty"`         // optional
 894	CanDeleteMessages     bool   `json:"can_delete_messages,omitempty"`       // optional
 895	CanInviteUsers        bool   `json:"can_invite_users,omitempty"`          // optional
 896	CanRestrictMembers    bool   `json:"can_restrict_members,omitempty"`      // optional
 897	CanPinMessages        bool   `json:"can_pin_messages,omitempty"`          // optional
 898	CanPromoteMembers     bool   `json:"can_promote_members,omitempty"`       // optional
 899	CanSendMessages       bool   `json:"can_send_messages,omitempty"`         // optional
 900	CanSendMediaMessages  bool   `json:"can_send_media_messages,omitempty"`   // optional
 901	CanSendOtherMessages  bool   `json:"can_send_other_messages,omitempty"`   // optional
 902	CanAddWebPagePreviews bool   `json:"can_add_web_page_previews,omitempty"` // optional
 903}
 904
 905// IsCreator returns if the ChatMember was the creator of the chat.
 906func (chat ChatMember) IsCreator() bool { return chat.Status == "creator" }
 907
 908// IsAdministrator returns if the ChatMember is a chat administrator.
 909func (chat ChatMember) IsAdministrator() bool { return chat.Status == "administrator" }
 910
 911// IsMember returns if the ChatMember is a current member of the chat.
 912func (chat ChatMember) IsMember() bool { return chat.Status == "member" }
 913
 914// HasLeft returns if the ChatMember left the chat.
 915func (chat ChatMember) HasLeft() bool { return chat.Status == "left" }
 916
 917// WasKicked returns if the ChatMember was kicked from the chat.
 918func (chat ChatMember) WasKicked() bool { return chat.Status == "kicked" }
 919
 920// Game is a game within Telegram.
 921type Game struct {
 922	Title        string          `json:"title"`
 923	Description  string          `json:"description"`
 924	Photo        []PhotoSize     `json:"photo"`
 925	Text         string          `json:"text"`
 926	TextEntities []MessageEntity `json:"text_entities"`
 927	Animation    Animation       `json:"animation"`
 928}
 929
 930// Animation is a GIF animation demonstrating the game.
 931type Animation struct {
 932	FileID   string    `json:"file_id"`
 933	Thumb    PhotoSize `json:"thumb"`
 934	FileName string    `json:"file_name"`
 935	MimeType string    `json:"mime_type"`
 936	FileSize int       `json:"file_size"`
 937}
 938
 939// GameHighScore is a user's score and position on the leaderboard.
 940type GameHighScore struct {
 941	Position int  `json:"position"`
 942	User     User `json:"user"`
 943	Score    int  `json:"score"`
 944}
 945
 946// CallbackGame is for starting a game in an inline keyboard button.
 947type CallbackGame struct{}
 948
 949// WebhookInfo is information about a currently set webhook.
 950type WebhookInfo struct {
 951	URL                  string `json:"url"`
 952	HasCustomCertificate bool   `json:"has_custom_certificate"`
 953	PendingUpdateCount   int    `json:"pending_update_count"`
 954	LastErrorDate        int    `json:"last_error_date"`    // optional
 955	LastErrorMessage     string `json:"last_error_message"` // optional
 956	MaxConnections       int    `json:"max_connections"`    // optional
 957}
 958
 959// IsSet returns true if a webhook is currently set.
 960func (info WebhookInfo) IsSet() bool {
 961	return info.URL != ""
 962}
 963
 964// InputMediaPhoto contains a photo for displaying as part of a media group.
 965type InputMediaPhoto struct {
 966	Type      string `json:"type"`
 967	Media     string `json:"media"`
 968	Caption   string `json:"caption"`
 969	ParseMode string `json:"parse_mode"`
 970}
 971
 972// InputMediaVideo contains a video for displaying as part of a media group.
 973type InputMediaVideo struct {
 974	Type  string `json:"type"`
 975	Media string `json:"media"`
 976	// thumb intentionally missing as it is not currently compatible
 977	Caption           string `json:"caption"`
 978	ParseMode         string `json:"parse_mode"`
 979	Width             int    `json:"width"`
 980	Height            int    `json:"height"`
 981	Duration          int    `json:"duration"`
 982	SupportsStreaming bool   `json:"supports_streaming"`
 983}
 984
 985// InlineQuery is a Query from Telegram for an inline request.
 986type InlineQuery struct {
 987	ID       string    `json:"id"`
 988	From     *User     `json:"from"`
 989	Location *Location `json:"location"` // optional
 990	Query    string    `json:"query"`
 991	Offset   string    `json:"offset"`
 992}
 993
 994// InlineQueryResultArticle is an inline query response article.
 995type InlineQueryResultArticle struct {
 996	Type                string                `json:"type"`                            // required
 997	ID                  string                `json:"id"`                              // required
 998	Title               string                `json:"title"`                           // required
 999	InputMessageContent interface{}           `json:"input_message_content,omitempty"` // required
1000	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1001	URL                 string                `json:"url"`
1002	HideURL             bool                  `json:"hide_url"`
1003	Description         string                `json:"description"`
1004	ThumbURL            string                `json:"thumb_url"`
1005	ThumbWidth          int                   `json:"thumb_width"`
1006	ThumbHeight         int                   `json:"thumb_height"`
1007}
1008
1009// InlineQueryResultPhoto is an inline query response photo.
1010type InlineQueryResultPhoto struct {
1011	Type                string                `json:"type"`      // required
1012	ID                  string                `json:"id"`        // required
1013	URL                 string                `json:"photo_url"` // required
1014	MimeType            string                `json:"mime_type"`
1015	Width               int                   `json:"photo_width"`
1016	Height              int                   `json:"photo_height"`
1017	ThumbURL            string                `json:"thumb_url"`
1018	Title               string                `json:"title"`
1019	Description         string                `json:"description"`
1020	Caption             string                `json:"caption"`
1021	ParseMode           string                `json:"parse_mode"`
1022	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1023	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1024}
1025
1026// InlineQueryResultCachedPhoto is an inline query response with cached photo.
1027type InlineQueryResultCachedPhoto struct {
1028	Type                string                `json:"type"`          // required
1029	ID                  string                `json:"id"`            // required
1030	PhotoID             string                `json:"photo_file_id"` // required
1031	Title               string                `json:"title"`
1032	Description         string                `json:"description"`
1033	Caption             string                `json:"caption"`
1034	ParseMode           string                `json:"parse_mode"`
1035	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1036	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1037}
1038
1039// InlineQueryResultGIF is an inline query response GIF.
1040type InlineQueryResultGIF struct {
1041	Type                string                `json:"type"`      // required
1042	ID                  string                `json:"id"`        // required
1043	URL                 string                `json:"gif_url"`   // required
1044	ThumbURL            string                `json:"thumb_url"` // required
1045	Width               int                   `json:"gif_width,omitempty"`
1046	Height              int                   `json:"gif_height,omitempty"`
1047	Duration            int                   `json:"gif_duration,omitempty"`
1048	Title               string                `json:"title,omitempty"`
1049	Caption             string                `json:"caption,omitempty"`
1050	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1051	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1052}
1053
1054// InlineQueryResultCachedGIF is an inline query response with cached gif.
1055type InlineQueryResultCachedGIF struct {
1056	Type                string                `json:"type"`        // required
1057	ID                  string                `json:"id"`          // required
1058	GifID               string                `json:"gif_file_id"` // required
1059	Title               string                `json:"title"`
1060	Caption             string                `json:"caption"`
1061	ParseMode           string                `json:"parse_mode"`
1062	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1063	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1064}
1065
1066// InlineQueryResultMPEG4GIF is an inline query response MPEG4 GIF.
1067type InlineQueryResultMPEG4GIF struct {
1068	Type                string                `json:"type"`      // required
1069	ID                  string                `json:"id"`        // required
1070	URL                 string                `json:"mpeg4_url"` // required
1071	Width               int                   `json:"mpeg4_width"`
1072	Height              int                   `json:"mpeg4_height"`
1073	Duration            int                   `json:"mpeg4_duration"`
1074	ThumbURL            string                `json:"thumb_url"`
1075	Title               string                `json:"title"`
1076	Caption             string                `json:"caption"`
1077	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1078	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1079}
1080
1081// InlineQueryResultCachedMpeg4Gif is an inline query response with cached
1082// H.264/MPEG-4 AVC video without sound gif.
1083type InlineQueryResultCachedMpeg4Gif struct {
1084	Type                string                `json:"type"`          // required
1085	ID                  string                `json:"id"`            // required
1086	MGifID              string                `json:"mpeg4_file_id"` // required
1087	Title               string                `json:"title"`
1088	Caption             string                `json:"caption"`
1089	ParseMode           string                `json:"parse_mode"`
1090	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1091	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1092}
1093
1094// InlineQueryResultVideo is an inline query response video.
1095type InlineQueryResultVideo struct {
1096	Type                string                `json:"type"`      // required
1097	ID                  string                `json:"id"`        // required
1098	URL                 string                `json:"video_url"` // required
1099	MimeType            string                `json:"mime_type"` // required
1100	ThumbURL            string                `json:"thumb_url"`
1101	Title               string                `json:"title"`
1102	Caption             string                `json:"caption"`
1103	Width               int                   `json:"video_width"`
1104	Height              int                   `json:"video_height"`
1105	Duration            int                   `json:"video_duration"`
1106	Description         string                `json:"description"`
1107	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1108	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1109}
1110
1111// InlineQueryResultCachedVideo is an inline query response with cached video.
1112type InlineQueryResultCachedVideo struct {
1113	Type                string                `json:"type"`          // required
1114	ID                  string                `json:"id"`            // required
1115	VideoID             string                `json:"video_file_id"` // required
1116	Title               string                `json:"title"`         // required
1117	Description         string                `json:"description"`
1118	Caption             string                `json:"caption"`
1119	ParseMode           string                `json:"parse_mode"`
1120	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1121	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1122}
1123
1124// InlineQueryResultCachedSticker is an inline query response with cached sticker.
1125type InlineQueryResultCachedSticker struct {
1126	Type                string                `json:"type"`            // required
1127	ID                  string                `json:"id"`              // required
1128	StickerID           string                `json:"sticker_file_id"` // required
1129	Title               string                `json:"title"`           // required
1130	ParseMode           string                `json:"parse_mode"`
1131	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1132	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1133}
1134
1135// InlineQueryResultAudio is an inline query response audio.
1136type InlineQueryResultAudio struct {
1137	Type                string                `json:"type"`      // required
1138	ID                  string                `json:"id"`        // required
1139	URL                 string                `json:"audio_url"` // required
1140	Title               string                `json:"title"`     // required
1141	Caption             string                `json:"caption"`
1142	Performer           string                `json:"performer"`
1143	Duration            int                   `json:"audio_duration"`
1144	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1145	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1146}
1147
1148// InlineQueryResultCachedAudio is an inline query response with cached audio.
1149type InlineQueryResultCachedAudio struct {
1150	Type                string                `json:"type"`          // required
1151	ID                  string                `json:"id"`            // required
1152	AudioID             string                `json:"audio_file_id"` // required
1153	Caption             string                `json:"caption"`
1154	ParseMode           string                `json:"parse_mode"`
1155	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1156	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1157}
1158
1159// InlineQueryResultVoice is an inline query response voice.
1160type InlineQueryResultVoice struct {
1161	Type                string                `json:"type"`      // required
1162	ID                  string                `json:"id"`        // required
1163	URL                 string                `json:"voice_url"` // required
1164	Title               string                `json:"title"`     // required
1165	Caption             string                `json:"caption"`
1166	Duration            int                   `json:"voice_duration"`
1167	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1168	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1169}
1170
1171// InlineQueryResultCachedVoice is an inline query response with cached voice.
1172type InlineQueryResultCachedVoice struct {
1173	Type                string                `json:"type"`          // required
1174	ID                  string                `json:"id"`            // required
1175	VoiceID             string                `json:"voice_file_id"` // required
1176	Title               string                `json:"title"`         // required
1177	Caption             string                `json:"caption"`
1178	ParseMode           string                `json:"parse_mode"`
1179	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1180	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1181}
1182
1183// InlineQueryResultDocument is an inline query response document.
1184type InlineQueryResultDocument struct {
1185	Type                string                `json:"type"`  // required
1186	ID                  string                `json:"id"`    // required
1187	Title               string                `json:"title"` // required
1188	Caption             string                `json:"caption"`
1189	URL                 string                `json:"document_url"` // required
1190	MimeType            string                `json:"mime_type"`    // required
1191	Description         string                `json:"description"`
1192	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1193	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1194	ThumbURL            string                `json:"thumb_url"`
1195	ThumbWidth          int                   `json:"thumb_width"`
1196	ThumbHeight         int                   `json:"thumb_height"`
1197}
1198
1199// InlineQueryResultCachedDocument is an inline query response with cached document.
1200type InlineQueryResultCachedDocument struct {
1201	Type                string                `json:"type"`             // required
1202	ID                  string                `json:"id"`               // required
1203	DocumentID          string                `json:"document_file_id"` // required
1204	Title               string                `json:"title"`            // required
1205	Caption             string                `json:"caption"`
1206	Description         string                `json:"description"`
1207	ParseMode           string                `json:"parse_mode"`
1208	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1209	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1210}
1211
1212// InlineQueryResultLocation is an inline query response location.
1213type InlineQueryResultLocation struct {
1214	Type                string                `json:"type"`      // required
1215	ID                  string                `json:"id"`        // required
1216	Latitude            float64               `json:"latitude"`  // required
1217	Longitude           float64               `json:"longitude"` // required
1218	Title               string                `json:"title"`     // required
1219	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1220	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1221	ThumbURL            string                `json:"thumb_url"`
1222	ThumbWidth          int                   `json:"thumb_width"`
1223	ThumbHeight         int                   `json:"thumb_height"`
1224}
1225
1226// InlineQueryResultVenue is an inline query response venue.
1227type InlineQueryResultVenue struct {
1228	Type                string                `json:"type"`      // required
1229	ID                  string                `json:"id"`        // required
1230	Latitude            float64               `json:"latitude"`  // required
1231	Longitude           float64               `json:"longitude"` // required
1232	Title               string                `json:"title"`     // required
1233	Address             string                `json:"address"`   // required
1234	FoursquareID        string                `json:"foursquare_id"`
1235	FoursquareType      string                `json:"foursquare_type"`
1236	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1237	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1238	ThumbURL            string                `json:"thumb_url"`
1239	ThumbWidth          int                   `json:"thumb_width"`
1240	ThumbHeight         int                   `json:"thumb_height"`
1241}
1242
1243// InlineQueryResultGame is an inline query response game.
1244type InlineQueryResultGame struct {
1245	Type          string                `json:"type"`
1246	ID            string                `json:"id"`
1247	GameShortName string                `json:"game_short_name"`
1248	ReplyMarkup   *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1249}
1250
1251// ChosenInlineResult is an inline query result chosen by a User
1252type ChosenInlineResult struct {
1253	ResultID        string    `json:"result_id"`
1254	From            *User     `json:"from"`
1255	Location        *Location `json:"location"`
1256	InlineMessageID string    `json:"inline_message_id"`
1257	Query           string    `json:"query"`
1258}
1259
1260// InputTextMessageContent contains text for displaying
1261// as an inline query result.
1262type InputTextMessageContent struct {
1263	Text                  string `json:"message_text"`
1264	ParseMode             string `json:"parse_mode"`
1265	DisableWebPagePreview bool   `json:"disable_web_page_preview"`
1266}
1267
1268// InputLocationMessageContent contains a location for displaying
1269// as an inline query result.
1270type InputLocationMessageContent struct {
1271	Latitude  float64 `json:"latitude"`
1272	Longitude float64 `json:"longitude"`
1273}
1274
1275// InputVenueMessageContent contains a venue for displaying
1276// as an inline query result.
1277type InputVenueMessageContent struct {
1278	Latitude     float64 `json:"latitude"`
1279	Longitude    float64 `json:"longitude"`
1280	Title        string  `json:"title"`
1281	Address      string  `json:"address"`
1282	FoursquareID string  `json:"foursquare_id"`
1283}
1284
1285// InputContactMessageContent contains a contact for displaying
1286// as an inline query result.
1287type InputContactMessageContent struct {
1288	PhoneNumber string `json:"phone_number"`
1289	FirstName   string `json:"first_name"`
1290	LastName    string `json:"last_name"`
1291}
1292
1293// Invoice contains basic information about an invoice.
1294type Invoice struct {
1295	Title          string `json:"title"`
1296	Description    string `json:"description"`
1297	StartParameter string `json:"start_parameter"`
1298	Currency       string `json:"currency"`
1299	TotalAmount    int    `json:"total_amount"`
1300}
1301
1302// LabeledPrice represents a portion of the price for goods or services.
1303type LabeledPrice struct {
1304	Label  string `json:"label"`
1305	Amount int    `json:"amount"`
1306}
1307
1308// ShippingAddress represents a shipping address.
1309type ShippingAddress struct {
1310	CountryCode string `json:"country_code"`
1311	State       string `json:"state"`
1312	City        string `json:"city"`
1313	StreetLine1 string `json:"street_line1"`
1314	StreetLine2 string `json:"street_line2"`
1315	PostCode    string `json:"post_code"`
1316}
1317
1318// OrderInfo represents information about an order.
1319type OrderInfo struct {
1320	Name            string           `json:"name,omitempty"`
1321	PhoneNumber     string           `json:"phone_number,omitempty"`
1322	Email           string           `json:"email,omitempty"`
1323	ShippingAddress *ShippingAddress `json:"shipping_address,omitempty"`
1324}
1325
1326// ShippingOption represents one shipping option.
1327type ShippingOption struct {
1328	ID     string          `json:"id"`
1329	Title  string          `json:"title"`
1330	Prices *[]LabeledPrice `json:"prices"`
1331}
1332
1333// SuccessfulPayment contains basic information about a successful payment.
1334type SuccessfulPayment struct {
1335	Currency                string     `json:"currency"`
1336	TotalAmount             int        `json:"total_amount"`
1337	InvoicePayload          string     `json:"invoice_payload"`
1338	ShippingOptionID        string     `json:"shipping_option_id,omitempty"`
1339	OrderInfo               *OrderInfo `json:"order_info,omitempty"`
1340	TelegramPaymentChargeID string     `json:"telegram_payment_charge_id"`
1341	ProviderPaymentChargeID string     `json:"provider_payment_charge_id"`
1342}
1343
1344// ShippingQuery contains information about an incoming shipping query.
1345type ShippingQuery struct {
1346	ID              string           `json:"id"`
1347	From            *User            `json:"from"`
1348	InvoicePayload  string           `json:"invoice_payload"`
1349	ShippingAddress *ShippingAddress `json:"shipping_address"`
1350}
1351
1352// PreCheckoutQuery contains information about an incoming pre-checkout query.
1353type PreCheckoutQuery struct {
1354	ID               string     `json:"id"`
1355	From             *User      `json:"from"`
1356	Currency         string     `json:"currency"`
1357	TotalAmount      int        `json:"total_amount"`
1358	InvoicePayload   string     `json:"invoice_payload"`
1359	ShippingOptionID string     `json:"shipping_option_id,omitempty"`
1360	OrderInfo        *OrderInfo `json:"order_info,omitempty"`
1361}
1362
1363// Error is an error containing extra information returned by the Telegram API.
1364type Error struct {
1365	Code    int
1366	Message string
1367	ResponseParameters
1368}
1369
1370func (e Error) Error() string {
1371	return e.Message
1372}
1373
1374// BotCommand represents a bot command.
1375type BotCommand struct {
1376	Command     string `json:"command"`
1377	Description string `json:"description"`
1378}