all repos — telegram-bot-api @ cbf597eaf6f657b48e0192ccf6f43b08956456be

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