all repos — telegram-bot-api @ 0a57807db79efce7f6719fbb2c0e0f83fda79aec

Golang bindings for the Telegram Bot API

types.go (view raw)

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