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