configs.go (view raw)
1package tgbotapi
2
3import (
4 "encoding/json"
5 "io"
6 "log"
7 "net/url"
8 "strconv"
9)
10
11// Telegram constants
12const (
13 // APIEndpoint is the endpoint for all API methods,
14 // with formatting for Sprintf.
15 APIEndpoint = "https://api.telegram.org/bot%s/%s"
16 // FileEndpoint is the endpoint for downloading a file from Telegram.
17 FileEndpoint = "https://api.telegram.org/file/bot%s/%s"
18)
19
20// Constant values for ChatActions
21const (
22 ChatTyping = "typing"
23 ChatUploadPhoto = "upload_photo"
24 ChatRecordVideo = "record_video"
25 ChatUploadVideo = "upload_video"
26 ChatRecordAudio = "record_audio"
27 ChatUploadAudio = "upload_audio"
28 ChatUploadDocument = "upload_document"
29 ChatFindLocation = "find_location"
30)
31
32// API errors
33const (
34 // APIForbidden happens when a token is bad
35 APIForbidden = "forbidden"
36)
37
38// Constant values for ParseMode in MessageConfig
39const (
40 ModeMarkdown = "Markdown"
41)
42
43// Chattable is any config type that can be sent.
44type Chattable interface {
45 values() (url.Values, error)
46 method() string
47}
48
49// Fileable is any config type that can be sent that includes a file.
50type Fileable interface {
51 Chattable
52 params() (map[string]string, error)
53 name() string
54 getFile() interface{}
55 useExistingFile() bool
56}
57
58// BaseChat is base type for all chat config types.
59type BaseChat struct {
60 ChatID int // required
61 ChannelUsername string
62 ReplyToMessageID int
63 ReplyMarkup interface{}
64}
65
66// values returns url.Values representation of BaseChat
67func (chat *BaseChat) values() (url.Values, error) {
68 v := url.Values{}
69 if chat.ChannelUsername != "" {
70 v.Add("chat_id", chat.ChannelUsername)
71 } else {
72 v.Add("chat_id", strconv.Itoa(chat.ChatID))
73 }
74
75 if chat.ReplyToMessageID != 0 {
76 v.Add("reply_to_message_id", strconv.Itoa(chat.ReplyToMessageID))
77 }
78
79 if chat.ReplyMarkup != nil {
80 data, err := json.Marshal(chat.ReplyMarkup)
81 if err != nil {
82 return v, err
83 }
84
85 v.Add("reply_markup", string(data))
86 }
87
88 return v, nil
89}
90
91// BaseFile is a base type for all file config types.
92type BaseFile struct {
93 BaseChat
94 FilePath string
95 File interface{}
96 FileID string
97 UseExisting bool
98 MimeType string
99 FileSize int
100}
101
102// params returns a map[string]string representation of BaseFile.
103func (file BaseFile) params() (map[string]string, error) {
104 params := make(map[string]string)
105
106 if file.ChannelUsername != "" {
107 params["chat_id"] = file.ChannelUsername
108 } else {
109 params["chat_id"] = strconv.Itoa(file.ChatID)
110 }
111
112 if file.ReplyToMessageID != 0 {
113 params["reply_to_message_id"] = strconv.Itoa(file.ReplyToMessageID)
114 }
115
116 if file.ReplyMarkup != nil {
117 data, err := json.Marshal(file.ReplyMarkup)
118 if err != nil {
119 return params, err
120 }
121
122 params["reply_markup"] = string(data)
123 }
124
125 if file.MimeType != "" {
126 params["mime_type"] = file.MimeType
127 }
128
129 if file.FileSize > 0 {
130 params["file_size"] = strconv.Itoa(file.FileSize)
131 }
132
133 return params, nil
134}
135
136// getFile returns the file.
137func (file BaseFile) getFile() interface{} {
138 var result interface{}
139 if file.FilePath == "" {
140 result = file.File
141 } else {
142 log.Println("FilePath is deprecated.")
143 log.Println("Please use BaseFile.File instead.")
144 result = file.FilePath
145 }
146
147 return result
148}
149
150// useExistingFile returns if the BaseFile has already been uploaded.
151func (file BaseFile) useExistingFile() bool {
152 return file.UseExisting
153}
154
155// MessageConfig contains information about a SendMessage request.
156type MessageConfig struct {
157 BaseChat
158 Text string
159 ParseMode string
160 DisableWebPagePreview bool
161}
162
163// values returns a url.Values representation of MessageConfig.
164func (config MessageConfig) values() (url.Values, error) {
165 v, _ := config.BaseChat.values()
166 v.Add("text", config.Text)
167 v.Add("disable_web_page_preview", strconv.FormatBool(config.DisableWebPagePreview))
168 if config.ParseMode != "" {
169 v.Add("parse_mode", config.ParseMode)
170 }
171
172 return v, nil
173}
174
175// method returns Telegram API method name for sending Message.
176func (config MessageConfig) method() string {
177 return "sendMessage"
178}
179
180// ForwardConfig contains information about a ForwardMessage request.
181type ForwardConfig struct {
182 BaseChat
183 FromChatID int // required
184 FromChannelUsername string
185 MessageID int // required
186}
187
188// values returns a url.Values representation of ForwardConfig.
189func (config ForwardConfig) values() (url.Values, error) {
190 v, _ := config.BaseChat.values()
191 v.Add("from_chat_id", strconv.Itoa(config.FromChatID))
192 v.Add("message_id", strconv.Itoa(config.MessageID))
193 return v, nil
194}
195
196// method returns Telegram API method name for sending Forward.
197func (config ForwardConfig) method() string {
198 return "forwardMessage"
199}
200
201// PhotoConfig contains information about a SendPhoto request.
202type PhotoConfig struct {
203 BaseFile
204 Caption string
205}
206
207// Params returns a map[string]string representation of PhotoConfig.
208func (config PhotoConfig) params() (map[string]string, error) {
209 params, _ := config.BaseFile.params()
210
211 if config.Caption != "" {
212 params["caption"] = config.Caption
213 }
214
215 return params, nil
216}
217
218// Values returns a url.Values representation of PhotoConfig.
219func (config PhotoConfig) values() (url.Values, error) {
220 v, _ := config.BaseChat.values()
221
222 v.Add(config.name(), config.FileID)
223 if config.Caption != "" {
224 v.Add("caption", config.Caption)
225 }
226 return v, nil
227}
228
229// name returns the field name for the Photo.
230func (config PhotoConfig) name() string {
231 return "photo"
232}
233
234// method returns Telegram API method name for sending Photo.
235func (config PhotoConfig) method() string {
236 return "sendPhoto"
237}
238
239// AudioConfig contains information about a SendAudio request.
240type AudioConfig struct {
241 BaseFile
242 Duration int
243 Performer string
244 Title string
245}
246
247// values returns a url.Values representation of AudioConfig.
248func (config AudioConfig) values() (url.Values, error) {
249 v, _ := config.BaseChat.values()
250
251 v.Add(config.name(), config.FileID)
252 if config.Duration != 0 {
253 v.Add("duration", strconv.Itoa(config.Duration))
254 }
255
256 if config.Performer != "" {
257 v.Add("performer", config.Performer)
258 }
259 if config.Title != "" {
260 v.Add("title", config.Title)
261 }
262
263 return v, nil
264}
265
266// params returns a map[string]string representation of AudioConfig.
267func (config AudioConfig) params() (map[string]string, error) {
268 params, _ := config.BaseFile.params()
269
270 if config.Duration != 0 {
271 params["duration"] = strconv.Itoa(config.Duration)
272 }
273
274 if config.Performer != "" {
275 params["performer"] = config.Performer
276 }
277 if config.Title != "" {
278 params["title"] = config.Title
279 }
280
281 return params, nil
282}
283
284// name returns the field name for the Audio.
285func (config AudioConfig) name() string {
286 return "audio"
287}
288
289// method returns Telegram API method name for sending Audio.
290func (config AudioConfig) method() string {
291 return "sendAudio"
292}
293
294// DocumentConfig contains information about a SendDocument request.
295type DocumentConfig struct {
296 BaseFile
297}
298
299// values returns a url.Values representation of DocumentConfig.
300func (config DocumentConfig) values() (url.Values, error) {
301 v, _ := config.BaseChat.values()
302
303 v.Add(config.name(), config.FileID)
304
305 return v, nil
306}
307
308// params returns a map[string]string representation of DocumentConfig.
309func (config DocumentConfig) params() (map[string]string, error) {
310 params, _ := config.BaseFile.params()
311
312 return params, nil
313}
314
315// name returns the field name for the Document.
316func (config DocumentConfig) name() string {
317 return "document"
318}
319
320// method returns Telegram API method name for sending Document.
321func (config DocumentConfig) method() string {
322 return "sendDocument"
323}
324
325// StickerConfig contains information about a SendSticker request.
326type StickerConfig struct {
327 BaseFile
328}
329
330// values returns a url.Values representation of StickerConfig.
331func (config StickerConfig) values() (url.Values, error) {
332 v, _ := config.BaseChat.values()
333
334 v.Add(config.name(), config.FileID)
335
336 return v, nil
337}
338
339// params returns a map[string]string representation of StickerConfig.
340func (config StickerConfig) params() (map[string]string, error) {
341 params, _ := config.BaseFile.params()
342
343 return params, nil
344}
345
346// name returns the field name for the Sticker.
347func (config StickerConfig) name() string {
348 return "sticker"
349}
350
351// method returns Telegram API method name for sending Sticker.
352func (config StickerConfig) method() string {
353 return "sendSticker"
354}
355
356// VideoConfig contains information about a SendVideo request.
357type VideoConfig struct {
358 BaseFile
359 Duration int
360 Caption string
361}
362
363// values returns a url.Values representation of VideoConfig.
364func (config VideoConfig) values() (url.Values, error) {
365 v, _ := config.BaseChat.values()
366
367 v.Add(config.name(), config.FileID)
368 if config.Duration != 0 {
369 v.Add("duration", strconv.Itoa(config.Duration))
370 }
371 if config.Caption != "" {
372 v.Add("caption", config.Caption)
373 }
374
375 return v, nil
376}
377
378// params returns a map[string]string representation of VideoConfig.
379func (config VideoConfig) params() (map[string]string, error) {
380 params, _ := config.BaseFile.params()
381
382 return params, nil
383}
384
385// name returns the field name for the Video.
386func (config VideoConfig) name() string {
387 return "video"
388}
389
390// method returns Telegram API method name for sending Video.
391func (config VideoConfig) method() string {
392 return "sendVideo"
393}
394
395// VoiceConfig contains information about a SendVoice request.
396type VoiceConfig struct {
397 BaseFile
398 Duration int
399}
400
401// values returns a url.Values representation of VoiceConfig.
402func (config VoiceConfig) values() (url.Values, error) {
403 v, _ := config.BaseChat.values()
404
405 v.Add(config.name(), config.FileID)
406 if config.Duration != 0 {
407 v.Add("duration", strconv.Itoa(config.Duration))
408 }
409
410 return v, nil
411}
412
413// params returns a map[string]string representation of VoiceConfig.
414func (config VoiceConfig) params() (map[string]string, error) {
415 params, _ := config.BaseFile.params()
416
417 if config.Duration != 0 {
418 params["duration"] = strconv.Itoa(config.Duration)
419 }
420
421 return params, nil
422}
423
424// name returns the field name for the Voice.
425func (config VoiceConfig) name() string {
426 return "voice"
427}
428
429// method returns Telegram API method name for sending Voice.
430func (config VoiceConfig) method() string {
431 return "sendVoice"
432}
433
434// LocationConfig contains information about a SendLocation request.
435type LocationConfig struct {
436 BaseChat
437 Latitude float64 // required
438 Longitude float64 // required
439}
440
441// values returns a url.Values representation of LocationConfig.
442func (config LocationConfig) values() (url.Values, error) {
443 v, _ := config.BaseChat.values()
444
445 v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64))
446 v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64))
447
448 return v, nil
449}
450
451// method returns Telegram API method name for sending Location.
452func (config LocationConfig) method() string {
453 return "sendLocation"
454}
455
456// ChatActionConfig contains information about a SendChatAction request.
457type ChatActionConfig struct {
458 BaseChat
459 Action string // required
460}
461
462// values returns a url.Values representation of ChatActionConfig.
463func (config ChatActionConfig) values() (url.Values, error) {
464 v, _ := config.BaseChat.values()
465 v.Add("action", config.Action)
466 return v, nil
467}
468
469// method returns Telegram API method name for sending ChatAction.
470func (config ChatActionConfig) method() string {
471 return "sendChatAction"
472}
473
474// UserProfilePhotosConfig contains information about a
475// GetUserProfilePhotos request.
476type UserProfilePhotosConfig struct {
477 UserID int
478 Offset int
479 Limit int
480}
481
482// FileConfig has information about a file hosted on Telegram.
483type FileConfig struct {
484 FileID string
485}
486
487// UpdateConfig contains information about a GetUpdates request.
488type UpdateConfig struct {
489 Offset int
490 Limit int
491 Timeout int
492}
493
494// WebhookConfig contains information about a SetWebhook request.
495type WebhookConfig struct {
496 URL *url.URL
497 Certificate interface{}
498}
499
500// FileBytes contains information about a set of bytes to upload
501// as a File.
502type FileBytes struct {
503 Name string
504 Bytes []byte
505}
506
507// FileReader contains information about a reader to upload as a File.
508// If Size is -1, it will read the entire Reader into memory to
509// calculate a Size.
510type FileReader struct {
511 Name string
512 Reader io.Reader
513 Size int64
514}
515
516// InlineConfig contains information on making an InlineQuery response.
517type InlineConfig struct {
518 InlineQueryID string `json:"inline_query_id"`
519 Results []InlineQueryResult `json:"results"`
520 CacheTime int `json:"cache_time"`
521 IsPersonal bool `json:"is_personal"`
522 NextOffset string `json:"next_offset"`
523}