all repos — telegram-bot-api @ 49a467b7c416fd06d6de7f67549ac42d5339e78b

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,omitempty"`
  17	ErrorCode   int                 `json:"error_code,omitempty"`
  18	Description string              `json:"description,omitempty"`
  19	Parameters  *ResponseParameters `json:"parameters,omitempty"`
  20}
  21
  22// ResponseParameters are various errors that can be returned in APIResponse.
  23type ResponseParameters struct {
  24	MigrateToChatID int64 `json:"migrate_to_chat_id,omitempty"` // optional
  25	RetryAfter      int   `json:"retry_after,omitempty"`        // 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,omitempty"`
  32	EditedMessage      *Message            `json:"edited_message,omitempty"`
  33	ChannelPost        *Message            `json:"channel_post,omitempty"`
  34	EditedChannelPost  *Message            `json:"edited_channel_post,omitempty"`
  35	InlineQuery        *InlineQuery        `json:"inline_query,omitempty"`
  36	ChosenInlineResult *ChosenInlineResult `json:"chosen_inline_result,omitempty"`
  37	CallbackQuery      *CallbackQuery      `json:"callback_query,omitempty"`
  38	ShippingQuery      *ShippingQuery      `json:"shipping_query,omitempty"`
  39	PreCheckoutQuery   *PreCheckoutQuery   `json:"pre_checkout_query,omitempty"`
  40	Poll               *Poll               `json:"poll,omitempty"`
  41	PollAnswer         *PollAnswer         `json:"poll_answer,omitempty"`
  42}
  43
  44// UpdatesChannel is the channel for getting updates.
  45type UpdatesChannel <-chan Update
  46
  47// Clear discards all unprocessed incoming updates.
  48func (ch UpdatesChannel) Clear() {
  49	for len(ch) != 0 {
  50		<-ch
  51	}
  52}
  53
  54// User is a user on Telegram.
  55type User struct {
  56	ID                      int    `json:"id"`
  57	FirstName               string `json:"first_name"`
  58	LastName                string `json:"last_name,omitempty"`                   // optional
  59	UserName                string `json:"username,omitempty"`                    // optional
  60	LanguageCode            string `json:"language_code,omitempty"`               // optional
  61	IsBot                   bool   `json:"is_bot,omitempty"`                      // optional
  62	CanJoinGroups           bool   `json:"can_join_groups,omitempty"`             // optional
  63	CanReadAllGroupMessages bool   `json:"can_read_all_group_messages,omitempty"` // optional
  64	SupportsInlineQueries   bool   `json:"supports_inline_queries,omitempty"`     // optional
  65}
  66
  67// String displays a simple text version of a user.
  68//
  69// It is normally a user's username, but falls back to a first/last
  70// name as available.
  71func (u *User) String() string {
  72	if u.UserName != "" {
  73		return u.UserName
  74	}
  75
  76	name := u.FirstName
  77	if u.LastName != "" {
  78		name += " " + u.LastName
  79	}
  80
  81	return name
  82}
  83
  84// GroupChat is a group chat.
  85type GroupChat struct {
  86	ID    int    `json:"id"`
  87	Title string `json:"title"`
  88}
  89
  90// ChatPhoto represents a chat photo.
  91type ChatPhoto struct {
  92	SmallFileID       string `json:"small_file_id"`
  93	SmallFileUniqueID string `json:"small_file_unique_id"`
  94	BigFileID         string `json:"big_file_id"`
  95	BigFileUniqueID   string `json:"big_file_unique_id"`
  96}
  97
  98// ChatPermissions describes actions that a non-administrator user is
  99// allowed to take in a chat. All fields are optional.
 100type ChatPermissions struct {
 101	CanSendMessages       bool `json:"can_send_messages"`
 102	CanSendMediaMessages  bool `json:"can_send_media_messages"`
 103	CanSendPolls          bool `json:"can_send_polls"`
 104	CanSendOtherMessages  bool `json:"can_send_other_messages"`
 105	CanAddWebPagePreviews bool `json:"can_add_web_page_previews"`
 106	CanChangeInfo         bool `json:"can_change_info"`
 107	CanInviteUsers        bool `json:"can_invite_users"`
 108	CanPinMessages        bool `json:"can_pin_messages"`
 109}
 110
 111// Chat contains information about the place a message was sent.
 112type Chat struct {
 113	ID                  int64            `json:"id"`
 114	Type                string           `json:"type"`
 115	Title               string           `json:"title,omitempty"`                          // optional
 116	UserName            string           `json:"username,omitempty"`                       // optional
 117	FirstName           string           `json:"first_name,omitempty"`                     // optional
 118	LastName            string           `json:"last_name,omitempty"`                      // optional
 119	AllMembersAreAdmins bool             `json:"all_members_are_administrators,omitempty"` // deprecated, optional
 120	Photo               *ChatPhoto       `json:"photo,omitempty"`                          // optional
 121	Description         string           `json:"description,omitempty"`                    // optional
 122	InviteLink          string           `json:"invite_link,omitempty"`                    // optional
 123	PinnedMessage       *Message         `json:"pinned_message,omitempty"`                 // optional
 124	Permissions         *ChatPermissions `json:"permissions,omitempty"`                    // optional
 125	SlowModeDelay       int              `json:"slow_mode_delay,omitempty"`                // optional
 126	StickerSetName      string           `json:"sticker_set_name,omitempty"`               // optional
 127	CanSetStickerSet    bool             `json:"can_set_sticker_set,omitempty"`            // optional
 128}
 129
 130// IsPrivate returns if the Chat is a private conversation.
 131func (c Chat) IsPrivate() bool {
 132	return c.Type == "private"
 133}
 134
 135// IsGroup returns if the Chat is a group.
 136func (c Chat) IsGroup() bool {
 137	return c.Type == "group"
 138}
 139
 140// IsSuperGroup returns if the Chat is a supergroup.
 141func (c Chat) IsSuperGroup() bool {
 142	return c.Type == "supergroup"
 143}
 144
 145// IsChannel returns if the Chat is a channel.
 146func (c Chat) IsChannel() bool {
 147	return c.Type == "channel"
 148}
 149
 150// ChatConfig returns a ChatConfig struct for chat related methods.
 151func (c Chat) ChatConfig() ChatConfig {
 152	return ChatConfig{ChatID: c.ID}
 153}
 154
 155// Message is returned by almost every request, and contains data about
 156// almost anything.
 157type Message struct {
 158	MessageID             int                   `json:"message_id"`
 159	From                  *User                 `json:"from,omitempty"` // optional
 160	Date                  int                   `json:"date"`
 161	Chat                  *Chat                 `json:"chat"`
 162	ForwardFrom           *User                 `json:"forward_from,omitempty"`            // optional
 163	ForwardFromChat       *Chat                 `json:"forward_from_chat,omitempty"`       // optional
 164	ForwardFromMessageID  int                   `json:"forward_from_message_id,omitempty"` // optional
 165	ForwardSignature      string                `json:"forward_signature,omitempty"`       // optional
 166	ForwardSenderName     string                `json:"forward_sender_name,omitempty"`     // optional
 167	ForwardDate           int                   `json:"forward_date,omitempty"`            // optional
 168	ReplyToMessage        *Message              `json:"reply_to_message,omitempty"`        // optional
 169	EditDate              int                   `json:"edit_date,omitempty"`               // optional
 170	MediaGroupID          string                `json:"media_group_id,omitempty"`          // optional
 171	AuthorSignature       string                `json:"author_signature,omitempty"`        // optional
 172	Text                  string                `json:"text,omitempty"`                    // optional
 173	Entities              []MessageEntity       `json:"entities,omitempty"`                // optional
 174	CaptionEntities       []MessageEntity       `json:"caption_entities,omitempty"`        // optional
 175	Audio                 *Audio                `json:"audio,omitempty"`                   // optional
 176	Document              *Document             `json:"document,omitempty"`                // optional
 177	Animation             *ChatAnimation        `json:"animation,omitempty"`               // optional
 178	Game                  *Game                 `json:"game,omitempty"`                    // optional
 179	Photo                 []PhotoSize           `json:"photo,omitempty"`                   // optional
 180	Sticker               *Sticker              `json:"sticker,omitempty"`                 // optional
 181	Video                 *Video                `json:"video,omitempty"`                   // optional
 182	VideoNote             *VideoNote            `json:"video_note,omitempty"`              // optional
 183	Voice                 *Voice                `json:"voice,omitempty"`                   // optional
 184	Caption               string                `json:"caption,omitempty"`                 // optional
 185	Contact               *Contact              `json:"contact,omitempty"`                 // optional
 186	Location              *Location             `json:"location,omitempty"`                // optional
 187	Venue                 *Venue                `json:"venue,omitempty"`                   // optional
 188	Poll                  *Poll                 `json:"poll,omitempty"`                    // optional
 189	Dice                  *Dice                 `json:"dice,omitempty"`                    // optional
 190	NewChatMembers        []User                `json:"new_chat_members,omitempty"`        // optional
 191	LeftChatMember        *User                 `json:"left_chat_member,omitempty"`        // optional
 192	NewChatTitle          string                `json:"new_chat_title,omitempty"`          // optional
 193	NewChatPhoto          []PhotoSize           `json:"new_chat_photo,omitempty"`          // optional
 194	DeleteChatPhoto       bool                  `json:"delete_chat_photo,omitempty"`       // optional
 195	GroupChatCreated      bool                  `json:"group_chat_created,omitempty"`      // optional
 196	SuperGroupChatCreated bool                  `json:"supergroup_chat_created,omitempty"` // optional
 197	ChannelChatCreated    bool                  `json:"channel_chat_created,omitempty"`    // optional
 198	MigrateToChatID       int64                 `json:"migrate_to_chat_id,omitempty"`      // optional
 199	MigrateFromChatID     int64                 `json:"migrate_from_chat_id,omitempty"`    // optional
 200	PinnedMessage         *Message              `json:"pinned_message,omitempty"`          // optional
 201	Invoice               *Invoice              `json:"invoice,omitempty"`                 // optional
 202	SuccessfulPayment     *SuccessfulPayment    `json:"successful_payment,omitempty"`      // optional
 203	ConnectedWebsite      string                `json:"connected_website,omitempty"`       // optional
 204	PassportData          *PassportData         `json:"passport_data,omitempty"`           // optional
 205	ReplyMarkup           *InlineKeyboardMarkup `json:"reply_markup,omitempty"`            // optional
 206}
 207
 208// Time converts the message timestamp into a Time.
 209func (m *Message) Time() time.Time {
 210	return time.Unix(int64(m.Date), 0)
 211}
 212
 213// IsCommand returns true if message starts with a "bot_command" entity.
 214func (m *Message) IsCommand() bool {
 215	if m.Entities == nil || len(m.Entities) == 0 {
 216		return false
 217	}
 218
 219	entity := m.Entities[0]
 220	return entity.Offset == 0 && entity.IsCommand()
 221}
 222
 223// Command checks if the message was a command and if it was, returns the
 224// command. If the Message was not a command, it returns an empty string.
 225//
 226// If the command contains the at name syntax, it is removed. Use
 227// CommandWithAt() if you do not want that.
 228func (m *Message) Command() string {
 229	command := m.CommandWithAt()
 230
 231	if i := strings.Index(command, "@"); i != -1 {
 232		command = command[:i]
 233	}
 234
 235	return command
 236}
 237
 238// CommandWithAt checks if the message was a command and if it was, returns the
 239// command. If the Message was not a command, it returns an empty string.
 240//
 241// If the command contains the at name syntax, it is not removed. Use Command()
 242// if you want that.
 243func (m *Message) CommandWithAt() string {
 244	if !m.IsCommand() {
 245		return ""
 246	}
 247
 248	// IsCommand() checks that the message begins with a bot_command entity
 249	entity := m.Entities[0]
 250	return m.Text[1:entity.Length]
 251}
 252
 253// CommandArguments checks if the message was a command and if it was,
 254// returns all text after the command name. If the Message was not a
 255// command, it returns an empty string.
 256//
 257// Note: The first character after the command name is omitted:
 258// - "/foo bar baz" yields "bar baz", not " bar baz"
 259// - "/foo-bar baz" yields "bar baz", too
 260// Even though the latter is not a command conforming to the spec, the API
 261// marks "/foo" as command entity.
 262func (m *Message) CommandArguments() string {
 263	if !m.IsCommand() {
 264		return ""
 265	}
 266
 267	// IsCommand() checks that the message begins with a bot_command entity
 268	entity := m.Entities[0]
 269
 270	if len(m.Text) == entity.Length {
 271		return "" // The command makes up the whole message
 272	}
 273
 274	return m.Text[entity.Length+1:]
 275}
 276
 277// MessageEntity contains information about data in a Message.
 278type MessageEntity struct {
 279	Type     string `json:"type"`
 280	Offset   int    `json:"offset"`
 281	Length   int    `json:"length"`
 282	URL      string `json:"url,omitempty"`      // optional
 283	User     *User  `json:"user,omitempty"`     // optional
 284	Language string `json:"language,omitempty"` // optional
 285}
 286
 287// ParseURL attempts to parse a URL contained within a MessageEntity.
 288func (e MessageEntity) ParseURL() (*url.URL, error) {
 289	if e.URL == "" {
 290		return nil, errors.New(ErrBadURL)
 291	}
 292
 293	return url.Parse(e.URL)
 294}
 295
 296// IsMention returns true if the type of the message entity is "mention" (@username).
 297func (e MessageEntity) IsMention() bool {
 298	return e.Type == "mention"
 299}
 300
 301// IsHashtag returns true if the type of the message entity is "hashtag".
 302func (e MessageEntity) IsHashtag() bool {
 303	return e.Type == "hashtag"
 304}
 305
 306// IsCommand returns true if the type of the message entity is "bot_command".
 307func (e MessageEntity) IsCommand() bool {
 308	return e.Type == "bot_command"
 309}
 310
 311// IsUrl returns true if the type of the message entity is "url".
 312func (e MessageEntity) IsUrl() bool {
 313	return e.Type == "url"
 314}
 315
 316// IsEmail returns true if the type of the message entity is "email".
 317func (e MessageEntity) IsEmail() bool {
 318	return e.Type == "email"
 319}
 320
 321// IsBold returns true if the type of the message entity is "bold" (bold text).
 322func (e MessageEntity) IsBold() bool {
 323	return e.Type == "bold"
 324}
 325
 326// IsItalic returns true if the type of the message entity is "italic" (italic text).
 327func (e MessageEntity) IsItalic() bool {
 328	return e.Type == "italic"
 329}
 330
 331// IsCode returns true if the type of the message entity is "code" (monowidth string).
 332func (e MessageEntity) IsCode() bool {
 333	return e.Type == "code"
 334}
 335
 336// IsPre returns true if the type of the message entity is "pre" (monowidth block).
 337func (e MessageEntity) IsPre() bool {
 338	return e.Type == "pre"
 339}
 340
 341// IsTextLink returns true if the type of the message entity is "text_link" (clickable text URL).
 342func (e MessageEntity) IsTextLink() bool {
 343	return e.Type == "text_link"
 344}
 345
 346// PhotoSize contains information about photos.
 347type PhotoSize struct {
 348	FileID       string `json:"file_id"`
 349	FileUniqueID string `json:"file_unique_id"`
 350	Width        int    `json:"width"`
 351	Height       int    `json:"height"`
 352	FileSize     int    `json:"file_size,omitempty"` // optional
 353}
 354
 355// Audio contains information about audio.
 356type Audio struct {
 357	FileID       string `json:"file_id"`
 358	FileUniqueID string `json:"file_unique_id"`
 359	Duration     int    `json:"duration"`
 360	Performer    string `json:"performer,omitempty"` // optional
 361	Title        string `json:"title,omitempty"`     // optional
 362	MimeType     string `json:"mime_type,omitempty"` // optional
 363	FileSize     int    `json:"file_size,omitempty"` // optional
 364}
 365
 366// Document contains information about a document.
 367type Document struct {
 368	FileID       string     `json:"file_id"`
 369	FileUniqueID string     `json:"file_unique_id"`
 370	Thumbnail    *PhotoSize `json:"thumb,omitempty"`     // optional
 371	FileName     string     `json:"file_name,omitempty"` // optional
 372	MimeType     string     `json:"mime_type,omitempty"` // optional
 373	FileSize     int        `json:"file_size,omitempty"` // optional
 374}
 375
 376// Sticker contains information about a sticker.
 377type Sticker struct {
 378	FileID       string       `json:"file_id"`
 379	FileUniqueID string       `json:"file_unique_id"`
 380	Width        int          `json:"width"`
 381	Height       int          `json:"height"`
 382	IsAnimated   bool         `json:"is_animated"`
 383	Thumbnail    *PhotoSize   `json:"thumb,omitempty"`         // optional
 384	Emoji        string       `json:"emoji,omitempty"`         // optional
 385	SetName      string       `json:"set_name,omitempty"`      // optional
 386	MaskPosition MaskPosition `json:"mask_position,omitempty"` //optional
 387	FileSize     int          `json:"file_size,omitempty"`     // optional
 388}
 389
 390// MaskPosition is the position of a mask.
 391type MaskPosition struct {
 392	Point     string     `json:"point"`
 393	XShift    float32    `json:"x_shift"`
 394	YShift    float32    `json:"y_shift"`
 395	Scale     float32    `json:"scale"`
 396	FileID    string     `json:"file_id"`
 397	Width     int        `json:"width"`
 398	Height    int        `json:"height"`
 399	Thumbnail *PhotoSize `json:"thumb,omitempty"`     // optional
 400	Emoji     string     `json:"emoji,omitempty"`     // optional
 401	FileSize  int        `json:"file_size,omitempty"` // optional
 402	SetName   string     `json:"set_name,omitempty"`  // optional
 403}
 404
 405// ChatAnimation contains information about an animation.
 406type ChatAnimation struct {
 407	FileID       string     `json:"file_id"`
 408	FileUniqueID string     `json:"file_unique_id"`
 409	Width        int        `json:"width"`
 410	Height       int        `json:"height"`
 411	Duration     int        `json:"duration"`
 412	Thumbnail    *PhotoSize `json:"thumb,omitempty"`     // optional
 413	FileName     string     `json:"file_name,omitempty"` // optional
 414	MimeType     string     `json:"mime_type,omitempty"` // optional
 415	FileSize     int        `json:"file_size,omitempty"` // optional
 416}
 417
 418// Video contains information about a video.
 419type Video struct {
 420	FileID       string     `json:"file_id"`
 421	FileUniqueID string     `json:"file_unique_id"`
 422	Width        int        `json:"width"`
 423	Height       int        `json:"height"`
 424	Duration     int        `json:"duration"`
 425	Thumbnail    *PhotoSize `json:"thumb,omitempty"`     // optional
 426	MimeType     string     `json:"mime_type,omitempty"` // optional
 427	FileSize     int        `json:"file_size,omitempty"` // optional
 428}
 429
 430// VideoNote contains information about a video.
 431type VideoNote struct {
 432	FileID       string     `json:"file_id"`
 433	FileUniqueID string     `json:"file_unique_id"`
 434	Length       int        `json:"length"`
 435	Duration     int        `json:"duration"`
 436	Thumbnail    *PhotoSize `json:"thumb,omitempty"`     // optional
 437	FileSize     int        `json:"file_size,omitempty"` // optional
 438}
 439
 440// Voice contains information about a voice.
 441type Voice struct {
 442	FileID       string `json:"file_id"`
 443	FileUniqueID string `json:"file_unique_id"`
 444	Duration     int    `json:"duration"`
 445	MimeType     string `json:"mime_type,omitempty"` // optional
 446	FileSize     int    `json:"file_size,omitempty"` // optional
 447}
 448
 449// Contact contains information about a contact.
 450//
 451// Note that LastName and UserID may be empty.
 452type Contact struct {
 453	PhoneNumber string `json:"phone_number"`
 454	FirstName   string `json:"first_name"`
 455	LastName    string `json:"last_name,omitempty"` // optional
 456	UserID      int    `json:"user_id,omitempty"`   // optional
 457	VCard       string `json:"vcard,omitempty"`     // optional
 458}
 459
 460// Location contains information about a place.
 461type Location struct {
 462	Longitude float64 `json:"longitude"`
 463	Latitude  float64 `json:"latitude"`
 464}
 465
 466// Venue contains information about a venue, including its Location.
 467type Venue struct {
 468	Location     Location `json:"location"`
 469	Title        string   `json:"title"`
 470	Address      string   `json:"address"`
 471	FoursquareID string   `json:"foursquare_id,omitempty"` // optional
 472}
 473
 474// PollOption contains information about one answer option in a poll.
 475type PollOption struct {
 476	Text       string `json:"text"`
 477	VoterCount int    `json:"voter_count"`
 478}
 479
 480// PollAnswer represents an answer of a user in a non-anonymous poll.
 481type PollAnswer struct {
 482	PollID    string `json:"poll_id"`
 483	User      User   `json:"user"`
 484	OptionIDs []int  `json:"option_ids"`
 485}
 486
 487// Poll contains information about a poll.
 488type Poll struct {
 489	ID                    string          `json:"id"`
 490	Question              string          `json:"question"`
 491	Options               []PollOption    `json:"options"`
 492	IsClosed              bool            `json:"is_closed"`
 493	IsAnonymous           bool            `json:"is_anonymous"`
 494	Type                  string          `json:"type"`
 495	AllowsMultipleAnswers bool            `json:"allows_multiple_answers"`
 496	CorrectOptionID       int             `json:"correct_option_id,omitempty"`    // optional
 497	Explanation           string          `json:"explanation,omitempty"`          // optional
 498	ExplanationEntities   []MessageEntity `json:"explanation_entities,omitempty"` // optional
 499	OpenPeriod            int             `json:"open_period,omitempty"`          // optional
 500	CloseDate             int             `json:"close_date,omitempty"`           // optional
 501}
 502
 503// Dice represents a single dice value.
 504type Dice struct {
 505	Emoji string `json:"emoji"`
 506	Value int    `json:"value"`
 507}
 508
 509// UserProfilePhotos contains a set of user profile photos.
 510type UserProfilePhotos struct {
 511	TotalCount int           `json:"total_count"`
 512	Photos     [][]PhotoSize `json:"photos"`
 513}
 514
 515// File contains information about a file to download from Telegram.
 516type File struct {
 517	FileID       string `json:"file_id"`
 518	FileUniqueID string `json:"file_unique_id"`
 519	FileSize     int    `json:"file_size,omitempty"` // optional
 520	FilePath     string `json:"file_path,omitempty"` // optional
 521}
 522
 523// Link returns a full path to the download URL for a File.
 524//
 525// It requires the Bot Token to create the link.
 526func (f *File) Link(token string) string {
 527	return fmt.Sprintf(FileEndpoint, token, f.FilePath)
 528}
 529
 530// ReplyKeyboardMarkup allows the Bot to set a custom keyboard.
 531type ReplyKeyboardMarkup struct {
 532	Keyboard        [][]KeyboardButton `json:"keyboard"`
 533	ResizeKeyboard  bool               `json:"resize_keyboard,omitempty"`   // optional
 534	OneTimeKeyboard bool               `json:"one_time_keyboard,omitempty"` // optional
 535	Selective       bool               `json:"selective,omitempty"`         // optional
 536}
 537
 538// KeyboardButton is a button within a custom keyboard.
 539type KeyboardButton struct {
 540	Text            string                  `json:"text"`
 541	RequestContact  bool                    `json:"request_contact"`
 542	RequestLocation bool                    `json:"request_location"`
 543	RequestPoll     *KeyboardButtonPollType `json:"request_poll,omitempty"`
 544}
 545
 546// KeyboardButtonPollType represents type of a poll, which is allowed to
 547// be created and sent when the corresponding button is pressed.
 548type KeyboardButtonPollType struct {
 549	Type string `json:"type"`
 550}
 551
 552// ReplyKeyboardHide allows the Bot to hide a custom keyboard.
 553type ReplyKeyboardHide struct {
 554	HideKeyboard bool `json:"hide_keyboard"`
 555	Selective    bool `json:"selective,omitempty"` // optional
 556}
 557
 558// ReplyKeyboardRemove allows the Bot to hide a custom keyboard.
 559type ReplyKeyboardRemove struct {
 560	RemoveKeyboard bool `json:"remove_keyboard"`
 561	Selective      bool `json:"selective"`
 562}
 563
 564// InlineKeyboardMarkup is a custom keyboard presented for an inline bot.
 565type InlineKeyboardMarkup struct {
 566	InlineKeyboard [][]InlineKeyboardButton `json:"inline_keyboard"`
 567}
 568
 569// InlineKeyboardButton is a button within a custom keyboard for
 570// inline query responses.
 571//
 572// Note that some values are references as even an empty string
 573// will change behavior.
 574//
 575// CallbackGame, if set, MUST be first button in first row.
 576type InlineKeyboardButton struct {
 577	Text                         string        `json:"text"`
 578	URL                          *string       `json:"url,omitempty"`                              // optional
 579	LoginURL                     *LoginURL     `json:"login_url,omitempty"`                        // optional
 580	CallbackData                 *string       `json:"callback_data,omitempty"`                    // optional
 581	SwitchInlineQuery            *string       `json:"switch_inline_query,omitempty"`              // optional
 582	SwitchInlineQueryCurrentChat *string       `json:"switch_inline_query_current_chat,omitempty"` // optional
 583	CallbackGame                 *CallbackGame `json:"callback_game,omitempty"`                    // optional
 584	Pay                          bool          `json:"pay,omitempty"`                              // optional
 585}
 586
 587// LoginURL is the parameters for the login inline keyboard button type.
 588type LoginURL struct {
 589	URL                string `json:"url"`
 590	ForwardText        string `json:"forward_text"`
 591	BotUsername        string `json:"bot_username"`
 592	RequestWriteAccess bool   `json:"request_write_access"`
 593}
 594
 595// CallbackQuery is data sent when a keyboard button with callback data
 596// is clicked.
 597type CallbackQuery struct {
 598	ID              string   `json:"id"`
 599	From            *User    `json:"from"`
 600	Message         *Message `json:"message,omitempty"`           // optional
 601	InlineMessageID string   `json:"inline_message_id,omitempty"` // optional
 602	ChatInstance    string   `json:"chat_instance"`
 603	Data            string   `json:"data,omitempty"`            // optional
 604	GameShortName   string   `json:"game_short_name,omitempty"` // optional
 605}
 606
 607// ForceReply allows the Bot to have users directly reply to it without
 608// additional interaction.
 609type ForceReply struct {
 610	ForceReply bool `json:"force_reply"`
 611	Selective  bool `json:"selective"` // optional
 612}
 613
 614// ChatMember is information about a member in a chat.
 615type ChatMember struct {
 616	User                  *User  `json:"user"`
 617	Status                string `json:"status"`
 618	CustomTitle           string `json:"custom_title,omitempty"`              // optional
 619	UntilDate             int64  `json:"until_date,omitempty"`                // optional
 620	CanBeEdited           bool   `json:"can_be_edited,omitempty"`             // optional
 621	CanPostMessages       bool   `json:"can_post_messages,omitempty"`         // optional
 622	CanEditMessages       bool   `json:"can_edit_messages,omitempty"`         // optional
 623	CanDeleteMessages     bool   `json:"can_delete_messages,omitempty"`       // optional
 624	CanRestrictMembers    bool   `json:"can_restrict_members,omitempty"`      // optional
 625	CanPromoteMembers     bool   `json:"can_promote_members,omitempty"`       // optional
 626	CanChangeInfo         bool   `json:"can_change_info,omitempty"`           // optional
 627	CanInviteUsers        bool   `json:"can_invite_users,omitempty"`          // optional
 628	CanPinMessages        bool   `json:"can_pin_messages,omitempty"`          // optional
 629	IsChatMember          bool   `json:"is_member,omitempty"`                 // optional
 630	CanSendMessages       bool   `json:"can_send_messages,omitempty"`         // optional
 631	CanSendMediaMessages  bool   `json:"can_send_media_messages,omitempty"`   // optional
 632	CanSendPolls          bool   `json:"can_send_polls,omitempty"`            // optional
 633	CanSendOtherMessages  bool   `json:"can_send_other_messages,omitempty"`   // optional
 634	CanAddWebPagePreviews bool   `json:"can_add_web_page_previews,omitempty"` // optional
 635}
 636
 637// IsCreator returns if the ChatMember was the creator of the chat.
 638func (chat ChatMember) IsCreator() bool { return chat.Status == "creator" }
 639
 640// IsAdministrator returns if the ChatMember is a chat administrator.
 641func (chat ChatMember) IsAdministrator() bool { return chat.Status == "administrator" }
 642
 643// IsMember returns if the ChatMember is a current member of the chat.
 644func (chat ChatMember) IsMember() bool { return chat.Status == "member" }
 645
 646// HasLeft returns if the ChatMember left the chat.
 647func (chat ChatMember) HasLeft() bool { return chat.Status == "left" }
 648
 649// WasKicked returns if the ChatMember was kicked from the chat.
 650func (chat ChatMember) WasKicked() bool { return chat.Status == "kicked" }
 651
 652// Game is a game within Telegram.
 653type Game struct {
 654	Title        string          `json:"title"`
 655	Description  string          `json:"description"`
 656	Photo        []PhotoSize     `json:"photo"`
 657	Text         string          `json:"text"`
 658	TextEntities []MessageEntity `json:"text_entities"`
 659	Animation    Animation       `json:"animation"`
 660}
 661
 662// Animation is a GIF animation demonstrating the game.
 663type Animation struct {
 664	FileID       string    `json:"file_id"`
 665	FileUniqueID string    `json:"file_unique_id"`
 666	Thumb        PhotoSize `json:"thumb"`
 667	FileName     string    `json:"file_name"`
 668	MimeType     string    `json:"mime_type"`
 669	FileSize     int       `json:"file_size"`
 670}
 671
 672// GameHighScore is a user's score and position on the leaderboard.
 673type GameHighScore struct {
 674	Position int  `json:"position"`
 675	User     User `json:"user"`
 676	Score    int  `json:"score"`
 677}
 678
 679// CallbackGame is for starting a game in an inline keyboard button.
 680type CallbackGame struct{}
 681
 682// WebhookInfo is information about a currently set webhook.
 683type WebhookInfo struct {
 684	URL                  string `json:"url"`
 685	HasCustomCertificate bool   `json:"has_custom_certificate"`
 686	PendingUpdateCount   int    `json:"pending_update_count"`
 687	LastErrorDate        int    `json:"last_error_date,omitempty"`    // optional
 688	LastErrorMessage     string `json:"last_error_message,omitempty"` // optional
 689}
 690
 691// IsSet returns true if a webhook is currently set.
 692func (info WebhookInfo) IsSet() bool {
 693	return info.URL != ""
 694}
 695
 696// InlineQuery is a Query from Telegram for an inline request.
 697type InlineQuery struct {
 698	ID       string    `json:"id"`
 699	From     *User     `json:"from"`
 700	Location *Location `json:"location,omitempty"` // optional
 701	Query    string    `json:"query"`
 702	Offset   string    `json:"offset"`
 703}
 704
 705// InlineQueryResultArticle is an inline query response article.
 706type InlineQueryResultArticle struct {
 707	Type                string                `json:"type"`                            // required
 708	ID                  string                `json:"id"`                              // required
 709	Title               string                `json:"title"`                           // required
 710	InputMessageContent interface{}           `json:"input_message_content,omitempty"` // required
 711	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
 712	URL                 string                `json:"url"`
 713	HideURL             bool                  `json:"hide_url"`
 714	Description         string                `json:"description"`
 715	ThumbURL            string                `json:"thumb_url"`
 716	ThumbWidth          int                   `json:"thumb_width"`
 717	ThumbHeight         int                   `json:"thumb_height"`
 718}
 719
 720// InlineQueryResultPhoto is an inline query response photo.
 721type InlineQueryResultPhoto struct {
 722	Type                string                `json:"type"`      // required
 723	ID                  string                `json:"id"`        // required
 724	URL                 string                `json:"photo_url"` // required
 725	MimeType            string                `json:"mime_type"`
 726	Width               int                   `json:"photo_width"`
 727	Height              int                   `json:"photo_height"`
 728	ThumbURL            string                `json:"thumb_url"`
 729	Title               string                `json:"title"`
 730	Description         string                `json:"description"`
 731	Caption             string                `json:"caption"`
 732	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
 733	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
 734}
 735
 736// InlineQueryResultCachedPhoto is an inline query response with cached photo.
 737type InlineQueryResultCachedPhoto struct {
 738	Type                string                `json:"type"`          // required
 739	ID                  string                `json:"id"`            // required
 740	PhotoID             string                `json:"photo_file_id"` // required
 741	Title               string                `json:"title"`
 742	Description         string                `json:"description"`
 743	Caption             string                `json:"caption"`
 744	ParseMode           string                `json:"parse_mode"`
 745	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
 746	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
 747}
 748
 749// InlineQueryResultGIF is an inline query response GIF.
 750type InlineQueryResultGIF struct {
 751	Type                string                `json:"type"`      // required
 752	ID                  string                `json:"id"`        // required
 753	URL                 string                `json:"gif_url"`   // required
 754	ThumbURL            string                `json:"thumb_url"` // required
 755	Width               int                   `json:"gif_width,omitempty"`
 756	Height              int                   `json:"gif_height,omitempty"`
 757	Duration            int                   `json:"gif_duration,omitempty"`
 758	Title               string                `json:"title,omitempty"`
 759	Caption             string                `json:"caption,omitempty"`
 760	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
 761	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
 762}
 763
 764// InlineQueryResultCachedGIF is an inline query response with cached gif.
 765type InlineQueryResultCachedGIF struct {
 766	Type                string                `json:"type"`        // required
 767	ID                  string                `json:"id"`          // required
 768	GifID               string                `json:"gif_file_id"` // required
 769	Title               string                `json:"title"`
 770	Caption             string                `json:"caption"`
 771	ParseMode           string                `json:"parse_mode"`
 772	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
 773	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
 774}
 775
 776// InlineQueryResultMPEG4GIF is an inline query response MPEG4 GIF.
 777type InlineQueryResultMPEG4GIF struct {
 778	Type                string                `json:"type"`      // required
 779	ID                  string                `json:"id"`        // required
 780	URL                 string                `json:"mpeg4_url"` // required
 781	Width               int                   `json:"mpeg4_width"`
 782	Height              int                   `json:"mpeg4_height"`
 783	Duration            int                   `json:"mpeg4_duration"`
 784	ThumbURL            string                `json:"thumb_url"`
 785	Title               string                `json:"title"`
 786	Caption             string                `json:"caption"`
 787	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
 788	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
 789}
 790
 791// InlineQueryResultCachedMpeg4Gif is an inline query response with cached
 792// H.264/MPEG-4 AVC video without sound gif.
 793type InlineQueryResultCachedMpeg4Gif struct {
 794	Type                string                `json:"type"`          // required
 795	ID                  string                `json:"id"`            // required
 796	MGifID              string                `json:"mpeg4_file_id"` // required
 797	Title               string                `json:"title"`
 798	Caption             string                `json:"caption"`
 799	ParseMode           string                `json:"parse_mode"`
 800	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
 801	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
 802}
 803
 804// InlineQueryResultVideo is an inline query response video.
 805type InlineQueryResultVideo struct {
 806	Type                string                `json:"type"`      // required
 807	ID                  string                `json:"id"`        // required
 808	URL                 string                `json:"video_url"` // required
 809	MimeType            string                `json:"mime_type"` // required
 810	ThumbURL            string                `json:"thumb_url"`
 811	Title               string                `json:"title"`
 812	Caption             string                `json:"caption"`
 813	Width               int                   `json:"video_width"`
 814	Height              int                   `json:"video_height"`
 815	Duration            int                   `json:"video_duration"`
 816	Description         string                `json:"description"`
 817	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
 818	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
 819}
 820
 821// InlineQueryResultCachedVideo is an inline query response with cached video.
 822type InlineQueryResultCachedVideo struct {
 823	Type                string                `json:"type"`          // required
 824	ID                  string                `json:"id"`            // required
 825	VideoID             string                `json:"video_file_id"` // required
 826	Title               string                `json:"title"`         // required
 827	Description         string                `json:"description"`
 828	Caption             string                `json:"caption"`
 829	ParseMode           string                `json:"parse_mode"`
 830	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
 831	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
 832}
 833
 834// InlineQueryResultAudio is an inline query response audio.
 835type InlineQueryResultAudio struct {
 836	Type                string                `json:"type"`      // required
 837	ID                  string                `json:"id"`        // required
 838	URL                 string                `json:"audio_url"` // required
 839	Title               string                `json:"title"`     // required
 840	Caption             string                `json:"caption"`
 841	Performer           string                `json:"performer"`
 842	Duration            int                   `json:"audio_duration"`
 843	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
 844	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
 845}
 846
 847// InlineQueryResultCachedAudio is an inline query response with cached audio.
 848type InlineQueryResultCachedAudio struct {
 849	Type                string                `json:"type"`          // required
 850	ID                  string                `json:"id"`            // required
 851	AudioID             string                `json:"audio_file_id"` // required
 852	Caption             string                `json:"caption"`
 853	ParseMode           string                `json:"parse_mode"`
 854	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
 855	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
 856}
 857
 858// InlineQueryResultVoice is an inline query response voice.
 859type InlineQueryResultVoice struct {
 860	Type                string                `json:"type"`      // required
 861	ID                  string                `json:"id"`        // required
 862	URL                 string                `json:"voice_url"` // required
 863	Title               string                `json:"title"`     // required
 864	Caption             string                `json:"caption"`
 865	Duration            int                   `json:"voice_duration"`
 866	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
 867	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
 868}
 869
 870// InlineQueryResultCachedVoice is an inline query response with cached voice.
 871type InlineQueryResultCachedVoice struct {
 872	Type                string                `json:"type"`          // required
 873	ID                  string                `json:"id"`            // required
 874	VoiceID             string                `json:"voice_file_id"` // required
 875	Title               string                `json:"title"`         // required
 876	Caption             string                `json:"caption"`
 877	ParseMode           string                `json:"parse_mode"`
 878	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
 879	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
 880}
 881
 882// InlineQueryResultDocument is an inline query response document.
 883type InlineQueryResultDocument struct {
 884	Type                string                `json:"type"`  // required
 885	ID                  string                `json:"id"`    // required
 886	Title               string                `json:"title"` // required
 887	Caption             string                `json:"caption"`
 888	URL                 string                `json:"document_url"` // required
 889	MimeType            string                `json:"mime_type"`    // required
 890	Description         string                `json:"description"`
 891	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
 892	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
 893	ThumbURL            string                `json:"thumb_url"`
 894	ThumbWidth          int                   `json:"thumb_width"`
 895	ThumbHeight         int                   `json:"thumb_height"`
 896}
 897
 898// InlineQueryResultCachedDocument is an inline query response with cached document.
 899type InlineQueryResultCachedDocument struct {
 900	Type                string                `json:"type"`             // required
 901	ID                  string                `json:"id"`               // required
 902	DocumentID          string                `json:"document_file_id"` // required
 903	Title               string                `json:"title"`            // required
 904	Caption             string                `json:"caption"`
 905	Description         string                `json:"description"`
 906	ParseMode           string                `json:"parse_mode"`
 907	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
 908	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
 909}
 910
 911// InlineQueryResultLocation is an inline query response location.
 912type InlineQueryResultLocation struct {
 913	Type                string                `json:"type"`        // required
 914	ID                  string                `json:"id"`          // required
 915	Latitude            float64               `json:"latitude"`    // required
 916	Longitude           float64               `json:"longitude"`   // required
 917	LivePeriod          int                   `json:"live_period"` // optional
 918	Title               string                `json:"title"`       // required
 919	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
 920	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
 921	ThumbURL            string                `json:"thumb_url"`
 922	ThumbWidth          int                   `json:"thumb_width"`
 923	ThumbHeight         int                   `json:"thumb_height"`
 924}
 925
 926// InlineQueryResultContact is an inline query response contact.
 927type InlineQueryResultContact struct {
 928	Type                string                `json:"type"`         // required
 929	ID                  string                `json:"id"`           // required
 930	PhoneNumber         string                `json:"phone_number"` // required
 931	FirstName           string                `json:"first_name"`   // required
 932	LastName            string                `json:"last_name"`
 933	VCard               string                `json:"vcard"`
 934	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
 935	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
 936	ThumbURL            string                `json:"thumb_url"`
 937	ThumbWidth          int                   `json:"thumb_width"`
 938	ThumbHeight         int                   `json:"thumb_height"`
 939}
 940
 941// InlineQueryResultVenue is an inline query response venue.
 942type InlineQueryResultVenue struct {
 943	Type                string                `json:"type"`      // required
 944	ID                  string                `json:"id"`        // required
 945	Latitude            float64               `json:"latitude"`  // required
 946	Longitude           float64               `json:"longitude"` // required
 947	Title               string                `json:"title"`     // required
 948	Address             string                `json:"address"`   // required
 949	FoursquareID        string                `json:"foursquare_id"`
 950	FoursquareType      string                `json:"foursquare_type"`
 951	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
 952	InputMessageContent interface{}           `json:"input_message_content,omitempty"`
 953	ThumbURL            string                `json:"thumb_url"`
 954	ThumbWidth          int                   `json:"thumb_width"`
 955	ThumbHeight         int                   `json:"thumb_height"`
 956}
 957
 958// InlineQueryResultGame is an inline query response game.
 959type InlineQueryResultGame struct {
 960	Type          string                `json:"type"`
 961	ID            string                `json:"id"`
 962	GameShortName string                `json:"game_short_name"`
 963	ReplyMarkup   *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
 964}
 965
 966// ChosenInlineResult is an inline query result chosen by a User
 967type ChosenInlineResult struct {
 968	ResultID        string    `json:"result_id"`
 969	From            *User     `json:"from"`
 970	Location        *Location `json:"location"`
 971	InlineMessageID string    `json:"inline_message_id"`
 972	Query           string    `json:"query"`
 973}
 974
 975// InputTextMessageContent contains text for displaying
 976// as an inline query result.
 977type InputTextMessageContent struct {
 978	Text                  string `json:"message_text"`
 979	ParseMode             string `json:"parse_mode"`
 980	DisableWebPagePreview bool   `json:"disable_web_page_preview"`
 981}
 982
 983// InputLocationMessageContent contains a location for displaying
 984// as an inline query result.
 985type InputLocationMessageContent struct {
 986	Latitude  float64 `json:"latitude"`
 987	Longitude float64 `json:"longitude"`
 988}
 989
 990// InputVenueMessageContent contains a venue for displaying
 991// as an inline query result.
 992type InputVenueMessageContent struct {
 993	Latitude     float64 `json:"latitude"`
 994	Longitude    float64 `json:"longitude"`
 995	Title        string  `json:"title"`
 996	Address      string  `json:"address"`
 997	FoursquareID string  `json:"foursquare_id"`
 998}
 999
1000// InputContactMessageContent contains a contact for displaying
1001// as an inline query result.
1002type InputContactMessageContent struct {
1003	PhoneNumber string `json:"phone_number"`
1004	FirstName   string `json:"first_name"`
1005	LastName    string `json:"last_name"`
1006	VCard       string `json:"vcard"`
1007}
1008
1009// Invoice contains basic information about an invoice.
1010type Invoice struct {
1011	Title          string `json:"title"`
1012	Description    string `json:"description"`
1013	StartParameter string `json:"start_parameter"`
1014	Currency       string `json:"currency"`
1015	TotalAmount    int    `json:"total_amount"`
1016}
1017
1018// LabeledPrice represents a portion of the price for goods or services.
1019type LabeledPrice struct {
1020	Label  string `json:"label"`
1021	Amount int    `json:"amount"`
1022}
1023
1024// ShippingAddress represents a shipping address.
1025type ShippingAddress struct {
1026	CountryCode string `json:"country_code"`
1027	State       string `json:"state"`
1028	City        string `json:"city"`
1029	StreetLine1 string `json:"street_line1"`
1030	StreetLine2 string `json:"street_line2"`
1031	PostCode    string `json:"post_code"`
1032}
1033
1034// OrderInfo represents information about an order.
1035type OrderInfo struct {
1036	Name            string           `json:"name,omitempty"`
1037	PhoneNumber     string           `json:"phone_number,omitempty"`
1038	Email           string           `json:"email,omitempty"`
1039	ShippingAddress *ShippingAddress `json:"shipping_address,omitempty"`
1040}
1041
1042// ShippingOption represents one shipping option.
1043type ShippingOption struct {
1044	ID     string         `json:"id"`
1045	Title  string         `json:"title"`
1046	Prices []LabeledPrice `json:"prices"`
1047}
1048
1049// SuccessfulPayment contains basic information about a successful payment.
1050type SuccessfulPayment struct {
1051	Currency                string     `json:"currency"`
1052	TotalAmount             int        `json:"total_amount"`
1053	InvoicePayload          string     `json:"invoice_payload"`
1054	ShippingOptionID        string     `json:"shipping_option_id,omitempty"`
1055	OrderInfo               *OrderInfo `json:"order_info,omitempty"`
1056	TelegramPaymentChargeID string     `json:"telegram_payment_charge_id"`
1057	ProviderPaymentChargeID string     `json:"provider_payment_charge_id"`
1058}
1059
1060// ShippingQuery contains information about an incoming shipping query.
1061type ShippingQuery struct {
1062	ID              string           `json:"id"`
1063	From            *User            `json:"from"`
1064	InvoicePayload  string           `json:"invoice_payload"`
1065	ShippingAddress *ShippingAddress `json:"shipping_address"`
1066}
1067
1068// PreCheckoutQuery contains information about an incoming pre-checkout query.
1069type PreCheckoutQuery struct {
1070	ID               string     `json:"id"`
1071	From             *User      `json:"from"`
1072	Currency         string     `json:"currency"`
1073	TotalAmount      int        `json:"total_amount"`
1074	InvoicePayload   string     `json:"invoice_payload"`
1075	ShippingOptionID string     `json:"shipping_option_id,omitempty"`
1076	OrderInfo        *OrderInfo `json:"order_info,omitempty"`
1077}
1078
1079// StickerSet is a collection of stickers.
1080type StickerSet struct {
1081	Name          string     `json:"name"`
1082	Title         string     `json:"title"`
1083	IsAnimated    bool       `json:"is_animated"`
1084	ContainsMasks bool       `json:"contains_masks"`
1085	Stickers      []Sticker  `json:"stickers"`
1086	Thumb         *PhotoSize `json:"thumb"`
1087}
1088
1089// BotCommand represents Telegram's understanding of a command.
1090type BotCommand struct {
1091	Command     string `json:"command"`
1092	Description string `json:"description"`
1093}
1094
1095// BaseInputMedia is a base type for the InputMedia types.
1096type BaseInputMedia struct {
1097	Type      string `json:"type"`
1098	Media     string `json:"media"`
1099	Caption   string `json:"caption"`
1100	ParseMode string `json:"parse_mode"`
1101}
1102
1103// InputMediaPhoto is a photo to send as part of a media group.
1104type InputMediaPhoto struct {
1105	BaseInputMedia
1106}
1107
1108// InputMediaVideo is a video to send as part of a media group.
1109type InputMediaVideo struct {
1110	BaseInputMedia
1111	Width             int  `json:"width"`
1112	Height            int  `json:"height"`
1113	Duration          int  `json:"duration"`
1114	SupportsStreaming bool `json:"supports_streaming"`
1115}
1116
1117// InputMediaAnimation is an animation to send as part of a media group.
1118type InputMediaAnimation struct {
1119	BaseInputMedia
1120	Width    int `json:"width"`
1121	Height   int `json:"height"`
1122	Duration int `json:"duration"`
1123}
1124
1125// InputMediaAudio is a audio to send as part of a media group.
1126type InputMediaAudio struct {
1127	BaseInputMedia
1128	Duration  int    `json:"duration"`
1129	Performer string `json:"performer"`
1130	Title     string `json:"title"`
1131}
1132
1133// InputMediaDocument is a audio to send as part of a media group.
1134type InputMediaDocument struct {
1135	BaseInputMedia
1136}
1137
1138// Error is an error containing extra information returned by the Telegram API.
1139type Error struct {
1140	Code    int
1141	Message string
1142	ResponseParameters
1143}
1144
1145// Error message string.
1146func (e Error) Error() string {
1147	return e.Message
1148}