all repos — telegram-bot-api @ 7e9b33f9e882c24592c60662102a6b18d6aadef0

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