all repos — telegram-bot-api @ 9d6e221a006b09fb3435a69e7c2a5bc05f96892e

Golang bindings for the Telegram Bot API

configs.go (view raw)

  1package tgbotapi
  2
  3import (
  4	"encoding/json"
  5	"io"
  6	"net/url"
  7	"strconv"
  8)
  9
 10// Telegram constants
 11const (
 12	// APIEndpoint is the endpoint for all API methods,
 13	// with formatting for Sprintf.
 14	APIEndpoint = "https://api.telegram.org/bot%s/%s"
 15	// FileEndpoint is the endpoint for downloading a file from Telegram.
 16	FileEndpoint = "https://api.telegram.org/file/bot%s/%s"
 17)
 18
 19// Constant values for ChatActions
 20const (
 21	ChatTyping         = "typing"
 22	ChatUploadPhoto    = "upload_photo"
 23	ChatRecordVideo    = "record_video"
 24	ChatUploadVideo    = "upload_video"
 25	ChatRecordAudio    = "record_audio"
 26	ChatUploadAudio    = "upload_audio"
 27	ChatUploadDocument = "upload_document"
 28	ChatFindLocation   = "find_location"
 29)
 30
 31// API errors
 32const (
 33	// ErrAPIForbidden happens when a token is bad
 34	ErrAPIForbidden = "forbidden"
 35)
 36
 37// Constant values for ParseMode in MessageConfig
 38const (
 39	ModeMarkdown = "Markdown"
 40	ModeHTML     = "HTML"
 41)
 42
 43// Library errors
 44const (
 45	// ErrBadFileType happens when you pass an unknown type
 46	ErrBadFileType = "bad file type"
 47	ErrBadURL      = "bad or empty url"
 48)
 49
 50// Chattable is any config type that can be sent.
 51type Chattable interface {
 52	values() (url.Values, error)
 53	method() string
 54}
 55
 56// Fileable is any config type that can be sent that includes a file.
 57type Fileable interface {
 58	Chattable
 59	params() (map[string]string, error)
 60	name() string
 61	getFile() interface{}
 62	useExistingFile() bool
 63}
 64
 65// BaseChat is base type for all chat config types.
 66type BaseChat struct {
 67	ChatID              int64 // required
 68	ChannelUsername     string
 69	ReplyToMessageID    int
 70	ReplyMarkup         interface{}
 71	DisableNotification bool
 72}
 73
 74// values returns url.Values representation of BaseChat
 75func (chat *BaseChat) values() (url.Values, error) {
 76	v := url.Values{}
 77	if chat.ChannelUsername != "" {
 78		v.Add("chat_id", chat.ChannelUsername)
 79	} else {
 80		v.Add("chat_id", strconv.FormatInt(chat.ChatID, 10))
 81	}
 82
 83	if chat.ReplyToMessageID != 0 {
 84		v.Add("reply_to_message_id", strconv.Itoa(chat.ReplyToMessageID))
 85	}
 86
 87	if chat.ReplyMarkup != nil {
 88		data, err := json.Marshal(chat.ReplyMarkup)
 89		if err != nil {
 90			return v, err
 91		}
 92
 93		v.Add("reply_markup", string(data))
 94	}
 95
 96	v.Add("disable_notification", strconv.FormatBool(chat.DisableNotification))
 97
 98	return v, nil
 99}
100
101// BaseFile is a base type for all file config types.
102type BaseFile struct {
103	BaseChat
104	File        interface{}
105	FileID      string
106	UseExisting bool
107	MimeType    string
108	FileSize    int
109}
110
111// params returns a map[string]string representation of BaseFile.
112func (file BaseFile) params() (map[string]string, error) {
113	params := make(map[string]string)
114
115	if file.ChannelUsername != "" {
116		params["chat_id"] = file.ChannelUsername
117	} else {
118		params["chat_id"] = strconv.FormatInt(file.ChatID, 10)
119	}
120
121	if file.ReplyToMessageID != 0 {
122		params["reply_to_message_id"] = strconv.Itoa(file.ReplyToMessageID)
123	}
124
125	if file.ReplyMarkup != nil {
126		data, err := json.Marshal(file.ReplyMarkup)
127		if err != nil {
128			return params, err
129		}
130
131		params["reply_markup"] = string(data)
132	}
133
134	if file.MimeType != "" {
135		params["mime_type"] = file.MimeType
136	}
137
138	if file.FileSize > 0 {
139		params["file_size"] = strconv.Itoa(file.FileSize)
140	}
141
142	params["disable_notification"] = strconv.FormatBool(file.DisableNotification)
143
144	return params, nil
145}
146
147// getFile returns the file.
148func (file BaseFile) getFile() interface{} {
149	return file.File
150}
151
152// useExistingFile returns if the BaseFile has already been uploaded.
153func (file BaseFile) useExistingFile() bool {
154	return file.UseExisting
155}
156
157// BaseEdit is base type of all chat edits.
158type BaseEdit struct {
159	ChatID          int64
160	ChannelUsername string
161	MessageID       int
162	InlineMessageID string
163	ReplyMarkup     *InlineKeyboardMarkup
164}
165
166func (edit BaseEdit) values() (url.Values, error) {
167	v := url.Values{}
168
169	if edit.InlineMessageID == "" {
170		if edit.ChannelUsername != "" {
171			v.Add("chat_id", edit.ChannelUsername)
172		} else {
173			v.Add("chat_id", strconv.FormatInt(edit.ChatID, 10))
174		}
175		v.Add("message_id", strconv.Itoa(edit.MessageID))
176	} else {
177		v.Add("inline_message_id", edit.InlineMessageID)
178	}
179
180	if edit.ReplyMarkup != nil {
181		data, err := json.Marshal(edit.ReplyMarkup)
182		if err != nil {
183			return v, err
184		}
185		v.Add("reply_markup", string(data))
186	}
187
188	return v, nil
189}
190
191// MessageConfig contains information about a SendMessage request.
192type MessageConfig struct {
193	BaseChat
194	Text                  string
195	ParseMode             string
196	DisableWebPagePreview bool
197}
198
199// values returns a url.Values representation of MessageConfig.
200func (config MessageConfig) values() (url.Values, error) {
201	v, err := config.BaseChat.values()
202	if err != nil {
203		data := url.Values{}
204		return data, err
205	}
206	v.Add("text", config.Text)
207	v.Add("disable_web_page_preview", strconv.FormatBool(config.DisableWebPagePreview))
208	if config.ParseMode != "" {
209		v.Add("parse_mode", config.ParseMode)
210	}
211
212	return v, nil
213}
214
215// method returns Telegram API method name for sending Message.
216func (config MessageConfig) method() string {
217	return "sendMessage"
218}
219
220// ForwardConfig contains information about a ForwardMessage request.
221type ForwardConfig struct {
222	BaseChat
223	FromChatID          int64 // required
224	FromChannelUsername string
225	MessageID           int // required
226}
227
228// values returns a url.Values representation of ForwardConfig.
229func (config ForwardConfig) values() (url.Values, error) {
230	v, err := config.BaseChat.values()
231	if err != nil {
232		data := url.Values{}
233		return data, err
234	}
235	v.Add("from_chat_id", strconv.FormatInt(config.FromChatID, 10))
236	v.Add("message_id", strconv.Itoa(config.MessageID))
237	return v, nil
238}
239
240// method returns Telegram API method name for sending Forward.
241func (config ForwardConfig) method() string {
242	return "forwardMessage"
243}
244
245// PhotoConfig contains information about a SendPhoto request.
246type PhotoConfig struct {
247	BaseFile
248	Caption string
249}
250
251// Params returns a map[string]string representation of PhotoConfig.
252func (config PhotoConfig) params() (map[string]string, error) {
253	params, _ := config.BaseFile.params()
254
255	if config.Caption != "" {
256		params["caption"] = config.Caption
257	}
258
259	return params, nil
260}
261
262// Values returns a url.Values representation of PhotoConfig.
263func (config PhotoConfig) values() (url.Values, error) {
264	v, _ := config.BaseChat.values()
265
266	v.Add(config.name(), config.FileID)
267	if config.Caption != "" {
268		v.Add("caption", config.Caption)
269	}
270	return v, nil
271}
272
273// name returns the field name for the Photo.
274func (config PhotoConfig) name() string {
275	return "photo"
276}
277
278// method returns Telegram API method name for sending Photo.
279func (config PhotoConfig) method() string {
280	return "sendPhoto"
281}
282
283// AudioConfig contains information about a SendAudio request.
284type AudioConfig struct {
285	BaseFile
286	Caption   string
287	Duration  int
288	Performer string
289	Title     string
290}
291
292// values returns a url.Values representation of AudioConfig.
293func (config AudioConfig) values() (url.Values, error) {
294	v, err := config.BaseChat.values()
295	if err != nil {
296		data := url.Values{}
297		return data, err
298	}
299
300	v.Add(config.name(), config.FileID)
301	if config.Duration != 0 {
302		v.Add("duration", strconv.Itoa(config.Duration))
303	}
304
305	if config.Performer != "" {
306		v.Add("performer", config.Performer)
307	}
308	if config.Title != "" {
309		v.Add("title", config.Title)
310	}
311	if config.Caption != "" {
312		v.Add("caption", config.Caption)
313	}
314
315	return v, nil
316}
317
318// params returns a map[string]string representation of AudioConfig.
319func (config AudioConfig) params() (map[string]string, error) {
320	params, _ := config.BaseFile.params()
321
322	if config.Duration != 0 {
323		params["duration"] = strconv.Itoa(config.Duration)
324	}
325
326	if config.Performer != "" {
327		params["performer"] = config.Performer
328	}
329	if config.Title != "" {
330		params["title"] = config.Title
331	}
332	if config.Caption != "" {
333		params["caption"] = config.Caption
334	}
335
336	return params, nil
337}
338
339// name returns the field name for the Audio.
340func (config AudioConfig) name() string {
341	return "audio"
342}
343
344// method returns Telegram API method name for sending Audio.
345func (config AudioConfig) method() string {
346	return "sendAudio"
347}
348
349// DocumentConfig contains information about a SendDocument request.
350type DocumentConfig struct {
351	BaseFile
352}
353
354// values returns a url.Values representation of DocumentConfig.
355func (config DocumentConfig) values() (url.Values, error) {
356	v, err := config.BaseChat.values()
357	if err != nil {
358		data := url.Values{}
359		return data, err
360	}
361
362	v.Add(config.name(), config.FileID)
363
364	return v, nil
365}
366
367// params returns a map[string]string representation of DocumentConfig.
368func (config DocumentConfig) params() (map[string]string, error) {
369	params, _ := config.BaseFile.params()
370
371	return params, nil
372}
373
374// name returns the field name for the Document.
375func (config DocumentConfig) name() string {
376	return "document"
377}
378
379// method returns Telegram API method name for sending Document.
380func (config DocumentConfig) method() string {
381	return "sendDocument"
382}
383
384// StickerConfig contains information about a SendSticker request.
385type StickerConfig struct {
386	BaseFile
387}
388
389// values returns a url.Values representation of StickerConfig.
390func (config StickerConfig) values() (url.Values, error) {
391	v, err := config.BaseChat.values()
392	if err != nil {
393		data := url.Values{}
394		return data, err
395	}
396
397	v.Add(config.name(), config.FileID)
398
399	return v, nil
400}
401
402// params returns a map[string]string representation of StickerConfig.
403func (config StickerConfig) params() (map[string]string, error) {
404	params, _ := config.BaseFile.params()
405
406	return params, nil
407}
408
409// name returns the field name for the Sticker.
410func (config StickerConfig) name() string {
411	return "sticker"
412}
413
414// method returns Telegram API method name for sending Sticker.
415func (config StickerConfig) method() string {
416	return "sendSticker"
417}
418
419// VideoConfig contains information about a SendVideo request.
420type VideoConfig struct {
421	BaseFile
422	Duration int
423	Caption  string
424}
425
426// values returns a url.Values representation of VideoConfig.
427func (config VideoConfig) values() (url.Values, error) {
428	v, err := config.BaseChat.values()
429	if err != nil {
430		data := url.Values{}
431		return data, err
432	}
433
434	v.Add(config.name(), config.FileID)
435	if config.Duration != 0 {
436		v.Add("duration", strconv.Itoa(config.Duration))
437	}
438	if config.Caption != "" {
439		v.Add("caption", config.Caption)
440	}
441
442	return v, nil
443}
444
445// params returns a map[string]string representation of VideoConfig.
446func (config VideoConfig) params() (map[string]string, error) {
447	params, _ := config.BaseFile.params()
448
449	return params, nil
450}
451
452// name returns the field name for the Video.
453func (config VideoConfig) name() string {
454	return "video"
455}
456
457// method returns Telegram API method name for sending Video.
458func (config VideoConfig) method() string {
459	return "sendVideo"
460}
461
462// VoiceConfig contains information about a SendVoice request.
463type VoiceConfig struct {
464	BaseFile
465	Caption  string
466	Duration int
467}
468
469// values returns a url.Values representation of VoiceConfig.
470func (config VoiceConfig) values() (url.Values, error) {
471	v, err := config.BaseChat.values()
472	if err != nil {
473		data := url.Values{}
474		return data, err
475	}
476
477	v.Add(config.name(), config.FileID)
478	if config.Duration != 0 {
479		v.Add("duration", strconv.Itoa(config.Duration))
480	}
481
482	return v, nil
483}
484
485// params returns a map[string]string representation of VoiceConfig.
486func (config VoiceConfig) params() (map[string]string, error) {
487	params, _ := config.BaseFile.params()
488
489	if config.Duration != 0 {
490		params["duration"] = strconv.Itoa(config.Duration)
491	}
492
493	return params, nil
494}
495
496// name returns the field name for the Voice.
497func (config VoiceConfig) name() string {
498	return "voice"
499}
500
501// method returns Telegram API method name for sending Voice.
502func (config VoiceConfig) method() string {
503	return "sendVoice"
504}
505
506// LocationConfig contains information about a SendLocation request.
507type LocationConfig struct {
508	BaseChat
509	Latitude  float64 // required
510	Longitude float64 // required
511}
512
513// values returns a url.Values representation of LocationConfig.
514func (config LocationConfig) values() (url.Values, error) {
515	v, err := config.BaseChat.values()
516	if err != nil {
517		data := url.Values{}
518		return data, err
519	}
520
521	v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
522	v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
523
524	return v, nil
525}
526
527// method returns Telegram API method name for sending Location.
528func (config LocationConfig) method() string {
529	return "sendLocation"
530}
531
532// VenueConfig contains information about a SendVenue request.
533type VenueConfig struct {
534	BaseChat
535	Latitude     float64 // required
536	Longitude    float64 // required
537	Title        string  // required
538	Address      string  // required
539	FoursquareID string
540}
541
542func (config VenueConfig) values() (url.Values, error) {
543	v, err := config.BaseChat.values()
544	if err != nil {
545		data := url.Values{}
546		return data, err
547	}
548
549	v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
550	v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
551	v.Add("title", config.Title)
552	v.Add("address", config.Address)
553	if config.FoursquareID != "" {
554		v.Add("foursquare_id", config.FoursquareID)
555	}
556
557	return v, nil
558}
559
560func (config VenueConfig) method() string {
561	return "sendVenue"
562}
563
564// ContactConfig allows you to send a contact.
565type ContactConfig struct {
566	BaseChat
567	PhoneNumber string
568	FirstName   string
569	LastName    string
570}
571
572func (config ContactConfig) values() (url.Values, error) {
573	v, err := config.BaseChat.values()
574	if err != nil {
575		data := url.Values{}
576		return data, err
577	}
578
579	v.Add("phone_number", config.PhoneNumber)
580	v.Add("first_name", config.FirstName)
581	v.Add("last_name", config.LastName)
582
583	return v, nil
584}
585
586func (config ContactConfig) method() string {
587	return "sendContact"
588}
589
590// GameConfig allows you to send a game.
591type GameConfig struct {
592	BaseChat
593	GameShortName string
594}
595
596func (config GameConfig) values() (url.Values, error) {
597	v, err := config.BaseChat.values()
598	if err != nil {
599		data := url.Values{}
600		return data, err
601	}
602
603	v.Add("game_short_name", config.GameShortName)
604
605	return v, nil
606}
607
608func (config GameConfig) method() string {
609	return "sendGame"
610}
611
612// SetGameScoreConfig allows you to update the game score in a chat.
613type SetGameScoreConfig struct {
614	UserID             int
615	Score              int
616	Force              bool
617	DisableEditMessage bool
618	ChatID             int
619	ChannelUsername    string
620	MessageID          int
621	InlineMessageID    string
622}
623
624func (config SetGameScoreConfig) values() (url.Values, error) {
625	v := url.Values{}
626
627	v.Add("user_id", strconv.Itoa(config.UserID))
628	v.Add("score", strconv.Itoa(config.Score))
629	if config.InlineMessageID == "" {
630		if config.ChannelUsername == "" {
631			v.Add("chat_id", strconv.Itoa(config.ChatID))
632		} else {
633			v.Add("chat_id", config.ChannelUsername)
634		}
635		v.Add("message_id", strconv.Itoa(config.MessageID))
636	} else {
637		v.Add("inline_message_id", config.InlineMessageID)
638	}
639	v.Add("disable_edit_message", strconv.FormatBool(config.DisableEditMessage))
640
641	return v, nil
642}
643
644func (config SetGameScoreConfig) method() string {
645	return "setGameScore"
646}
647
648// GetGameHighScoresConfig allows you to fetch the high scores for a game.
649type GetGameHighScoresConfig struct {
650	UserID          int
651	ChatID          int
652	ChannelUsername string
653	MessageID       int
654	InlineMessageID string
655}
656
657func (config GetGameHighScoresConfig) values() (url.Values, error) {
658	v := url.Values{}
659
660	v.Add("user_id", strconv.Itoa(config.UserID))
661	if config.InlineMessageID == "" {
662		if config.ChannelUsername == "" {
663			v.Add("chat_id", strconv.Itoa(config.ChatID))
664		} else {
665			v.Add("chat_id", config.ChannelUsername)
666		}
667		v.Add("message_id", strconv.Itoa(config.MessageID))
668	} else {
669		v.Add("inline_message_id", config.InlineMessageID)
670	}
671
672	return v, nil
673}
674
675func (config GetGameHighScoresConfig) method() string {
676	return "getGameHighScores"
677}
678
679// ChatActionConfig contains information about a SendChatAction request.
680type ChatActionConfig struct {
681	BaseChat
682	Action string // required
683}
684
685// values returns a url.Values representation of ChatActionConfig.
686func (config ChatActionConfig) values() (url.Values, error) {
687	v, err := config.BaseChat.values()
688	if err != nil {
689		data := url.Values{}
690		return data, err
691	}
692	v.Add("action", config.Action)
693	return v, nil
694}
695
696// method returns Telegram API method name for sending ChatAction.
697func (config ChatActionConfig) method() string {
698	return "sendChatAction"
699}
700
701// EditMessageTextConfig allows you to modify the text in a message.
702type EditMessageTextConfig struct {
703	BaseEdit
704	Text                  string
705	ParseMode             string
706	DisableWebPagePreview bool
707}
708
709func (config EditMessageTextConfig) values() (url.Values, error) {
710	v, err := config.BaseEdit.values()
711	if err != nil {
712		data := url.Values{}
713		return data, err
714	}
715
716	v.Add("text", config.Text)
717	v.Add("parse_mode", config.ParseMode)
718	v.Add("disable_web_page_preview", strconv.FormatBool(config.DisableWebPagePreview))
719
720	return v, nil
721}
722
723func (config EditMessageTextConfig) method() string {
724	return "editMessageText"
725}
726
727// EditMessageCaptionConfig allows you to modify the caption of a message.
728type EditMessageCaptionConfig struct {
729	BaseEdit
730	Caption string
731}
732
733func (config EditMessageCaptionConfig) values() (url.Values, error) {
734	v, _ := config.BaseEdit.values()
735
736	v.Add("caption", config.Caption)
737
738	return v, nil
739}
740
741func (config EditMessageCaptionConfig) method() string {
742	return "editMessageCaption"
743}
744
745// EditMessageReplyMarkupConfig allows you to modify the reply markup
746// of a message.
747type EditMessageReplyMarkupConfig struct {
748	BaseEdit
749}
750
751func (config EditMessageReplyMarkupConfig) values() (url.Values, error) {
752	return config.BaseEdit.values()
753}
754
755func (config EditMessageReplyMarkupConfig) method() string {
756	return "editMessageReplyMarkup"
757}
758
759// UserProfilePhotosConfig contains information about a
760// GetUserProfilePhotos request.
761type UserProfilePhotosConfig struct {
762	UserID int
763	Offset int
764	Limit  int
765}
766
767// FileConfig has information about a file hosted on Telegram.
768type FileConfig struct {
769	FileID string
770}
771
772// UpdateConfig contains information about a GetUpdates request.
773type UpdateConfig struct {
774	Offset  int
775	Limit   int
776	Timeout int
777}
778
779// WebhookConfig contains information about a SetWebhook request.
780type WebhookConfig struct {
781	URL         *url.URL
782	Certificate interface{}
783}
784
785// FileBytes contains information about a set of bytes to upload
786// as a File.
787type FileBytes struct {
788	Name  string
789	Bytes []byte
790}
791
792// FileReader contains information about a reader to upload as a File.
793// If Size is -1, it will read the entire Reader into memory to
794// calculate a Size.
795type FileReader struct {
796	Name   string
797	Reader io.Reader
798	Size   int64
799}
800
801// InlineConfig contains information on making an InlineQuery response.
802type InlineConfig struct {
803	InlineQueryID     string        `json:"inline_query_id"`
804	Results           []interface{} `json:"results"`
805	CacheTime         int           `json:"cache_time"`
806	IsPersonal        bool          `json:"is_personal"`
807	NextOffset        string        `json:"next_offset"`
808	SwitchPMText      string        `json:"switch_pm_text"`
809	SwitchPMParameter string        `json:"switch_pm_parameter"`
810}
811
812// CallbackConfig contains information on making a CallbackQuery response.
813type CallbackConfig struct {
814	CallbackQueryID string `json:"callback_query_id"`
815	Text            string `json:"text"`
816	ShowAlert       bool   `json:"show_alert"`
817	URL             string `json:"url"`
818	CacheTime       int    `json:"cache_time"`
819}
820
821// ChatMemberConfig contains information about a user in a chat for use
822// with administrative functions such as kicking or unbanning a user.
823type ChatMemberConfig struct {
824	ChatID             int64
825	SuperGroupUsername string
826	UserID             int
827}
828
829// ChatConfig contains information about getting information on a chat.
830type ChatConfig struct {
831	ChatID             int64
832	SuperGroupUsername string
833}
834
835// ChatConfigWithUser contains information about getting information on
836// a specific user within a chat.
837type ChatConfigWithUser struct {
838	ChatID             int64
839	SuperGroupUsername string
840	UserID             int
841}