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