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// MessageConfig contains information about a SendMessage request.
157type MessageConfig struct {
158 BaseChat
159 Text string
160 ParseMode string
161 DisableWebPagePreview bool
162}
163
164// values returns a url.Values representation of MessageConfig.
165func (config MessageConfig) values() (url.Values, error) {
166 v, _ := config.BaseChat.values()
167 v.Add("text", config.Text)
168 v.Add("disable_web_page_preview", strconv.FormatBool(config.DisableWebPagePreview))
169 if config.ParseMode != "" {
170 v.Add("parse_mode", config.ParseMode)
171 }
172
173 return v, nil
174}
175
176// method returns Telegram API method name for sending Message.
177func (config MessageConfig) method() string {
178 return "sendMessage"
179}
180
181// ForwardConfig contains information about a ForwardMessage request.
182type ForwardConfig struct {
183 BaseChat
184 FromChatID int64 // required
185 FromChannelUsername string
186 MessageID int // required
187}
188
189// values returns a url.Values representation of ForwardConfig.
190func (config ForwardConfig) values() (url.Values, error) {
191 v, _ := config.BaseChat.values()
192 v.Add("from_chat_id", strconv.FormatInt(config.FromChatID, 10))
193 v.Add("message_id", strconv.Itoa(config.MessageID))
194 return v, nil
195}
196
197// method returns Telegram API method name for sending Forward.
198func (config ForwardConfig) method() string {
199 return "forwardMessage"
200}
201
202// PhotoConfig contains information about a SendPhoto request.
203type PhotoConfig struct {
204 BaseFile
205 Caption string
206}
207
208// Params returns a map[string]string representation of PhotoConfig.
209func (config PhotoConfig) params() (map[string]string, error) {
210 params, _ := config.BaseFile.params()
211
212 if config.Caption != "" {
213 params["caption"] = config.Caption
214 }
215
216 return params, nil
217}
218
219// Values returns a url.Values representation of PhotoConfig.
220func (config PhotoConfig) values() (url.Values, error) {
221 v, _ := config.BaseChat.values()
222
223 v.Add(config.name(), config.FileID)
224 if config.Caption != "" {
225 v.Add("caption", config.Caption)
226 }
227 return v, nil
228}
229
230// name returns the field name for the Photo.
231func (config PhotoConfig) name() string {
232 return "photo"
233}
234
235// method returns Telegram API method name for sending Photo.
236func (config PhotoConfig) method() string {
237 return "sendPhoto"
238}
239
240// AudioConfig contains information about a SendAudio request.
241type AudioConfig struct {
242 BaseFile
243 Duration int
244 Performer string
245 Title string
246}
247
248// values returns a url.Values representation of AudioConfig.
249func (config AudioConfig) values() (url.Values, error) {
250 v, _ := config.BaseChat.values()
251
252 v.Add(config.name(), config.FileID)
253 if config.Duration != 0 {
254 v.Add("duration", strconv.Itoa(config.Duration))
255 }
256
257 if config.Performer != "" {
258 v.Add("performer", config.Performer)
259 }
260 if config.Title != "" {
261 v.Add("title", config.Title)
262 }
263
264 return v, nil
265}
266
267// params returns a map[string]string representation of AudioConfig.
268func (config AudioConfig) params() (map[string]string, error) {
269 params, _ := config.BaseFile.params()
270
271 if config.Duration != 0 {
272 params["duration"] = strconv.Itoa(config.Duration)
273 }
274
275 if config.Performer != "" {
276 params["performer"] = config.Performer
277 }
278 if config.Title != "" {
279 params["title"] = config.Title
280 }
281
282 return params, nil
283}
284
285// name returns the field name for the Audio.
286func (config AudioConfig) name() string {
287 return "audio"
288}
289
290// method returns Telegram API method name for sending Audio.
291func (config AudioConfig) method() string {
292 return "sendAudio"
293}
294
295// DocumentConfig contains information about a SendDocument request.
296type DocumentConfig struct {
297 BaseFile
298}
299
300// values returns a url.Values representation of DocumentConfig.
301func (config DocumentConfig) values() (url.Values, error) {
302 v, _ := config.BaseChat.values()
303
304 v.Add(config.name(), config.FileID)
305
306 return v, nil
307}
308
309// params returns a map[string]string representation of DocumentConfig.
310func (config DocumentConfig) params() (map[string]string, error) {
311 params, _ := config.BaseFile.params()
312
313 return params, nil
314}
315
316// name returns the field name for the Document.
317func (config DocumentConfig) name() string {
318 return "document"
319}
320
321// method returns Telegram API method name for sending Document.
322func (config DocumentConfig) method() string {
323 return "sendDocument"
324}
325
326// StickerConfig contains information about a SendSticker request.
327type StickerConfig struct {
328 BaseFile
329}
330
331// values returns a url.Values representation of StickerConfig.
332func (config StickerConfig) 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 StickerConfig.
341func (config StickerConfig) 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 Sticker.
348func (config StickerConfig) name() string {
349 return "sticker"
350}
351
352// method returns Telegram API method name for sending Sticker.
353func (config StickerConfig) method() string {
354 return "sendSticker"
355}
356
357// VideoConfig contains information about a SendVideo request.
358type VideoConfig struct {
359 BaseFile
360 Duration int
361 Caption string
362}
363
364// values returns a url.Values representation of VideoConfig.
365func (config VideoConfig) values() (url.Values, error) {
366 v, _ := config.BaseChat.values()
367
368 v.Add(config.name(), config.FileID)
369 if config.Duration != 0 {
370 v.Add("duration", strconv.Itoa(config.Duration))
371 }
372 if config.Caption != "" {
373 v.Add("caption", config.Caption)
374 }
375
376 return v, nil
377}
378
379// params returns a map[string]string representation of VideoConfig.
380func (config VideoConfig) params() (map[string]string, error) {
381 params, _ := config.BaseFile.params()
382
383 return params, nil
384}
385
386// name returns the field name for the Video.
387func (config VideoConfig) name() string {
388 return "video"
389}
390
391// method returns Telegram API method name for sending Video.
392func (config VideoConfig) method() string {
393 return "sendVideo"
394}
395
396// VoiceConfig contains information about a SendVoice request.
397type VoiceConfig struct {
398 BaseFile
399 Duration int
400}
401
402// values returns a url.Values representation of VoiceConfig.
403func (config VoiceConfig) values() (url.Values, error) {
404 v, _ := config.BaseChat.values()
405
406 v.Add(config.name(), config.FileID)
407 if config.Duration != 0 {
408 v.Add("duration", strconv.Itoa(config.Duration))
409 }
410
411 return v, nil
412}
413
414// params returns a map[string]string representation of VoiceConfig.
415func (config VoiceConfig) params() (map[string]string, error) {
416 params, _ := config.BaseFile.params()
417
418 if config.Duration != 0 {
419 params["duration"] = strconv.Itoa(config.Duration)
420 }
421
422 return params, nil
423}
424
425// name returns the field name for the Voice.
426func (config VoiceConfig) name() string {
427 return "voice"
428}
429
430// method returns Telegram API method name for sending Voice.
431func (config VoiceConfig) method() string {
432 return "sendVoice"
433}
434
435// LocationConfig contains information about a SendLocation request.
436type LocationConfig struct {
437 BaseChat
438 Latitude float64 // required
439 Longitude float64 // required
440}
441
442// values returns a url.Values representation of LocationConfig.
443func (config LocationConfig) values() (url.Values, error) {
444 v, _ := config.BaseChat.values()
445
446 v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
447 v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
448
449 return v, nil
450}
451
452// method returns Telegram API method name for sending Location.
453func (config LocationConfig) method() string {
454 return "sendLocation"
455}
456
457// VenueConfig contains information about a SendVenue request.
458type VenueConfig struct {
459 BaseChat
460 Latitude float64 // required
461 Longitude float64 // required
462 Title string // required
463 Address string // required
464 FoursquareID string
465}
466
467func (config VenueConfig) values() (url.Values, error) {
468 v, _ := config.BaseChat.values()
469
470 v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
471 v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
472 v.Add("title", config.Title)
473 v.Add("address", config.Address)
474 if config.FoursquareID != "" {
475 v.Add("foursquare_id", config.FoursquareID)
476 }
477
478 return v, nil
479}
480
481func (config VenueConfig) method() string {
482 return "sendVenue"
483}
484
485// ChatActionConfig contains information about a SendChatAction request.
486type ChatActionConfig struct {
487 BaseChat
488 Action string // required
489}
490
491// values returns a url.Values representation of ChatActionConfig.
492func (config ChatActionConfig) values() (url.Values, error) {
493 v, _ := config.BaseChat.values()
494 v.Add("action", config.Action)
495 return v, nil
496}
497
498// method returns Telegram API method name for sending ChatAction.
499func (config ChatActionConfig) method() string {
500 return "sendChatAction"
501}
502
503// UserProfilePhotosConfig contains information about a
504// GetUserProfilePhotos request.
505type UserProfilePhotosConfig struct {
506 UserID int
507 Offset int
508 Limit int
509}
510
511// FileConfig has information about a file hosted on Telegram.
512type FileConfig struct {
513 FileID string
514}
515
516// UpdateConfig contains information about a GetUpdates request.
517type UpdateConfig struct {
518 Offset int
519 Limit int
520 Timeout int
521}
522
523// WebhookConfig contains information about a SetWebhook request.
524type WebhookConfig struct {
525 URL *url.URL
526 Certificate interface{}
527}
528
529// FileBytes contains information about a set of bytes to upload
530// as a File.
531type FileBytes struct {
532 Name string
533 Bytes []byte
534}
535
536// FileReader contains information about a reader to upload as a File.
537// If Size is -1, it will read the entire Reader into memory to
538// calculate a Size.
539type FileReader struct {
540 Name string
541 Reader io.Reader
542 Size int64
543}
544
545// InlineConfig contains information on making an InlineQuery response.
546type InlineConfig struct {
547 InlineQueryID string `json:"inline_query_id"`
548 Results []interface{} `json:"results"`
549 CacheTime int `json:"cache_time"`
550 IsPersonal bool `json:"is_personal"`
551 NextOffset string `json:"next_offset"`
552 SwitchPMText string `json:"switch_pm_text"`
553 SwitchPMParameter string `json:"switch_pm_parameter"`
554}
555
556// CallbackConfig contains information on making a CallbackQuery response.
557type CallbackConfig struct {
558 CallbackQueryID string `json:"callback_query_id"`
559 Text string `json:"text"`
560 ShowAlert bool `json:"show_alert"`
561}