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}
20
21// Update is an update response, from GetUpdates.
22type Update struct {
23 UpdateID int `json:"update_id"`
24 Message *Message `json:"message"`
25 EditedMessage *Message `json:"edited_message"`
26 InlineQuery *InlineQuery `json:"inline_query"`
27 ChosenInlineResult *ChosenInlineResult `json:"chosen_inline_result"`
28 CallbackQuery *CallbackQuery `json:"callback_query"`
29}
30
31// User is a user on Telegram.
32type User struct {
33 ID int `json:"id"`
34 FirstName string `json:"first_name"`
35 LastName string `json:"last_name"` // optional
36 UserName string `json:"username"` // optional
37}
38
39// String displays a simple text version of a user.
40//
41// It is normally a user's username, but falls back to a first/last
42// name as available.
43func (u *User) String() string {
44 if u.UserName != "" {
45 return u.UserName
46 }
47
48 name := u.FirstName
49 if u.LastName != "" {
50 name += " " + u.LastName
51 }
52
53 return name
54}
55
56// GroupChat is a group chat.
57type GroupChat struct {
58 ID int `json:"id"`
59 Title string `json:"title"`
60}
61
62// Chat contains information about the place a message was sent.
63type Chat struct {
64 ID int64 `json:"id"`
65 Type string `json:"type"`
66 Title string `json:"title"` // optional
67 UserName string `json:"username"` // optional
68 FirstName string `json:"first_name"` // optional
69 LastName string `json:"last_name"` // optional
70}
71
72// IsPrivate returns if the Chat is a private conversation.
73func (c Chat) IsPrivate() bool {
74 return c.Type == "private"
75}
76
77// IsGroup returns if the Chat is a group.
78func (c Chat) IsGroup() bool {
79 return c.Type == "group"
80}
81
82// IsSuperGroup returns if the Chat is a supergroup.
83func (c Chat) IsSuperGroup() bool {
84 return c.Type == "supergroup"
85}
86
87// IsChannel returns if the Chat is a channel.
88func (c Chat) IsChannel() bool {
89 return c.Type == "channel"
90}
91
92// ChatConfig returns a ChatConfig struct for chat related methods.
93func (c Chat) ChatConfig() ChatConfig {
94 return ChatConfig{ChatID: c.ID}
95}
96
97// Message is returned by almost every request, and contains data about
98// almost anything.
99type Message struct {
100 MessageID int `json:"message_id"`
101 From *User `json:"from"` // optional
102 Date int `json:"date"`
103 Chat *Chat `json:"chat"`
104 ForwardFrom *User `json:"forward_from"` // optional
105 ForwardFromChat *Chat `json:"forward_from_chat"` // optional
106 ForwardDate int `json:"forward_date"` // optional
107 ReplyToMessage *Message `json:"reply_to_message"` // optional
108 EditDate int `json:"edit_date"` // optional
109 Text string `json:"text"` // optional
110 Entities *[]MessageEntity `json:"entities"` // optional
111 Audio *Audio `json:"audio"` // optional
112 Document *Document `json:"document"` // optional
113 Photo *[]PhotoSize `json:"photo"` // optional
114 Sticker *Sticker `json:"sticker"` // optional
115 Video *Video `json:"video"` // optional
116 Voice *Voice `json:"voice"` // optional
117 Caption string `json:"caption"` // optional
118 Contact *Contact `json:"contact"` // optional
119 Location *Location `json:"location"` // optional
120 Venue *Venue `json:"venue"` // optional
121 NewChatMember *User `json:"new_chat_member"` // optional
122 LeftChatMember *User `json:"left_chat_member"` // optional
123 NewChatTitle string `json:"new_chat_title"` // optional
124 NewChatPhoto *[]PhotoSize `json:"new_chat_photo"` // optional
125 DeleteChatPhoto bool `json:"delete_chat_photo"` // optional
126 GroupChatCreated bool `json:"group_chat_created"` // optional
127 SuperGroupChatCreated bool `json:"supergroup_chat_created"` // optional
128 ChannelChatCreated bool `json:"channel_chat_created"` // optional
129 MigrateToChatID int64 `json:"migrate_to_chat_id"` // optional
130 MigrateFromChatID int64 `json:"migrate_from_chat_id"` // optional
131 PinnedMessage *Message `json:"pinned_message"` // optional
132}
133
134// Time converts the message timestamp into a Time.
135func (m *Message) Time() time.Time {
136 return time.Unix(int64(m.Date), 0)
137}
138
139// IsCommand returns true if message starts with '/'.
140func (m *Message) IsCommand() bool {
141 return m.Text != "" && m.Text[0] == '/'
142}
143
144// Command checks if the message was a command and if it was, returns the
145// command. If the Message was not a command, it returns an empty string.
146//
147// If the command contains the at bot syntax, it removes the bot name.
148func (m *Message) Command() string {
149 if !m.IsCommand() {
150 return ""
151 }
152
153 command := strings.SplitN(m.Text, " ", 2)[0][1:]
154
155 if i := strings.Index(command, "@"); i != -1 {
156 command = command[:i]
157 }
158
159 return command
160}
161
162// CommandArguments checks if the message was a command and if it was,
163// returns all text after the command name. If the Message was not a
164// command, it returns an empty string.
165func (m *Message) CommandArguments() string {
166 if !m.IsCommand() {
167 return ""
168 }
169
170 split := strings.SplitN(m.Text, " ", 2)
171 if len(split) != 2 {
172 return ""
173 }
174
175 return strings.SplitN(m.Text, " ", 2)[1]
176}
177
178// MessageEntity contains information about data in a Message.
179type MessageEntity struct {
180 Type string `json:"type"`
181 Offset int `json:"offset"`
182 Length int `json:"length"`
183 URL string `json:"url"` // optional
184 User *User `json:"user"` // optional
185}
186
187// ParseURL attempts to parse a URL contained within a MessageEntity.
188func (entity MessageEntity) ParseURL() (*url.URL, error) {
189 if entity.URL == "" {
190 return nil, errors.New(ErrBadURL)
191 }
192
193 return url.Parse(entity.URL)
194}
195
196// PhotoSize contains information about photos.
197type PhotoSize struct {
198 FileID string `json:"file_id"`
199 Width int `json:"width"`
200 Height int `json:"height"`
201 FileSize int `json:"file_size"` // optional
202}
203
204// Audio contains information about audio.
205type Audio struct {
206 FileID string `json:"file_id"`
207 Duration int `json:"duration"`
208 Performer string `json:"performer"` // optional
209 Title string `json:"title"` // optional
210 MimeType string `json:"mime_type"` // optional
211 FileSize int `json:"file_size"` // optional
212}
213
214// Document contains information about a document.
215type Document struct {
216 FileID string `json:"file_id"`
217 Thumbnail *PhotoSize `json:"thumb"` // optional
218 FileName string `json:"file_name"` // optional
219 MimeType string `json:"mime_type"` // optional
220 FileSize int `json:"file_size"` // optional
221}
222
223// Sticker contains information about a sticker.
224type Sticker struct {
225 FileID string `json:"file_id"`
226 Width int `json:"width"`
227 Height int `json:"height"`
228 Thumbnail *PhotoSize `json:"thumb"` // optional
229 Emoji string `json:"emoji"` // optional
230 FileSize int `json:"file_size"` // optional
231}
232
233// Video contains information about a video.
234type Video struct {
235 FileID string `json:"file_id"`
236 Width int `json:"width"`
237 Height int `json:"height"`
238 Duration int `json:"duration"`
239 Thumbnail *PhotoSize `json:"thumb"` // optional
240 MimeType string `json:"mime_type"` // optional
241 FileSize int `json:"file_size"` // optional
242}
243
244// Voice contains information about a voice.
245type Voice struct {
246 FileID string `json:"file_id"`
247 Duration int `json:"duration"`
248 MimeType string `json:"mime_type"` // optional
249 FileSize int `json:"file_size"` // optional
250}
251
252// Contact contains information about a contact.
253//
254// Note that LastName and UserID may be empty.
255type Contact struct {
256 PhoneNumber string `json:"phone_number"`
257 FirstName string `json:"first_name"`
258 LastName string `json:"last_name"` // optional
259 UserID int `json:"user_id"` // optional
260}
261
262// Location contains information about a place.
263type Location struct {
264 Longitude float64 `json:"longitude"`
265 Latitude float64 `json:"latitude"`
266}
267
268// Venue contains information about a venue, including its Location.
269type Venue struct {
270 Location Location `json:"location"`
271 Title string `json:"title"`
272 Address string `json:"address"`
273 FoursquareID string `json:"foursquare_id"` // optional
274}
275
276// UserProfilePhotos contains a set of user profile photos.
277type UserProfilePhotos struct {
278 TotalCount int `json:"total_count"`
279 Photos [][]PhotoSize `json:"photos"`
280}
281
282// File contains information about a file to download from Telegram.
283type File struct {
284 FileID string `json:"file_id"`
285 FileSize int `json:"file_size"` // optional
286 FilePath string `json:"file_path"` // optional
287}
288
289// Link returns a full path to the download URL for a File.
290//
291// It requires the Bot Token to create the link.
292func (f *File) Link(token string) string {
293 return fmt.Sprintf(FileEndpoint, token, f.FilePath)
294}
295
296// ReplyKeyboardMarkup allows the Bot to set a custom keyboard.
297type ReplyKeyboardMarkup struct {
298 Keyboard [][]KeyboardButton `json:"keyboard"`
299 ResizeKeyboard bool `json:"resize_keyboard"` // optional
300 OneTimeKeyboard bool `json:"one_time_keyboard"` // optional
301 Selective bool `json:"selective"` // optional
302}
303
304// KeyboardButton is a button within a custom keyboard.
305type KeyboardButton struct {
306 Text string `json:"text"`
307 RequestContact bool `json:"request_contact"`
308 RequestLocation bool `json:"request_location"`
309}
310
311// ReplyKeyboardHide allows the Bot to hide a custom keyboard.
312type ReplyKeyboardHide struct {
313 HideKeyboard bool `json:"hide_keyboard"`
314 Selective bool `json:"selective"` // optional
315}
316
317// InlineKeyboardMarkup is a custom keyboard presented for an inline bot.
318type InlineKeyboardMarkup struct {
319 InlineKeyboard [][]InlineKeyboardButton `json:"inline_keyboard"`
320}
321
322// InlineKeyboardButton is a button within a custom keyboard for
323// inline query responses.
324//
325// Note that some values are references as even an empty string
326// will change behavior.
327type InlineKeyboardButton struct {
328 Text string `json:"text"`
329 URL *string `json:"url,omitempty"` // optional
330 CallbackData *string `json:"callback_data,omitempty"` // optional
331 SwitchInlineQuery *string `json:"switch_inline_query,omitempty"` // optional
332}
333
334// CallbackQuery is data sent when a keyboard button with callback data
335// is clicked.
336type CallbackQuery struct {
337 ID string `json:"id"`
338 From *User `json:"from"`
339 Message *Message `json:"message"` // optional
340 InlineMessageID string `json:"inline_message_id"` // optional
341 Data string `json:"data"` // optional
342}
343
344// ForceReply allows the Bot to have users directly reply to it without
345// additional interaction.
346type ForceReply struct {
347 ForceReply bool `json:"force_reply"`
348 Selective bool `json:"selective"` // optional
349}
350
351// ChatMember is information about a member in a chat.
352type ChatMember struct {
353 User *User `json:"user"`
354 Status string `json:"status"`
355}
356
357// IsCreator returns if the ChatMember was the creator of the chat.
358func (chat ChatMember) IsCreator() bool { return chat.Status == "creator" }
359
360// IsAdministrator returns if the ChatMember is a chat administrator.
361func (chat ChatMember) IsAdministrator() bool { return chat.Status == "administrator" }
362
363// IsMember returns if the ChatMember is a current member of the chat.
364func (chat ChatMember) IsMember() bool { return chat.Status == "member" }
365
366// HasLeft returns if the ChatMember left the chat.
367func (chat ChatMember) HasLeft() bool { return chat.Status == "left" }
368
369// WasKicked returns if the ChatMember was kicked from the chat.
370func (chat ChatMember) WasKicked() bool { return chat.Status == "kicked" }
371
372// InlineQuery is a Query from Telegram for an inline request.
373type InlineQuery struct {
374 ID string `json:"id"`
375 From *User `json:"from"`
376 Location *Location `json:"location"` // optional
377 Query string `json:"query"`
378 Offset string `json:"offset"`
379}
380
381// InlineQueryResultArticle is an inline query response article.
382type InlineQueryResultArticle struct {
383 Type string `json:"type"` // required
384 ID string `json:"id"` // required
385 Title string `json:"title"` // required
386 InputMessageContent interface{} `json:"input_message_content,omitempty"` // required
387 ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
388 URL string `json:"url"`
389 HideURL bool `json:"hide_url"`
390 Description string `json:"description"`
391 ThumbURL string `json:"thumb_url"`
392 ThumbWidth int `json:"thumb_width"`
393 ThumbHeight int `json:"thumb_height"`
394}
395
396// InlineQueryResultPhoto is an inline query response photo.
397type InlineQueryResultPhoto struct {
398 Type string `json:"type"` // required
399 ID string `json:"id"` // required
400 URL string `json:"photo_url"` // required
401 MimeType string `json:"mime_type"`
402 Width int `json:"photo_width"`
403 Height int `json:"photo_height"`
404 ThumbURL string `json:"thumb_url"`
405 Title string `json:"title"`
406 Description string `json:"description"`
407 Caption string `json:"caption"`
408 ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
409 InputMessageContent interface{} `json:"input_message_content,omitempty"`
410}
411
412// InlineQueryResultGIF is an inline query response GIF.
413type InlineQueryResultGIF struct {
414 Type string `json:"type"` // required
415 ID string `json:"id"` // required
416 URL string `json:"gif_url"` // required
417 Width int `json:"gif_width"`
418 Height int `json:"gif_height"`
419 ThumbURL string `json:"thumb_url"`
420 Title string `json:"title"`
421 Caption string `json:"caption"`
422 ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
423 InputMessageContent interface{} `json:"input_message_content,omitempty"`
424}
425
426// InlineQueryResultMPEG4GIF is an inline query response MPEG4 GIF.
427type InlineQueryResultMPEG4GIF struct {
428 Type string `json:"type"` // required
429 ID string `json:"id"` // required
430 URL string `json:"mpeg4_url"` // required
431 Width int `json:"mpeg4_width"`
432 Height int `json:"mpeg4_height"`
433 ThumbURL string `json:"thumb_url"`
434 Title string `json:"title"`
435 Caption string `json:"caption"`
436 ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
437 InputMessageContent interface{} `json:"input_message_content,omitempty"`
438}
439
440// InlineQueryResultVideo is an inline query response video.
441type InlineQueryResultVideo struct {
442 Type string `json:"type"` // required
443 ID string `json:"id"` // required
444 URL string `json:"video_url"` // required
445 MimeType string `json:"mime_type"` // required
446 ThumbURL string `json:"thumb_url"`
447 Title string `json:"title"`
448 Caption string `json:"caption"`
449 Width int `json:"video_width"`
450 Height int `json:"video_height"`
451 Duration int `json:"video_duration"`
452 Description string `json:"description"`
453 ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
454 InputMessageContent interface{} `json:"input_message_content,omitempty"`
455}
456
457// InlineQueryResultAudio is an inline query response audio.
458type InlineQueryResultAudio struct {
459 Type string `json:"type"` // required
460 ID string `json:"id"` // required
461 URL string `json:"audio_url"` // required
462 Title string `json:"title"` // required
463 Performer string `json:"performer"`
464 Duration int `json:"audio_duration"`
465 ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
466 InputMessageContent interface{} `json:"input_message_content,omitempty"`
467}
468
469// InlineQueryResultVoice is an inline query response voice.
470type InlineQueryResultVoice struct {
471 Type string `json:"type"` // required
472 ID string `json:"id"` // required
473 URL string `json:"voice_url"` // required
474 Title string `json:"title"` // required
475 Duration int `json:"voice_duration"`
476 ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
477 InputMessageContent interface{} `json:"input_message_content,omitempty"`
478}
479
480// InlineQueryResultDocument is an inline query response document.
481type InlineQueryResultDocument struct {
482 Type string `json:"type"` // required
483 ID string `json:"id"` // required
484 Title string `json:"title"` // required
485 Caption string `json:"caption"`
486 URL string `json:"document_url"` // required
487 MimeType string `json:"mime_type"` // required
488 Description string `json:"description"`
489 ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
490 InputMessageContent interface{} `json:"input_message_content,omitempty"`
491 ThumbURL string `json:"thumb_url"`
492 ThumbWidth int `json:"thumb_width"`
493 ThumbHeight int `json:"thumb_height"`
494}
495
496// InlineQueryResultLocation is an inline query response location.
497type InlineQueryResultLocation struct {
498 Type string `json:"type"` // required
499 ID string `json:"id"` // required
500 Latitude float64 `json:"latitude"` // required
501 Longitude float64 `json:"longitude"` // required
502 Title string `json:"title"` // required
503 ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
504 InputMessageContent interface{} `json:"input_message_content,omitempty"`
505 ThumbURL string `json:"thumb_url"`
506 ThumbWidth int `json:"thumb_width"`
507 ThumbHeight int `json:"thumb_height"`
508}
509
510// ChosenInlineResult is an inline query result chosen by a User
511type ChosenInlineResult struct {
512 ResultID string `json:"result_id"`
513 From *User `json:"from"`
514 Location *Location `json:"location"`
515 InlineMessageID string `json:"inline_message_id"`
516 Query string `json:"query"`
517}
518
519// InputTextMessageContent contains text for displaying
520// as an inline query result.
521type InputTextMessageContent struct {
522 Text string `json:"message_text"`
523 ParseMode string `json:"parse_mode"`
524 DisableWebPagePreview bool `json:"disable_web_page_preview"`
525}
526
527// InputLocationMessageContent contains a location for displaying
528// as an inline query result.
529type InputLocationMessageContent struct {
530 Latitude float64 `json:"latitude"`
531 Longitude float64 `json:"longitude"`
532}
533
534// InputVenueMessageContent contains a venue for displaying
535// as an inline query result.
536type InputVenueMessageContent struct {
537 Latitude float64 `json:"latitude"`
538 Longitude float64 `json:"longitude"`
539 Title string `json:"title"`
540 Address string `json:"address"`
541 FoursquareID string `json:"foursquare_id"`
542}
543
544// InputContactMessageContent contains a contact for displaying
545// as an inline query result.
546type InputContactMessageContent struct {
547 PhoneNumber string `json:"phone_number"`
548 FirstName string `json:"first_name"`
549 LastName string `json:"last_name"`
550}