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