all repos — telegram-bot-api @ f57724f783b167bf0352f706bbaf9d1642572361

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		return v, err
204	}
205	v.Add("text", config.Text)
206	v.Add("disable_web_page_preview", strconv.FormatBool(config.DisableWebPagePreview))
207	if config.ParseMode != "" {
208		v.Add("parse_mode", config.ParseMode)
209	}
210
211	return v, nil
212}
213
214// method returns Telegram API method name for sending Message.
215func (config MessageConfig) method() string {
216	return "sendMessage"
217}
218
219// ForwardConfig contains information about a ForwardMessage request.
220type ForwardConfig struct {
221	BaseChat
222	FromChatID          int64 // required
223	FromChannelUsername string
224	MessageID           int // required
225}
226
227// values returns a url.Values representation of ForwardConfig.
228func (config ForwardConfig) values() (url.Values, error) {
229	v, err := config.BaseChat.values()
230	if err != nil {
231		return v, err
232	}
233	v.Add("from_chat_id", strconv.FormatInt(config.FromChatID, 10))
234	v.Add("message_id", strconv.Itoa(config.MessageID))
235	return v, nil
236}
237
238// method returns Telegram API method name for sending Forward.
239func (config ForwardConfig) method() string {
240	return "forwardMessage"
241}
242
243// PhotoConfig contains information about a SendPhoto request.
244type PhotoConfig struct {
245	BaseFile
246	Caption string
247}
248
249// Params returns a map[string]string representation of PhotoConfig.
250func (config PhotoConfig) params() (map[string]string, error) {
251	params, _ := config.BaseFile.params()
252
253	if config.Caption != "" {
254		params["caption"] = config.Caption
255	}
256
257	return params, nil
258}
259
260// Values returns a url.Values representation of PhotoConfig.
261func (config PhotoConfig) values() (url.Values, error) {
262	v, err := config.BaseChat.values()
263	if err != nil {
264		return v, err
265	}
266
267	v.Add(config.name(), config.FileID)
268	if config.Caption != "" {
269		v.Add("caption", config.Caption)
270	}
271	return v, nil
272}
273
274// name returns the field name for the Photo.
275func (config PhotoConfig) name() string {
276	return "photo"
277}
278
279// method returns Telegram API method name for sending Photo.
280func (config PhotoConfig) method() string {
281	return "sendPhoto"
282}
283
284// AudioConfig contains information about a SendAudio request.
285type AudioConfig struct {
286	BaseFile
287	Caption   string
288	Duration  int
289	Performer string
290	Title     string
291}
292
293// values returns a url.Values representation of AudioConfig.
294func (config AudioConfig) values() (url.Values, error) {
295	v, err := config.BaseChat.values()
296	if err != nil {
297		return v, 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		return v, err
359	}
360
361	v.Add(config.name(), config.FileID)
362
363	return v, nil
364}
365
366// params returns a map[string]string representation of DocumentConfig.
367func (config DocumentConfig) params() (map[string]string, error) {
368	params, _ := config.BaseFile.params()
369
370	return params, nil
371}
372
373// name returns the field name for the Document.
374func (config DocumentConfig) name() string {
375	return "document"
376}
377
378// method returns Telegram API method name for sending Document.
379func (config DocumentConfig) method() string {
380	return "sendDocument"
381}
382
383// StickerConfig contains information about a SendSticker request.
384type StickerConfig struct {
385	BaseFile
386}
387
388// values returns a url.Values representation of StickerConfig.
389func (config StickerConfig) values() (url.Values, error) {
390	v, err := config.BaseChat.values()
391	if err != nil {
392		return v, err
393	}
394
395	v.Add(config.name(), config.FileID)
396
397	return v, nil
398}
399
400// params returns a map[string]string representation of StickerConfig.
401func (config StickerConfig) params() (map[string]string, error) {
402	params, _ := config.BaseFile.params()
403
404	return params, nil
405}
406
407// name returns the field name for the Sticker.
408func (config StickerConfig) name() string {
409	return "sticker"
410}
411
412// method returns Telegram API method name for sending Sticker.
413func (config StickerConfig) method() string {
414	return "sendSticker"
415}
416
417// VideoConfig contains information about a SendVideo request.
418type VideoConfig struct {
419	BaseFile
420	Duration int
421	Caption  string
422}
423
424// values returns a url.Values representation of VideoConfig.
425func (config VideoConfig) values() (url.Values, error) {
426	v, err := config.BaseChat.values()
427	if err != nil {
428		return v, err
429	}
430
431	v.Add(config.name(), config.FileID)
432	if config.Duration != 0 {
433		v.Add("duration", strconv.Itoa(config.Duration))
434	}
435	if config.Caption != "" {
436		v.Add("caption", config.Caption)
437	}
438
439	return v, nil
440}
441
442// params returns a map[string]string representation of VideoConfig.
443func (config VideoConfig) params() (map[string]string, error) {
444	params, _ := config.BaseFile.params()
445
446	return params, nil
447}
448
449// name returns the field name for the Video.
450func (config VideoConfig) name() string {
451	return "video"
452}
453
454// method returns Telegram API method name for sending Video.
455func (config VideoConfig) method() string {
456	return "sendVideo"
457}
458
459// VoiceConfig contains information about a SendVoice request.
460type VoiceConfig struct {
461	BaseFile
462	Caption  string
463	Duration int
464}
465
466// values returns a url.Values representation of VoiceConfig.
467func (config VoiceConfig) values() (url.Values, error) {
468	v, err := config.BaseChat.values()
469	if err != nil {
470		return v, err
471	}
472
473	v.Add(config.name(), config.FileID)
474	if config.Duration != 0 {
475		v.Add("duration", strconv.Itoa(config.Duration))
476	}
477
478	return v, nil
479}
480
481// params returns a map[string]string representation of VoiceConfig.
482func (config VoiceConfig) params() (map[string]string, error) {
483	params, _ := config.BaseFile.params()
484
485	if config.Duration != 0 {
486		params["duration"] = strconv.Itoa(config.Duration)
487	}
488
489	return params, nil
490}
491
492// name returns the field name for the Voice.
493func (config VoiceConfig) name() string {
494	return "voice"
495}
496
497// method returns Telegram API method name for sending Voice.
498func (config VoiceConfig) method() string {
499	return "sendVoice"
500}
501
502// LocationConfig contains information about a SendLocation request.
503type LocationConfig struct {
504	BaseChat
505	Latitude  float64 // required
506	Longitude float64 // required
507}
508
509// values returns a url.Values representation of LocationConfig.
510func (config LocationConfig) values() (url.Values, error) {
511	v, err := config.BaseChat.values()
512	if err != nil {
513		return v, err
514	}
515
516	v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
517	v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
518
519	return v, nil
520}
521
522// method returns Telegram API method name for sending Location.
523func (config LocationConfig) method() string {
524	return "sendLocation"
525}
526
527// VenueConfig contains information about a SendVenue request.
528type VenueConfig struct {
529	BaseChat
530	Latitude     float64 // required
531	Longitude    float64 // required
532	Title        string  // required
533	Address      string  // required
534	FoursquareID string
535}
536
537func (config VenueConfig) values() (url.Values, error) {
538	v, err := config.BaseChat.values()
539	if err != nil {
540		return v, err
541	}
542
543	v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
544	v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
545	v.Add("title", config.Title)
546	v.Add("address", config.Address)
547	if config.FoursquareID != "" {
548		v.Add("foursquare_id", config.FoursquareID)
549	}
550
551	return v, nil
552}
553
554func (config VenueConfig) method() string {
555	return "sendVenue"
556}
557
558// ContactConfig allows you to send a contact.
559type ContactConfig struct {
560	BaseChat
561	PhoneNumber string
562	FirstName   string
563	LastName    string
564}
565
566func (config ContactConfig) values() (url.Values, error) {
567	v, err := config.BaseChat.values()
568	if err != nil {
569		return v, err
570	}
571
572	v.Add("phone_number", config.PhoneNumber)
573	v.Add("first_name", config.FirstName)
574	v.Add("last_name", config.LastName)
575
576	return v, nil
577}
578
579func (config ContactConfig) method() string {
580	return "sendContact"
581}
582
583// GameConfig allows you to send a game.
584type GameConfig struct {
585	BaseChat
586	GameShortName string
587}
588
589func (config GameConfig) values() (url.Values, error) {
590	v, err := config.BaseChat.values()
591	if err != nil {
592		return v, err
593	}
594
595	v.Add("game_short_name", config.GameShortName)
596
597	return v, nil
598}
599
600func (config GameConfig) method() string {
601	return "sendGame"
602}
603
604// SetGameScoreConfig allows you to update the game score in a chat.
605type SetGameScoreConfig struct {
606	UserID             int
607	Score              int
608	Force              bool
609	DisableEditMessage bool
610	ChatID             int
611	ChannelUsername    string
612	MessageID          int
613	InlineMessageID    string
614}
615
616func (config SetGameScoreConfig) values() (url.Values, error) {
617	v := url.Values{}
618
619	v.Add("user_id", strconv.Itoa(config.UserID))
620	v.Add("score", strconv.Itoa(config.Score))
621	if config.InlineMessageID == "" {
622		if config.ChannelUsername == "" {
623			v.Add("chat_id", strconv.Itoa(config.ChatID))
624		} else {
625			v.Add("chat_id", config.ChannelUsername)
626		}
627		v.Add("message_id", strconv.Itoa(config.MessageID))
628	} else {
629		v.Add("inline_message_id", config.InlineMessageID)
630	}
631	v.Add("disable_edit_message", strconv.FormatBool(config.DisableEditMessage))
632
633	return v, nil
634}
635
636func (config SetGameScoreConfig) method() string {
637	return "setGameScore"
638}
639
640// GetGameHighScoresConfig allows you to fetch the high scores for a game.
641type GetGameHighScoresConfig struct {
642	UserID          int
643	ChatID          int
644	ChannelUsername string
645	MessageID       int
646	InlineMessageID string
647}
648
649func (config GetGameHighScoresConfig) values() (url.Values, error) {
650	v := url.Values{}
651
652	v.Add("user_id", strconv.Itoa(config.UserID))
653	if config.InlineMessageID == "" {
654		if config.ChannelUsername == "" {
655			v.Add("chat_id", strconv.Itoa(config.ChatID))
656		} else {
657			v.Add("chat_id", config.ChannelUsername)
658		}
659		v.Add("message_id", strconv.Itoa(config.MessageID))
660	} else {
661		v.Add("inline_message_id", config.InlineMessageID)
662	}
663
664	return v, nil
665}
666
667func (config GetGameHighScoresConfig) method() string {
668	return "getGameHighScores"
669}
670
671// ChatActionConfig contains information about a SendChatAction request.
672type ChatActionConfig struct {
673	BaseChat
674	Action string // required
675}
676
677// values returns a url.Values representation of ChatActionConfig.
678func (config ChatActionConfig) values() (url.Values, error) {
679	v, err := config.BaseChat.values()
680	if err != nil {
681		return v, err
682	}
683	v.Add("action", config.Action)
684	return v, nil
685}
686
687// method returns Telegram API method name for sending ChatAction.
688func (config ChatActionConfig) method() string {
689	return "sendChatAction"
690}
691
692// EditMessageTextConfig allows you to modify the text in a message.
693type EditMessageTextConfig struct {
694	BaseEdit
695	Text                  string
696	ParseMode             string
697	DisableWebPagePreview bool
698}
699
700func (config EditMessageTextConfig) values() (url.Values, error) {
701	v, err := config.BaseEdit.values()
702	if err != nil {
703		return v, err
704	}
705
706	v.Add("text", config.Text)
707	v.Add("parse_mode", config.ParseMode)
708	v.Add("disable_web_page_preview", strconv.FormatBool(config.DisableWebPagePreview))
709
710	return v, nil
711}
712
713func (config EditMessageTextConfig) method() string {
714	return "editMessageText"
715}
716
717// EditMessageCaptionConfig allows you to modify the caption of a message.
718type EditMessageCaptionConfig struct {
719	BaseEdit
720	Caption string
721}
722
723func (config EditMessageCaptionConfig) values() (url.Values, error) {
724	v, _ := config.BaseEdit.values()
725
726	v.Add("caption", config.Caption)
727
728	return v, nil
729}
730
731func (config EditMessageCaptionConfig) method() string {
732	return "editMessageCaption"
733}
734
735// EditMessageReplyMarkupConfig allows you to modify the reply markup
736// of a message.
737type EditMessageReplyMarkupConfig struct {
738	BaseEdit
739}
740
741func (config EditMessageReplyMarkupConfig) values() (url.Values, error) {
742	return config.BaseEdit.values()
743}
744
745func (config EditMessageReplyMarkupConfig) method() string {
746	return "editMessageReplyMarkup"
747}
748
749// UserProfilePhotosConfig contains information about a
750// GetUserProfilePhotos request.
751type UserProfilePhotosConfig struct {
752	UserID int
753	Offset int
754	Limit  int
755}
756
757// FileConfig has information about a file hosted on Telegram.
758type FileConfig struct {
759	FileID string
760}
761
762// UpdateConfig contains information about a GetUpdates request.
763type UpdateConfig struct {
764	Offset  int
765	Limit   int
766	Timeout int
767}
768
769// WebhookConfig contains information about a SetWebhook request.
770type WebhookConfig struct {
771	URL         *url.URL
772	Certificate interface{}
773	MaxConnections int
774}
775
776// FileBytes contains information about a set of bytes to upload
777// as a File.
778type FileBytes struct {
779	Name  string
780	Bytes []byte
781}
782
783// FileReader contains information about a reader to upload as a File.
784// If Size is -1, it will read the entire Reader into memory to
785// calculate a Size.
786type FileReader struct {
787	Name   string
788	Reader io.Reader
789	Size   int64
790}
791
792// InlineConfig contains information on making an InlineQuery response.
793type InlineConfig struct {
794	InlineQueryID     string        `json:"inline_query_id"`
795	Results           []interface{} `json:"results"`
796	CacheTime         int           `json:"cache_time"`
797	IsPersonal        bool          `json:"is_personal"`
798	NextOffset        string        `json:"next_offset"`
799	SwitchPMText      string        `json:"switch_pm_text"`
800	SwitchPMParameter string        `json:"switch_pm_parameter"`
801}
802
803// CallbackConfig contains information on making a CallbackQuery response.
804type CallbackConfig struct {
805	CallbackQueryID string `json:"callback_query_id"`
806	Text            string `json:"text"`
807	ShowAlert       bool   `json:"show_alert"`
808	URL             string `json:"url"`
809	CacheTime       int    `json:"cache_time"`
810}
811
812// ChatMemberConfig contains information about a user in a chat for use
813// with administrative functions such as kicking or unbanning a user.
814type ChatMemberConfig struct {
815	ChatID             int64
816	SuperGroupUsername string
817	UserID             int
818}
819
820// ChatConfig contains information about getting information on a chat.
821type ChatConfig struct {
822	ChatID             int64
823	SuperGroupUsername string
824}
825
826// ChatConfigWithUser contains information about getting information on
827// a specific user within a chat.
828type ChatConfigWithUser struct {
829	ChatID             int64
830	SuperGroupUsername string
831	UserID             int
832}