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)
48
49// Chattable is any config type that can be sent.
50type Chattable interface {
51 values() (url.Values, error)
52 method() string
53}
54
55// Fileable is any config type that can be sent that includes a file.
56type Fileable interface {
57 Chattable
58 params() (map[string]string, error)
59 name() string
60 getFile() interface{}
61 useExistingFile() bool
62}
63
64// BaseChat is base type for all chat config types.
65type BaseChat struct {
66 ChatID int64 // required
67 ChannelUsername string
68 ReplyToMessageID int
69 ReplyMarkup interface{}
70 DisableNotification bool
71}
72
73// values returns url.Values representation of BaseChat
74func (chat *BaseChat) values() (url.Values, error) {
75 v := url.Values{}
76 if chat.ChannelUsername != "" {
77 v.Add("chat_id", chat.ChannelUsername)
78 } else {
79 v.Add("chat_id", strconv.FormatInt(chat.ChatID, 10))
80 }
81
82 if chat.ReplyToMessageID != 0 {
83 v.Add("reply_to_message_id", strconv.Itoa(chat.ReplyToMessageID))
84 }
85
86 if chat.ReplyMarkup != nil {
87 data, err := json.Marshal(chat.ReplyMarkup)
88 if err != nil {
89 return v, err
90 }
91
92 v.Add("reply_markup", string(data))
93 }
94
95 v.Add("disable_notification", strconv.FormatBool(chat.DisableNotification))
96
97 return v, nil
98}
99
100// BaseFile is a base type for all file config types.
101type BaseFile struct {
102 BaseChat
103 File interface{}
104 FileID string
105 UseExisting bool
106 MimeType string
107 FileSize int
108}
109
110// params returns a map[string]string representation of BaseFile.
111func (file BaseFile) params() (map[string]string, error) {
112 params := make(map[string]string)
113
114 if file.ChannelUsername != "" {
115 params["chat_id"] = file.ChannelUsername
116 } else {
117 params["chat_id"] = strconv.FormatInt(file.ChatID, 10)
118 }
119
120 if file.ReplyToMessageID != 0 {
121 params["reply_to_message_id"] = strconv.Itoa(file.ReplyToMessageID)
122 }
123
124 if file.ReplyMarkup != nil {
125 data, err := json.Marshal(file.ReplyMarkup)
126 if err != nil {
127 return params, err
128 }
129
130 params["reply_markup"] = string(data)
131 }
132
133 if file.MimeType != "" {
134 params["mime_type"] = file.MimeType
135 }
136
137 if file.FileSize > 0 {
138 params["file_size"] = strconv.Itoa(file.FileSize)
139 }
140
141 params["disable_notification"] = strconv.FormatBool(file.DisableNotification)
142
143 return params, nil
144}
145
146// getFile returns the file.
147func (file BaseFile) getFile() interface{} {
148 return file.File
149}
150
151// useExistingFile returns if the BaseFile has already been uploaded.
152func (file BaseFile) useExistingFile() bool {
153 return file.UseExisting
154}
155
156// BaseEdit is base type of all chat edits.
157type BaseEdit struct {
158 ChatID int64
159 ChannelUsername string
160 MessageID int
161 InlineMessageID string
162 ReplyMarkup *InlineKeyboardMarkup
163}
164
165func (edit BaseEdit) values() (url.Values, error) {
166 v := url.Values{}
167
168 if edit.ChannelUsername != "" {
169 v.Add("chat_id", edit.ChannelUsername)
170 } else {
171 v.Add("chat_id", strconv.FormatInt(edit.ChatID, 10))
172 }
173 v.Add("message_id", strconv.Itoa(edit.MessageID))
174 v.Add("inline_message_id", edit.InlineMessageID)
175
176 if edit.ReplyMarkup != nil {
177 data, err := json.Marshal(edit.ReplyMarkup)
178 if err != nil {
179 return v, err
180 }
181 v.Add("reply_markup", string(data))
182 }
183
184 return v, nil
185}
186
187// MessageConfig contains information about a SendMessage request.
188type MessageConfig struct {
189 BaseChat
190 Text string
191 ParseMode string
192 DisableWebPagePreview bool
193}
194
195// values returns a url.Values representation of MessageConfig.
196func (config MessageConfig) values() (url.Values, error) {
197 v, _ := config.BaseChat.values()
198 v.Add("text", config.Text)
199 v.Add("disable_web_page_preview", strconv.FormatBool(config.DisableWebPagePreview))
200 if config.ParseMode != "" {
201 v.Add("parse_mode", config.ParseMode)
202 }
203
204 return v, nil
205}
206
207// method returns Telegram API method name for sending Message.
208func (config MessageConfig) method() string {
209 return "sendMessage"
210}
211
212// ForwardConfig contains information about a ForwardMessage request.
213type ForwardConfig struct {
214 BaseChat
215 FromChatID int64 // required
216 FromChannelUsername string
217 MessageID int // required
218}
219
220// values returns a url.Values representation of ForwardConfig.
221func (config ForwardConfig) values() (url.Values, error) {
222 v, _ := config.BaseChat.values()
223 v.Add("from_chat_id", strconv.FormatInt(config.FromChatID, 10))
224 v.Add("message_id", strconv.Itoa(config.MessageID))
225 return v, nil
226}
227
228// method returns Telegram API method name for sending Forward.
229func (config ForwardConfig) method() string {
230 return "forwardMessage"
231}
232
233// PhotoConfig contains information about a SendPhoto request.
234type PhotoConfig struct {
235 BaseFile
236 Caption string
237}
238
239// Params returns a map[string]string representation of PhotoConfig.
240func (config PhotoConfig) params() (map[string]string, error) {
241 params, _ := config.BaseFile.params()
242
243 if config.Caption != "" {
244 params["caption"] = config.Caption
245 }
246
247 return params, nil
248}
249
250// Values returns a url.Values representation of PhotoConfig.
251func (config PhotoConfig) values() (url.Values, error) {
252 v, _ := config.BaseChat.values()
253
254 v.Add(config.name(), config.FileID)
255 if config.Caption != "" {
256 v.Add("caption", config.Caption)
257 }
258 return v, nil
259}
260
261// name returns the field name for the Photo.
262func (config PhotoConfig) name() string {
263 return "photo"
264}
265
266// method returns Telegram API method name for sending Photo.
267func (config PhotoConfig) method() string {
268 return "sendPhoto"
269}
270
271// AudioConfig contains information about a SendAudio request.
272type AudioConfig struct {
273 BaseFile
274 Duration int
275 Performer string
276 Title string
277}
278
279// values returns a url.Values representation of AudioConfig.
280func (config AudioConfig) values() (url.Values, error) {
281 v, _ := config.BaseChat.values()
282
283 v.Add(config.name(), config.FileID)
284 if config.Duration != 0 {
285 v.Add("duration", strconv.Itoa(config.Duration))
286 }
287
288 if config.Performer != "" {
289 v.Add("performer", config.Performer)
290 }
291 if config.Title != "" {
292 v.Add("title", config.Title)
293 }
294
295 return v, nil
296}
297
298// params returns a map[string]string representation of AudioConfig.
299func (config AudioConfig) params() (map[string]string, error) {
300 params, _ := config.BaseFile.params()
301
302 if config.Duration != 0 {
303 params["duration"] = strconv.Itoa(config.Duration)
304 }
305
306 if config.Performer != "" {
307 params["performer"] = config.Performer
308 }
309 if config.Title != "" {
310 params["title"] = config.Title
311 }
312
313 return params, nil
314}
315
316// name returns the field name for the Audio.
317func (config AudioConfig) name() string {
318 return "audio"
319}
320
321// method returns Telegram API method name for sending Audio.
322func (config AudioConfig) method() string {
323 return "sendAudio"
324}
325
326// DocumentConfig contains information about a SendDocument request.
327type DocumentConfig struct {
328 BaseFile
329}
330
331// values returns a url.Values representation of DocumentConfig.
332func (config DocumentConfig) values() (url.Values, error) {
333 v, _ := config.BaseChat.values()
334
335 v.Add(config.name(), config.FileID)
336
337 return v, nil
338}
339
340// params returns a map[string]string representation of DocumentConfig.
341func (config DocumentConfig) params() (map[string]string, error) {
342 params, _ := config.BaseFile.params()
343
344 return params, nil
345}
346
347// name returns the field name for the Document.
348func (config DocumentConfig) name() string {
349 return "document"
350}
351
352// method returns Telegram API method name for sending Document.
353func (config DocumentConfig) method() string {
354 return "sendDocument"
355}
356
357// StickerConfig contains information about a SendSticker request.
358type StickerConfig struct {
359 BaseFile
360}
361
362// values returns a url.Values representation of StickerConfig.
363func (config StickerConfig) values() (url.Values, error) {
364 v, _ := config.BaseChat.values()
365
366 v.Add(config.name(), config.FileID)
367
368 return v, nil
369}
370
371// params returns a map[string]string representation of StickerConfig.
372func (config StickerConfig) params() (map[string]string, error) {
373 params, _ := config.BaseFile.params()
374
375 return params, nil
376}
377
378// name returns the field name for the Sticker.
379func (config StickerConfig) name() string {
380 return "sticker"
381}
382
383// method returns Telegram API method name for sending Sticker.
384func (config StickerConfig) method() string {
385 return "sendSticker"
386}
387
388// VideoConfig contains information about a SendVideo request.
389type VideoConfig struct {
390 BaseFile
391 Duration int
392 Caption string
393}
394
395// values returns a url.Values representation of VideoConfig.
396func (config VideoConfig) values() (url.Values, error) {
397 v, _ := config.BaseChat.values()
398
399 v.Add(config.name(), config.FileID)
400 if config.Duration != 0 {
401 v.Add("duration", strconv.Itoa(config.Duration))
402 }
403 if config.Caption != "" {
404 v.Add("caption", config.Caption)
405 }
406
407 return v, nil
408}
409
410// params returns a map[string]string representation of VideoConfig.
411func (config VideoConfig) params() (map[string]string, error) {
412 params, _ := config.BaseFile.params()
413
414 return params, nil
415}
416
417// name returns the field name for the Video.
418func (config VideoConfig) name() string {
419 return "video"
420}
421
422// method returns Telegram API method name for sending Video.
423func (config VideoConfig) method() string {
424 return "sendVideo"
425}
426
427// VoiceConfig contains information about a SendVoice request.
428type VoiceConfig struct {
429 BaseFile
430 Duration int
431}
432
433// values returns a url.Values representation of VoiceConfig.
434func (config VoiceConfig) values() (url.Values, error) {
435 v, _ := config.BaseChat.values()
436
437 v.Add(config.name(), config.FileID)
438 if config.Duration != 0 {
439 v.Add("duration", strconv.Itoa(config.Duration))
440 }
441
442 return v, nil
443}
444
445// params returns a map[string]string representation of VoiceConfig.
446func (config VoiceConfig) params() (map[string]string, error) {
447 params, _ := config.BaseFile.params()
448
449 if config.Duration != 0 {
450 params["duration"] = strconv.Itoa(config.Duration)
451 }
452
453 return params, nil
454}
455
456// name returns the field name for the Voice.
457func (config VoiceConfig) name() string {
458 return "voice"
459}
460
461// method returns Telegram API method name for sending Voice.
462func (config VoiceConfig) method() string {
463 return "sendVoice"
464}
465
466// LocationConfig contains information about a SendLocation request.
467type LocationConfig struct {
468 BaseChat
469 Latitude float64 // required
470 Longitude float64 // required
471}
472
473// values returns a url.Values representation of LocationConfig.
474func (config LocationConfig) values() (url.Values, error) {
475 v, _ := config.BaseChat.values()
476
477 v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
478 v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
479
480 return v, nil
481}
482
483// method returns Telegram API method name for sending Location.
484func (config LocationConfig) method() string {
485 return "sendLocation"
486}
487
488// VenueConfig contains information about a SendVenue request.
489type VenueConfig struct {
490 BaseChat
491 Latitude float64 // required
492 Longitude float64 // required
493 Title string // required
494 Address string // required
495 FoursquareID string
496}
497
498func (config VenueConfig) values() (url.Values, error) {
499 v, _ := config.BaseChat.values()
500
501 v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
502 v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
503 v.Add("title", config.Title)
504 v.Add("address", config.Address)
505 if config.FoursquareID != "" {
506 v.Add("foursquare_id", config.FoursquareID)
507 }
508
509 return v, nil
510}
511
512func (config VenueConfig) method() string {
513 return "sendVenue"
514}
515
516// ChatActionConfig contains information about a SendChatAction request.
517type ChatActionConfig struct {
518 BaseChat
519 Action string // required
520}
521
522// values returns a url.Values representation of ChatActionConfig.
523func (config ChatActionConfig) values() (url.Values, error) {
524 v, _ := config.BaseChat.values()
525 v.Add("action", config.Action)
526 return v, nil
527}
528
529// method returns Telegram API method name for sending ChatAction.
530func (config ChatActionConfig) method() string {
531 return "sendChatAction"
532}
533
534// EditMessageTextConfig allows you to modify the text in a message.
535type EditMessageTextConfig struct {
536 BaseEdit
537 Text string
538 ParseMode string
539 DisableWebPagePreview bool
540 ReplyMarkup InlineKeyboardMarkup
541}
542
543func (config EditMessageTextConfig) values() (url.Values, error) {
544 v, _ := config.BaseEdit.values()
545
546 v.Add("text", config.Text)
547 v.Add("parse_mode", config.ParseMode)
548 v.Add("disable_web_page_preview", strconv.FormatBool(config.DisableWebPagePreview))
549
550 return v, nil
551}
552
553func (config EditMessageTextConfig) method() string {
554 return "editMessageText"
555}
556
557// EditMessageCaptionConfig allows you to modify the caption of a message.
558type EditMessageCaptionConfig struct {
559 BaseEdit
560 Caption string
561 ReplyMarkup InlineKeyboardMarkup
562}
563
564func (config EditMessageCaptionConfig) values() (url.Values, error) {
565 v, _ := config.BaseEdit.values()
566
567 v.Add("caption", config.Caption)
568
569 return v, nil
570}
571
572func (config EditMessageCaptionConfig) method() string {
573 return "editMessageCaption"
574}
575
576// EditMessageReplyMarkup allows you to modify the reply markup
577// of a message.
578type EditMessageReplyMarkup struct {
579 BaseEdit
580 ReplyMarkup InlineKeyboardMarkup
581}
582
583func (config EditMessageReplyMarkup) values() (url.Values, error) {
584 return config.BaseEdit.values()
585}
586
587func (config EditMessageReplyMarkup) method() string {
588 return "editMessageReplyMarkup"
589}
590
591// UserProfilePhotosConfig contains information about a
592// GetUserProfilePhotos request.
593type UserProfilePhotosConfig struct {
594 UserID int
595 Offset int
596 Limit int
597}
598
599// FileConfig has information about a file hosted on Telegram.
600type FileConfig struct {
601 FileID string
602}
603
604// UpdateConfig contains information about a GetUpdates request.
605type UpdateConfig struct {
606 Offset int
607 Limit int
608 Timeout int
609}
610
611// WebhookConfig contains information about a SetWebhook request.
612type WebhookConfig struct {
613 URL *url.URL
614 Certificate interface{}
615}
616
617// FileBytes contains information about a set of bytes to upload
618// as a File.
619type FileBytes struct {
620 Name string
621 Bytes []byte
622}
623
624// FileReader contains information about a reader to upload as a File.
625// If Size is -1, it will read the entire Reader into memory to
626// calculate a Size.
627type FileReader struct {
628 Name string
629 Reader io.Reader
630 Size int64
631}
632
633// InlineConfig contains information on making an InlineQuery response.
634type InlineConfig struct {
635 InlineQueryID string `json:"inline_query_id"`
636 Results []interface{} `json:"results"`
637 CacheTime int `json:"cache_time"`
638 IsPersonal bool `json:"is_personal"`
639 NextOffset string `json:"next_offset"`
640 SwitchPMText string `json:"switch_pm_text"`
641 SwitchPMParameter string `json:"switch_pm_parameter"`
642}
643
644// CallbackConfig contains information on making a CallbackQuery response.
645type CallbackConfig struct {
646 CallbackQueryID string `json:"callback_query_id"`
647 Text string `json:"text"`
648 ShowAlert bool `json:"show_alert"`
649}
650
651// ChatMemberConfig contains information about a user in a chat for use
652// with administrative functions such as kicking or unbanning a user.
653type ChatMemberConfig struct {
654 ChatID int64
655 SuperGroupUsername string
656 UserID int
657}