all repos — telegram-bot-api @ 133755f959377fdf29fc230258d9215faa29cd6f

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