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