all repos — telegram-bot-api @ 047d7356559ea551e9d3dff3933c4c2aa9fd67ad

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