all repos — telegram-bot-api @ 4a2c8c4547a868841c1ec088302b23b59443de2b

Golang bindings for the Telegram Bot API

types.go (view raw)

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