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