all repos — telegram-bot-api @ e6fdc8e02a7cb652a10914ae21dd73483c193ca1

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