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