-
Notifications
You must be signed in to change notification settings - Fork 22
/
configs_message.go
530 lines (462 loc) · 11.9 KB
/
configs_message.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
package telegram
import (
"bytes"
"encoding/json"
"io"
"net/url"
"strconv"
)
// Assert interfaces
var _ Filer = (*PhotoCfg)(nil)
var _ Filer = (*AudioCfg)(nil)
var _ Filer = (*VideoCfg)(nil)
var _ Filer = (*VoiceCfg)(nil)
var _ Filer = (*DocumentCfg)(nil)
var _ Filer = (*StickerCfg)(nil)
var _ Filer = (*WebhookCfg)(nil)
// BaseMessage is a base type for all message config types.
// Implements Messenger interface.
type BaseMessage struct {
BaseChat
// If the message is a reply, ID of the original message
ReplyToMessageID int64
// Additional interface options.
// A JSON-serialized object for a custom reply keyboard,
// instructions to hide keyboard or to force a reply from the user.
ReplyMarkup ReplyMarkup
// Sends the message silently.
// iOS users will not receive a notification,
// Android users will receive a notification with no sound.
// Other apps coming soon.
DisableNotification bool
}
// Values returns url.Values representation of BaseMessage
func (m BaseMessage) Values() (url.Values, error) {
v, err := m.BaseChat.Values()
if err != nil {
return nil, err
}
if m.ReplyToMessageID != 0 {
v.Add(
"reply_to_message_id",
strconv.FormatInt(m.ReplyToMessageID, 10),
)
}
if m.ReplyMarkup != nil {
data, err := json.Marshal(m.ReplyMarkup)
if err != nil {
return nil, err
}
v.Add("reply_markup", string(data))
}
if m.DisableNotification {
v.Add(
"disable_notification",
strconv.FormatBool(m.DisableNotification),
)
}
return v, nil
}
// Message returns instance of *Message type.
func (BaseMessage) Message() *Message {
return &Message{}
}
// MessageCfg contains information about a SendMessage request.
// Use it to send text messages.
// Implements Messenger interface.
type MessageCfg struct {
BaseMessage
Text string
// Send Markdown or HTML, if you want Telegram apps to show
// bold, italic, fixed-width text or inline URLs in your bot's message.
// Use one of constants: ModeHTML, ModeMarkdown.
ParseMode string
// Disables link previews for links in this message.
DisableWebPagePreview bool
}
// Name returns method name
func (cfg MessageCfg) Name() string {
return sendMessageMethod
}
// Values returns a url.Values representation of MessageCfg.
// Returns RequiredError if Text is empty.
func (cfg MessageCfg) Values() (url.Values, error) {
v, err := cfg.BaseMessage.Values()
if err != nil {
return nil, err
}
if cfg.Text == "" {
return nil, NewRequiredError("Text")
}
v.Add("text", cfg.Text)
if cfg.DisableWebPagePreview {
v.Add(
"disable_web_page_preview",
strconv.FormatBool(cfg.DisableWebPagePreview),
)
}
if cfg.ParseMode != "" {
v.Add("parse_mode", cfg.ParseMode)
}
return v, nil
}
// LocationCfg contains information about a SendLocation request.
type LocationCfg struct {
BaseMessage
Location
}
// Values returns a url.Values representation of LocationCfg.
func (cfg LocationCfg) Values() (url.Values, error) {
v, err := cfg.BaseMessage.Values()
if err != nil {
return nil, err
}
updateValues(v, cfg.Location.Values())
return v, nil
}
// Name method returns Telegram API method name for sending Location.
func (cfg LocationCfg) Name() string {
return sendLocationMethod
}
// ContactCfg contains information about a SendContact request.
// Use it to send information about a venue
// Implements Messenger interface.
type ContactCfg struct {
BaseMessage
Contact
}
// Name returns method name
func (cfg ContactCfg) Name() string {
return sendContactMethod
}
// Values returns a url.Values representation of ContactCfg.
// Returns RequiredError if Text is empty.
func (cfg ContactCfg) Values() (url.Values, error) {
v, err := cfg.BaseMessage.Values()
if err != nil {
return nil, err
}
missed := []string{}
if cfg.Contact.FirstName == "" {
missed = append(missed, "FirstName")
}
if cfg.Contact.PhoneNumber == "" {
missed = append(missed, "PhoneNumber")
}
if len(missed) > 0 {
return nil, NewRequiredError(missed...)
}
updateValues(v, cfg.Contact.Values())
return v, nil
}
// VenueCfg contains information about a SendVenue request.
// Use it to send information about a venue
// Implements Messenger interface.
type VenueCfg struct {
BaseMessage
Venue
}
// Name returns method name
func (cfg VenueCfg) Name() string {
return sendVenueMethod
}
// Values returns a url.Values representation of VenueCfg.
// Returns RequiredError if Text is empty.
func (cfg VenueCfg) Values() (url.Values, error) {
v, err := cfg.BaseMessage.Values()
if err != nil {
return nil, err
}
missed := []string{}
if cfg.Venue.Title == "" {
missed = append(missed, "Title")
}
if cfg.Venue.Address == "" {
missed = append(missed, "Address")
}
if len(missed) > 0 {
return nil, NewRequiredError(missed...)
}
updateValues(v, cfg.Venue.Values())
return v, nil
}
// ForwardMessageCfg contains information about a ForwardMessage request.
// Use it to forward messages of any kind
// Implements Messenger interface.
type ForwardMessageCfg struct {
BaseChat
// Unique identifier for the chat where the original message was sent
FromChat BaseChat
// Unique message identifier
MessageID int64
// Sends the message silently.
// iOS users will not receive a notification,
// Android users will receive a notification with no sound.
// Other apps coming soon.
DisableNotification bool
}
// Message returns instance of *Message type.
func (ForwardMessageCfg) Message() *Message {
return &Message{}
}
// Name returns method name
func (cfg ForwardMessageCfg) Name() string {
return forwardMessageMethod
}
// Values returns a url.Values representation of MessageCfg.
// Returns RequiredError if Text is empty.
func (cfg ForwardMessageCfg) Values() (url.Values, error) {
v, err := cfg.BaseChat.Values()
if err != nil {
return nil, err
}
from, err := cfg.FromChat.Values()
if err != nil {
return nil, err
}
updateValuesWithPrefix(v, from, "from_")
if cfg.MessageID == 0 {
return nil, NewRequiredError("MessageID")
}
v.Add("message_id", strconv.FormatInt(cfg.MessageID, 10))
if cfg.DisableNotification {
v.Add(
"disable_notification",
strconv.FormatBool(cfg.DisableNotification),
)
}
return v, nil
}
type localFile struct {
filename string
reader io.Reader
}
func (l localFile) Reader() io.Reader {
return l.reader
}
func (l localFile) Name() string {
return l.filename
}
// NewInputFile takes Reader object and returns InputFile.
func NewInputFile(filename string, r io.Reader) InputFile {
return localFile{filename, r}
}
// NewBytesFile takes byte slice and returns InputFile.
func NewBytesFile(filename string, data []byte) InputFile {
return NewInputFile(filename, bytes.NewBuffer(data))
}
// BaseFile describes file settings. It's an abstract type.
type BaseFile struct {
BaseMessage
FileID string
MimeType string
InputFile InputFile
}
// GetFileID returns fileID if it's exist
func (b BaseFile) GetFileID() string {
return b.FileID
}
// Exist returns true if file exists on telegram servers
func (b BaseFile) Exist() bool {
return b.FileID != ""
}
// File returns InputFile object that are used to create request
func (b BaseFile) File() InputFile {
return b.InputFile
}
// Values returns a url.Values representation of BaseFile.
func (b BaseFile) Values() (url.Values, error) {
v, err := b.BaseMessage.Values()
if err != nil {
return nil, err
}
if b.MimeType != "" {
v.Add("mime_type", b.MimeType)
}
return v, nil
}
// Reset method removes FileID and sets new InputFile
func (b *BaseFile) Reset(i InputFile) {
b.FileID = ""
b.InputFile = i
}
// PhotoCfg contains information about a SendPhoto request.
// Use it to send information about a venue
// Implements Filer and Messenger interfaces.
type PhotoCfg struct {
BaseFile
Caption string
}
// Name returns method name
func (cfg PhotoCfg) Name() string {
return sendPhotoMethod
}
// Values returns a url.Values representation of PhotoCfg.
func (cfg PhotoCfg) Values() (url.Values, error) {
v, err := cfg.BaseFile.Values()
if err != nil {
return nil, err
}
if cfg.BaseFile.FileID != "" {
v.Add(cfg.Field(), cfg.BaseFile.FileID)
}
if cfg.Caption != "" {
v.Add("caption", cfg.Caption)
}
return v, nil
}
// Field returns name for photo file data
func (cfg PhotoCfg) Field() string {
return photoField
}
// AudioCfg contains information about a SendAudio request.
// Use it to send information about an audio
// Implements Filer and Messenger interfaces.
type AudioCfg struct {
BaseFile
Duration int
Performer string
Title string
}
// Name returns method name
func (cfg AudioCfg) Name() string {
return sendAudioMethod
}
// Values returns a url.Values representation of AudioCfg.
func (cfg AudioCfg) Values() (url.Values, error) {
v, err := cfg.BaseFile.Values()
if err != nil {
return nil, err
}
if cfg.BaseFile.FileID != "" {
v.Add(cfg.Field(), cfg.BaseFile.FileID)
}
if cfg.Duration != 0 {
v.Add("duration", strconv.Itoa(cfg.Duration))
}
if cfg.Performer != "" {
v.Add("performer", cfg.Performer)
}
if cfg.Title != "" {
v.Add("title", cfg.Title)
}
return v, nil
}
// Field returns name for audio file data
func (cfg AudioCfg) Field() string {
return audioField
}
// VideoCfg contains information about a SendVideo request.
// Use it to send information about a video
// Implements Filer and Messenger interfaces.
type VideoCfg struct {
BaseFile
Duration int
Caption string
}
// Name returns method name
func (cfg VideoCfg) Name() string {
return sendVideoMethod
}
// Values returns a url.Values representation of VideoCfg.
func (cfg VideoCfg) Values() (url.Values, error) {
v, err := cfg.BaseFile.Values()
if err != nil {
return nil, err
}
if cfg.BaseFile.FileID != "" {
v.Add(cfg.Field(), cfg.BaseFile.FileID)
}
if cfg.Duration != 0 {
v.Add("duration", strconv.Itoa(cfg.Duration))
}
if cfg.Caption != "" {
v.Add("caption", cfg.Caption)
}
return v, nil
}
// Field returns name for video file data
func (cfg VideoCfg) Field() string {
return videoField
}
// VoiceCfg contains information about a SendVoice request.
// Use it to send information about a venue
// Implements Filer and Messenger interfaces.
type VoiceCfg struct {
BaseFile
Duration int
}
// Name returns method name
func (cfg VoiceCfg) Name() string {
return sendVoiceMethod
}
// Values returns a url.Values representation of VoiceCfg.
func (cfg VoiceCfg) Values() (url.Values, error) {
v, err := cfg.BaseFile.Values()
if err != nil {
return nil, err
}
if cfg.BaseFile.FileID != "" {
v.Add(cfg.Field(), cfg.BaseFile.FileID)
}
if cfg.BaseFile.FileID != "" {
v.Add(cfg.Field(), cfg.BaseFile.FileID)
}
if cfg.Duration != 0 {
v.Add("duration", strconv.Itoa(cfg.Duration))
}
return v, nil
}
// Field returns name for voice file data
func (cfg VoiceCfg) Field() string {
return voiceField
}
// DocumentCfg contains information about a SendDocument request.
// Use it to send information about a documents
// Implements Filer and Messenger interfaces.
type DocumentCfg struct {
BaseFile
}
// Name returns method name
func (cfg DocumentCfg) Name() string {
return sendDocumentMethod
}
// Values returns a url.Values representation of DocumentCfg.
func (cfg DocumentCfg) Values() (url.Values, error) {
v, err := cfg.BaseFile.Values()
if err != nil {
return nil, err
}
if cfg.BaseFile.FileID != "" {
v.Add(cfg.Field(), cfg.BaseFile.FileID)
}
return v, nil
}
// Field returns name for document file data
func (cfg DocumentCfg) Field() string {
return documentField
}
// StickerCfg contains information about a SendSticker request.
// Implements Filer and Messenger interfaces.
type StickerCfg struct {
BaseFile
}
// Values returns a url.Values representation of StickerCfg.
func (cfg StickerCfg) Values() (url.Values, error) {
v, err := cfg.BaseFile.Values()
if err != nil {
return nil, err
}
if cfg.BaseFile.FileID != "" {
v.Add(cfg.Field(), cfg.BaseFile.FileID)
}
return v, nil
}
// Name method returns Telegram API method name for sending Sticker.
func (cfg StickerCfg) Name() string {
return sendStickerMethod
}
// Field returns name for sticker file data
func (cfg StickerCfg) Field() string {
return stickerField
}