all repos — telegram-bot-api @ 5875a46cdedea21de70ec6f5b4d4825bb1fe6f6e

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 unique identifier for this query
 869	ID string `json:"id"`
 870	// From sender
 871	From *User `json:"from"`
 872	// Message with the callback button that originated the query.
 873	// Note that message content and message date will not be available if the message is too old.
 874	//
 875	// optional
 876	Message *Message `json:"message"`
 877	// InlineMessageID identifier of the message sent via the bot in inline mode, that originated the query.
 878	//
 879	// optional
 880	//
 881	InlineMessageID string `json:"inline_message_id"`
 882	// ChatInstance global identifier, uniquely corresponding to the chat to which
 883	// the message with the callback button was sent. Useful for high scores in games.
 884	//
 885	ChatInstance string `json:"chat_instance"`
 886	// Data associated with the callback button. Be aware that
 887	// a bad client can send arbitrary data in this field.
 888	//
 889	// optional
 890	Data string `json:"data"`
 891	// GameShortName short name of a Game to be returned, serves as the unique identifier for the game.
 892	//
 893	// optional
 894	GameShortName string `json:"game_short_name"`
 895}
 896
 897// ForceReply allows the Bot to have users directly reply to it without
 898// additional interaction.
 899type ForceReply struct {
 900	// ForceReply shows reply interface to the user,
 901	// as if they manually selected the bot's message and tapped 'Reply'.
 902	ForceReply bool `json:"force_reply"`
 903	// Selective use this parameter if you want to force reply from specific users only.
 904	// Targets:
 905	//  1) users that are @mentioned in the text of the Message object;
 906	//  2) if the bot's message is a reply (has Message.ReplyToMessage not nil), sender of the original message.
 907	//
 908	// optional
 909	Selective bool `json:"selective"`
 910}
 911
 912// ChatMember is information about a member in a chat.
 913type ChatMember struct {
 914	// User information about the user
 915	User *User `json:"user"`
 916	// Status the member's status in the chat.
 917	// Can be
 918	//  “creator”,
 919	//  “administrator”,
 920	//  “member”,
 921	//  “restricted”,
 922	//  “left” or
 923	//  “kicked”
 924	Status string `json:"status"`
 925	// CustomTitle owner and administrators only. Custom title for this user
 926	//
 927	// optional
 928	CustomTitle string `json:"custom_title,omitempty"`
 929	// UntilDate restricted and kicked only.
 930	// Date when restrictions will be lifted for this user;
 931	// unix time.
 932	//
 933	// optional
 934	UntilDate int64 `json:"until_date,omitempty"`
 935	// CanBeEdited administrators only.
 936	// True, if the bot is allowed to edit administrator privileges of that user.
 937	//
 938	// optional
 939	CanBeEdited bool `json:"can_be_edited,omitempty"`
 940	// CanChangeInfo administrators and restricted only.
 941	// True, if the user is allowed to change the chat title, photo and other settings.
 942	//
 943	// optional
 944	CanChangeInfo bool `json:"can_change_info,omitempty"`
 945	// CanChangeInfo administrators only.
 946	// True, if the administrator can post in the channel;
 947	// channels only.
 948	//
 949	// optional
 950	CanPostMessages bool `json:"can_post_messages,omitempty"`
 951	// CanEditMessages administrators only.
 952	// True, if the administrator can edit messages of other users and can pin messages;
 953	// channels only.
 954	//
 955	// optional
 956	CanEditMessages bool `json:"can_edit_messages,omitempty"`
 957	// CanDeleteMessages administrators only.
 958	// True, if the administrator can delete messages of other users.
 959	//
 960	// optional
 961	CanDeleteMessages bool `json:"can_delete_messages,omitempty"`
 962	// CanInviteUsers administrators and restricted only.
 963	// True, if the user is allowed to invite new users to the chat.
 964	//
 965	// optional
 966	CanInviteUsers bool `json:"can_invite_users,omitempty"`
 967	// CanRestrictMembers administrators only.
 968	// True, if the administrator can restrict, ban or unban chat members.
 969	//
 970	// optional
 971	CanRestrictMembers bool `json:"can_restrict_members,omitempty"`
 972	// CanPinMessages
 973	//
 974	// optional
 975	CanPinMessages bool `json:"can_pin_messages,omitempty"`
 976	// CanPromoteMembers administrators only.
 977	// True, if the administrator can add new administrators
 978	// with a subset of their own privileges or demote administrators that he has promoted,
 979	// directly or indirectly (promoted by administrators that were appointed by the user).
 980	//
 981	// optional
 982	CanPromoteMembers bool `json:"can_promote_members,omitempty"`
 983	// CanSendMessages
 984	//
 985	// optional
 986	CanSendMessages bool `json:"can_send_messages,omitempty"`
 987	// CanSendMediaMessages restricted only.
 988	// True, if the user is allowed to send text messages, contacts, locations and venues
 989	//
 990	// optional
 991	CanSendMediaMessages bool `json:"can_send_media_messages,omitempty"`
 992	// CanSendOtherMessages restricted only.
 993	// True, if the user is allowed to send audios, documents,
 994	// photos, videos, video notes and voice notes.
 995	//
 996	// optional
 997	CanSendOtherMessages bool `json:"can_send_other_messages,omitempty"`
 998	// CanAddWebPagePreviews restricted only.
 999	// True, if the user is allowed to add web page previews to their messages.
1000	//
1001	// optional
1002	CanAddWebPagePreviews bool `json:"can_add_web_page_previews,omitempty"`
1003}
1004
1005// IsCreator returns if the ChatMember was the creator of the chat.
1006func (chat ChatMember) IsCreator() bool { return chat.Status == "creator" }
1007
1008// IsAdministrator returns if the ChatMember is a chat administrator.
1009func (chat ChatMember) IsAdministrator() bool { return chat.Status == "administrator" }
1010
1011// IsMember returns if the ChatMember is a current member of the chat.
1012func (chat ChatMember) IsMember() bool { return chat.Status == "member" }
1013
1014// HasLeft returns if the ChatMember left the chat.
1015func (chat ChatMember) HasLeft() bool { return chat.Status == "left" }
1016
1017// WasKicked returns if the ChatMember was kicked from the chat.
1018func (chat ChatMember) WasKicked() bool { return chat.Status == "kicked" }
1019
1020// Game is a game within Telegram.
1021type Game struct {
1022	// Title of the game
1023	Title string `json:"title"`
1024	// Description of the game
1025	Description string `json:"description"`
1026	// Photo that will be displayed in the game message in chats.
1027	Photo []PhotoSize `json:"photo"`
1028	// Text a brief description of the game or high scores included in the game message.
1029	// Can be automatically edited to include current high scores for the game
1030	// when the bot calls setGameScore, or manually edited using editMessageText. 0-4096 characters.
1031	//
1032	// optional
1033	Text string `json:"text"`
1034	// TextEntities special entities that appear in text, such as usernames, URLs, bot commands, etc.
1035	//
1036	// optional
1037	TextEntities []MessageEntity `json:"text_entities"`
1038	// Animation animation that will be displayed in the game message in chats.
1039	// Upload via BotFather (https://t.me/botfather).
1040	//
1041	// optional
1042	Animation Animation `json:"animation"`
1043}
1044
1045// Animation is a GIF animation demonstrating the game.
1046type Animation struct {
1047	FileID   string    `json:"file_id"`
1048	Thumb    PhotoSize `json:"thumb"`
1049	FileName string    `json:"file_name"`
1050	MimeType string    `json:"mime_type"`
1051	FileSize int       `json:"file_size"`
1052}
1053
1054// GameHighScore is a user's score and position on the leaderboard.
1055type GameHighScore struct {
1056	Position int  `json:"position"`
1057	User     User `json:"user"`
1058	Score    int  `json:"score"`
1059}
1060
1061// CallbackGame is for starting a game in an inline keyboard button.
1062type CallbackGame struct{}
1063
1064// WebhookInfo is information about a currently set webhook.
1065type WebhookInfo struct {
1066	URL                  string `json:"url"`
1067	HasCustomCertificate bool   `json:"has_custom_certificate"`
1068	PendingUpdateCount   int    `json:"pending_update_count"`
1069	LastErrorDate        int    `json:"last_error_date"`    // optional
1070	LastErrorMessage     string `json:"last_error_message"` // optional
1071	MaxConnections       int    `json:"max_connections"`    // optional
1072}
1073
1074// IsSet returns true if a webhook is currently set.
1075func (info WebhookInfo) IsSet() bool {
1076	return info.URL != ""
1077}
1078
1079// InputMediaPhoto contains a photo for displaying as part of a media group.
1080type InputMediaPhoto struct {
1081	Type      string `json:"type"`
1082	Media     string `json:"media"`
1083	Caption   string `json:"caption"`
1084	ParseMode string `json:"parse_mode"`
1085}
1086
1087// InputMediaVideo contains a video for displaying as part of a media group.
1088type InputMediaVideo struct {
1089	Type  string `json:"type"`
1090	Media string `json:"media"`
1091	// thumb intentionally missing as it is not currently compatible
1092	Caption           string `json:"caption"`
1093	ParseMode         string `json:"parse_mode"`
1094	Width             int    `json:"width"`
1095	Height            int    `json:"height"`
1096	Duration          int    `json:"duration"`
1097	SupportsStreaming bool   `json:"supports_streaming"`
1098}
1099
1100// InlineQuery is a Query from Telegram for an inline request.
1101type InlineQuery struct {
1102	ID       string    `json:"id"`
1103	From     *User     `json:"from"`
1104	Location *Location `json:"location"` // optional
1105	Query    string    `json:"query"`
1106	Offset   string    `json:"offset"`
1107}
1108
1109// InlineQueryResultArticle is an inline query response article.
1110type InlineQueryResultArticle struct {
1111	Type                string                `json:"type"`                            // required
1112	ID                  string                `json:"id"`                              // required
1113	Title               string                `json:"title"`                           // required
1114	InputMessageContent interface{}           `json:"input_message_content,omitempty"` // required
1115	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1116	URL                 string                `json:"url"`
1117	HideURL             bool                  `json:"hide_url"`
1118	Description         string                `json:"description"`
1119	ThumbURL            string                `json:"thumb_url"`
1120	ThumbWidth          int                   `json:"thumb_width"`
1121	ThumbHeight         int                   `json:"thumb_height"`
1122}
1123
1124// InlineQueryResultPhoto is an inline query response photo.
1125type InlineQueryResultPhoto struct {
1126	Type                string                `json:"type"`      // required
1127	ID                  string                `json:"id"`        // required
1128	URL                 string                `json:"photo_url"` // required
1129	MimeType            string                `json:"mime_type"`
1130	Width               int                   `json:"photo_width"`
1131	Height              int                   `json:"photo_height"`
1132	ThumbURL            string                `json:"thumb_url"`
1133	Title               string                `json:"title"`
1134	Description         string                `json:"description"`
1135	Caption             string                `json:"caption"`
1136	ParseMode           string                `json:"parse_mode"`
1137	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1138	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1139}
1140
1141// InlineQueryResultCachedPhoto is an inline query response with cached photo.
1142type InlineQueryResultCachedPhoto struct {
1143	Type                string                `json:"type"`          // required
1144	ID                  string                `json:"id"`            // required
1145	PhotoID             string                `json:"photo_file_id"` // required
1146	Title               string                `json:"title"`
1147	Description         string                `json:"description"`
1148	Caption             string                `json:"caption"`
1149	ParseMode           string                `json:"parse_mode"`
1150	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1151	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1152}
1153
1154// InlineQueryResultGIF is an inline query response GIF.
1155type InlineQueryResultGIF struct {
1156	Type                string                `json:"type"`      // required
1157	ID                  string                `json:"id"`        // required
1158	URL                 string                `json:"gif_url"`   // required
1159	ThumbURL            string                `json:"thumb_url"` // required
1160	Width               int                   `json:"gif_width,omitempty"`
1161	Height              int                   `json:"gif_height,omitempty"`
1162	Duration            int                   `json:"gif_duration,omitempty"`
1163	Title               string                `json:"title,omitempty"`
1164	Caption             string                `json:"caption,omitempty"`
1165	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1166	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1167}
1168
1169// InlineQueryResultCachedGIF is an inline query response with cached gif.
1170type InlineQueryResultCachedGIF struct {
1171	Type                string                `json:"type"`        // required
1172	ID                  string                `json:"id"`          // required
1173	GifID               string                `json:"gif_file_id"` // required
1174	Title               string                `json:"title"`
1175	Caption             string                `json:"caption"`
1176	ParseMode           string                `json:"parse_mode"`
1177	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1178	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1179}
1180
1181// InlineQueryResultMPEG4GIF is an inline query response MPEG4 GIF.
1182type InlineQueryResultMPEG4GIF struct {
1183	Type                string                `json:"type"`      // required
1184	ID                  string                `json:"id"`        // required
1185	URL                 string                `json:"mpeg4_url"` // required
1186	Width               int                   `json:"mpeg4_width"`
1187	Height              int                   `json:"mpeg4_height"`
1188	Duration            int                   `json:"mpeg4_duration"`
1189	ThumbURL            string                `json:"thumb_url"`
1190	Title               string                `json:"title"`
1191	Caption             string                `json:"caption"`
1192	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1193	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1194}
1195
1196// InlineQueryResultCachedMpeg4Gif is an inline query response with cached
1197// H.264/MPEG-4 AVC video without sound gif.
1198type InlineQueryResultCachedMpeg4Gif struct {
1199	Type                string                `json:"type"`          // required
1200	ID                  string                `json:"id"`            // required
1201	MGifID              string                `json:"mpeg4_file_id"` // required
1202	Title               string                `json:"title"`
1203	Caption             string                `json:"caption"`
1204	ParseMode           string                `json:"parse_mode"`
1205	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1206	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1207}
1208
1209// InlineQueryResultVideo is an inline query response video.
1210type InlineQueryResultVideo struct {
1211	Type                string                `json:"type"`      // required
1212	ID                  string                `json:"id"`        // required
1213	URL                 string                `json:"video_url"` // required
1214	MimeType            string                `json:"mime_type"` // required
1215	ThumbURL            string                `json:"thumb_url"`
1216	Title               string                `json:"title"`
1217	Caption             string                `json:"caption"`
1218	Width               int                   `json:"video_width"`
1219	Height              int                   `json:"video_height"`
1220	Duration            int                   `json:"video_duration"`
1221	Description         string                `json:"description"`
1222	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1223	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1224}
1225
1226// InlineQueryResultCachedVideo is an inline query response with cached video.
1227type InlineQueryResultCachedVideo struct {
1228	Type                string                `json:"type"`          // required
1229	ID                  string                `json:"id"`            // required
1230	VideoID             string                `json:"video_file_id"` // required
1231	Title               string                `json:"title"`         // required
1232	Description         string                `json:"description"`
1233	Caption             string                `json:"caption"`
1234	ParseMode           string                `json:"parse_mode"`
1235	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1236	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1237}
1238
1239// InlineQueryResultCachedSticker is an inline query response with cached sticker.
1240type InlineQueryResultCachedSticker struct {
1241	Type                string                `json:"type"`            // required
1242	ID                  string                `json:"id"`              // required
1243	StickerID           string                `json:"sticker_file_id"` // required
1244	Title               string                `json:"title"`           // required
1245	ParseMode           string                `json:"parse_mode"`
1246	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1247	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1248}
1249
1250// InlineQueryResultAudio is an inline query response audio.
1251type InlineQueryResultAudio struct {
1252	Type                string                `json:"type"`      // required
1253	ID                  string                `json:"id"`        // required
1254	URL                 string                `json:"audio_url"` // required
1255	Title               string                `json:"title"`     // required
1256	Caption             string                `json:"caption"`
1257	Performer           string                `json:"performer"`
1258	Duration            int                   `json:"audio_duration"`
1259	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1260	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1261}
1262
1263// InlineQueryResultCachedAudio is an inline query response with cached audio.
1264type InlineQueryResultCachedAudio struct {
1265	Type                string                `json:"type"`          // required
1266	ID                  string                `json:"id"`            // required
1267	AudioID             string                `json:"audio_file_id"` // required
1268	Caption             string                `json:"caption"`
1269	ParseMode           string                `json:"parse_mode"`
1270	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1271	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1272}
1273
1274// InlineQueryResultVoice is an inline query response voice.
1275type InlineQueryResultVoice struct {
1276	Type                string                `json:"type"`      // required
1277	ID                  string                `json:"id"`        // required
1278	URL                 string                `json:"voice_url"` // required
1279	Title               string                `json:"title"`     // required
1280	Caption             string                `json:"caption"`
1281	Duration            int                   `json:"voice_duration"`
1282	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1283	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1284}
1285
1286// InlineQueryResultCachedVoice is an inline query response with cached voice.
1287type InlineQueryResultCachedVoice struct {
1288	Type                string                `json:"type"`          // required
1289	ID                  string                `json:"id"`            // required
1290	VoiceID             string                `json:"voice_file_id"` // required
1291	Title               string                `json:"title"`         // required
1292	Caption             string                `json:"caption"`
1293	ParseMode           string                `json:"parse_mode"`
1294	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1295	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1296}
1297
1298// InlineQueryResultDocument is an inline query response document.
1299type InlineQueryResultDocument struct {
1300	Type                string                `json:"type"`  // required
1301	ID                  string                `json:"id"`    // required
1302	Title               string                `json:"title"` // required
1303	Caption             string                `json:"caption"`
1304	URL                 string                `json:"document_url"` // required
1305	MimeType            string                `json:"mime_type"`    // required
1306	Description         string                `json:"description"`
1307	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1308	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1309	ThumbURL            string                `json:"thumb_url"`
1310	ThumbWidth          int                   `json:"thumb_width"`
1311	ThumbHeight         int                   `json:"thumb_height"`
1312}
1313
1314// InlineQueryResultCachedDocument is an inline query response with cached document.
1315type InlineQueryResultCachedDocument struct {
1316	Type                string                `json:"type"`             // required
1317	ID                  string                `json:"id"`               // required
1318	DocumentID          string                `json:"document_file_id"` // required
1319	Title               string                `json:"title"`            // required
1320	Caption             string                `json:"caption"`
1321	Description         string                `json:"description"`
1322	ParseMode           string                `json:"parse_mode"`
1323	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1324	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1325}
1326
1327// InlineQueryResultLocation is an inline query response location.
1328type InlineQueryResultLocation struct {
1329	Type                string                `json:"type"`      // required
1330	ID                  string                `json:"id"`        // required
1331	Latitude            float64               `json:"latitude"`  // required
1332	Longitude           float64               `json:"longitude"` // required
1333	Title               string                `json:"title"`     // required
1334	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1335	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1336	ThumbURL            string                `json:"thumb_url"`
1337	ThumbWidth          int                   `json:"thumb_width"`
1338	ThumbHeight         int                   `json:"thumb_height"`
1339}
1340
1341// InlineQueryResultVenue is an inline query response venue.
1342type InlineQueryResultVenue struct {
1343	Type                string                `json:"type"`      // required
1344	ID                  string                `json:"id"`        // required
1345	Latitude            float64               `json:"latitude"`  // required
1346	Longitude           float64               `json:"longitude"` // required
1347	Title               string                `json:"title"`     // required
1348	Address             string                `json:"address"`   // required
1349	FoursquareID        string                `json:"foursquare_id"`
1350	FoursquareType      string                `json:"foursquare_type"`
1351	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1352	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
1353	ThumbURL            string                `json:"thumb_url"`
1354	ThumbWidth          int                   `json:"thumb_width"`
1355	ThumbHeight         int                   `json:"thumb_height"`
1356}
1357
1358// InlineQueryResultGame is an inline query response game.
1359type InlineQueryResultGame struct {
1360	Type          string                `json:"type"`
1361	ID            string                `json:"id"`
1362	GameShortName string                `json:"game_short_name"`
1363	ReplyMarkup   *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
1364}
1365
1366// ChosenInlineResult is an inline query result chosen by a User
1367type ChosenInlineResult struct {
1368	ResultID        string    `json:"result_id"`
1369	From            *User     `json:"from"`
1370	Location        *Location `json:"location"`
1371	InlineMessageID string    `json:"inline_message_id"`
1372	Query           string    `json:"query"`
1373}
1374
1375// InputTextMessageContent contains text for displaying
1376// as an inline query result.
1377type InputTextMessageContent struct {
1378	Text                  string `json:"message_text"`
1379	ParseMode             string `json:"parse_mode"`
1380	DisableWebPagePreview bool   `json:"disable_web_page_preview"`
1381}
1382
1383// InputLocationMessageContent contains a location for displaying
1384// as an inline query result.
1385type InputLocationMessageContent struct {
1386	Latitude  float64 `json:"latitude"`
1387	Longitude float64 `json:"longitude"`
1388}
1389
1390// InputVenueMessageContent contains a venue for displaying
1391// as an inline query result.
1392type InputVenueMessageContent struct {
1393	Latitude     float64 `json:"latitude"`
1394	Longitude    float64 `json:"longitude"`
1395	Title        string  `json:"title"`
1396	Address      string  `json:"address"`
1397	FoursquareID string  `json:"foursquare_id"`
1398}
1399
1400// InputContactMessageContent contains a contact for displaying
1401// as an inline query result.
1402type InputContactMessageContent struct {
1403	PhoneNumber string `json:"phone_number"`
1404	FirstName   string `json:"first_name"`
1405	LastName    string `json:"last_name"`
1406}
1407
1408// Invoice contains basic information about an invoice.
1409type Invoice struct {
1410	Title          string `json:"title"`
1411	Description    string `json:"description"`
1412	StartParameter string `json:"start_parameter"`
1413	Currency       string `json:"currency"`
1414	TotalAmount    int    `json:"total_amount"`
1415}
1416
1417// LabeledPrice represents a portion of the price for goods or services.
1418type LabeledPrice struct {
1419	Label  string `json:"label"`
1420	Amount int    `json:"amount"`
1421}
1422
1423// ShippingAddress represents a shipping address.
1424type ShippingAddress struct {
1425	CountryCode string `json:"country_code"`
1426	State       string `json:"state"`
1427	City        string `json:"city"`
1428	StreetLine1 string `json:"street_line1"`
1429	StreetLine2 string `json:"street_line2"`
1430	PostCode    string `json:"post_code"`
1431}
1432
1433// OrderInfo represents information about an order.
1434type OrderInfo struct {
1435	Name            string           `json:"name,omitempty"`
1436	PhoneNumber     string           `json:"phone_number,omitempty"`
1437	Email           string           `json:"email,omitempty"`
1438	ShippingAddress *ShippingAddress `json:"shipping_address,omitempty"`
1439}
1440
1441// ShippingOption represents one shipping option.
1442type ShippingOption struct {
1443	ID     string          `json:"id"`
1444	Title  string          `json:"title"`
1445	Prices *[]LabeledPrice `json:"prices"`
1446}
1447
1448// SuccessfulPayment contains basic information about a successful payment.
1449type SuccessfulPayment struct {
1450	Currency                string     `json:"currency"`
1451	TotalAmount             int        `json:"total_amount"`
1452	InvoicePayload          string     `json:"invoice_payload"`
1453	ShippingOptionID        string     `json:"shipping_option_id,omitempty"`
1454	OrderInfo               *OrderInfo `json:"order_info,omitempty"`
1455	TelegramPaymentChargeID string     `json:"telegram_payment_charge_id"`
1456	ProviderPaymentChargeID string     `json:"provider_payment_charge_id"`
1457}
1458
1459// ShippingQuery contains information about an incoming shipping query.
1460type ShippingQuery struct {
1461	ID              string           `json:"id"`
1462	From            *User            `json:"from"`
1463	InvoicePayload  string           `json:"invoice_payload"`
1464	ShippingAddress *ShippingAddress `json:"shipping_address"`
1465}
1466
1467// PreCheckoutQuery contains information about an incoming pre-checkout query.
1468type PreCheckoutQuery struct {
1469	ID               string     `json:"id"`
1470	From             *User      `json:"from"`
1471	Currency         string     `json:"currency"`
1472	TotalAmount      int        `json:"total_amount"`
1473	InvoicePayload   string     `json:"invoice_payload"`
1474	ShippingOptionID string     `json:"shipping_option_id,omitempty"`
1475	OrderInfo        *OrderInfo `json:"order_info,omitempty"`
1476}
1477
1478// Error is an error containing extra information returned by the Telegram API.
1479type Error struct {
1480	Code    int
1481	Message string
1482	ResponseParameters
1483}
1484
1485func (e Error) Error() string {
1486	return e.Message
1487}
1488
1489// BotCommand represents a bot command.
1490type BotCommand struct {
1491	Command     string `json:"command"`
1492	Description string `json:"description"`
1493}