go-tg-screenshot-bot

Форк
0
1
package tgbotapi
2

3
import (
4
	"bytes"
5
	"fmt"
6
	"io"
7
	"net/url"
8
	"os"
9
	"strconv"
10
)
11

12
// Telegram constants
13
const (
14
	// APIEndpoint is the endpoint for all API methods,
15
	// with formatting for Sprintf.
16
	APIEndpoint = "https://api.telegram.org/bot%s/%s"
17
	// FileEndpoint is the endpoint for downloading a file from Telegram.
18
	FileEndpoint = "https://api.telegram.org/file/bot%s/%s"
19
)
20

21
// Constant values for ChatActions
22
const (
23
	ChatTyping          = "typing"
24
	ChatUploadPhoto     = "upload_photo"
25
	ChatRecordVideo     = "record_video"
26
	ChatUploadVideo     = "upload_video"
27
	ChatRecordVoice     = "record_voice"
28
	ChatUploadVoice     = "upload_voice"
29
	ChatUploadDocument  = "upload_document"
30
	ChatChooseSticker   = "choose_sticker"
31
	ChatFindLocation    = "find_location"
32
	ChatRecordVideoNote = "record_video_note"
33
	ChatUploadVideoNote = "upload_video_note"
34
)
35

36
// API errors
37
const (
38
	// ErrAPIForbidden happens when a token is bad
39
	ErrAPIForbidden = "forbidden"
40
)
41

42
// Constant values for ParseMode in MessageConfig
43
const (
44
	ModeMarkdown   = "Markdown"
45
	ModeMarkdownV2 = "MarkdownV2"
46
	ModeHTML       = "HTML"
47
)
48

49
// Constant values for update types
50
const (
51
	// UpdateTypeMessage is new incoming message of any kind — text, photo, sticker, etc.
52
	UpdateTypeMessage = "message"
53

54
	// UpdateTypeEditedMessage is new version of a message that is known to the bot and was edited
55
	UpdateTypeEditedMessage = "edited_message"
56

57
	// UpdateTypeChannelPost is new incoming channel post of any kind — text, photo, sticker, etc.
58
	UpdateTypeChannelPost = "channel_post"
59

60
	// UpdateTypeEditedChannelPost is new version of a channel post that is known to the bot and was edited
61
	UpdateTypeEditedChannelPost = "edited_channel_post"
62

63
	// UpdateTypeInlineQuery is new incoming inline query
64
	UpdateTypeInlineQuery = "inline_query"
65

66
	// UpdateTypeChosenInlineResult i the result of an inline query that was chosen by a user and sent to their
67
	// chat partner. Please see the documentation on the feedback collecting for
68
	// details on how to enable these updates for your bot.
69
	UpdateTypeChosenInlineResult = "chosen_inline_result"
70

71
	// UpdateTypeCallbackQuery is new incoming callback query
72
	UpdateTypeCallbackQuery = "callback_query"
73

74
	// UpdateTypeShippingQuery is new incoming shipping query. Only for invoices with flexible price
75
	UpdateTypeShippingQuery = "shipping_query"
76

77
	// UpdateTypePreCheckoutQuery is new incoming pre-checkout query. Contains full information about checkout
78
	UpdateTypePreCheckoutQuery = "pre_checkout_query"
79

80
	// UpdateTypePoll is new poll state. Bots receive only updates about stopped polls and polls
81
	// which are sent by the bot
82
	UpdateTypePoll = "poll"
83

84
	// UpdateTypePollAnswer is when user changed their answer in a non-anonymous poll. Bots receive new votes
85
	// only in polls that were sent by the bot itself.
86
	UpdateTypePollAnswer = "poll_answer"
87

88
	// UpdateTypeMyChatMember is when the bot's chat member status was updated in a chat. For private chats, this
89
	// update is received only when the bot is blocked or unblocked by the user.
90
	UpdateTypeMyChatMember = "my_chat_member"
91

92
	// UpdateTypeChatMember is when the bot must be an administrator in the chat and must explicitly specify
93
	// this update in the list of allowed_updates to receive these updates.
94
	UpdateTypeChatMember = "chat_member"
95
)
96

97
// Library errors
98
const (
99
	ErrBadURL = "bad or empty url"
100
)
101

102
// Chattable is any config type that can be sent.
103
type Chattable interface {
104
	params() (Params, error)
105
	method() string
106
}
107

108
// Fileable is any config type that can be sent that includes a file.
109
type Fileable interface {
110
	Chattable
111
	files() []RequestFile
112
}
113

114
// RequestFile represents a file associated with a field name.
115
type RequestFile struct {
116
	// The file field name.
117
	Name string
118
	// The file data to include.
119
	Data RequestFileData
120
}
121

122
// RequestFileData represents the data to be used for a file.
123
type RequestFileData interface {
124
	// NeedsUpload shows if the file needs to be uploaded.
125
	NeedsUpload() bool
126

127
	// UploadData gets the file name and an `io.Reader` for the file to be uploaded. This
128
	// must only be called when the file needs to be uploaded.
129
	UploadData() (string, io.Reader, error)
130
	// SendData gets the file data to send when a file does not need to be uploaded. This
131
	// must only be called when the file does not need to be uploaded.
132
	SendData() string
133
}
134

135
// FileBytes contains information about a set of bytes to upload
136
// as a File.
137
type FileBytes struct {
138
	Name  string
139
	Bytes []byte
140
}
141

142
func (fb FileBytes) NeedsUpload() bool {
143
	return true
144
}
145

146
func (fb FileBytes) UploadData() (string, io.Reader, error) {
147
	return fb.Name, bytes.NewReader(fb.Bytes), nil
148
}
149

150
func (fb FileBytes) SendData() string {
151
	panic("FileBytes must be uploaded")
152
}
153

154
// FileReader contains information about a reader to upload as a File.
155
type FileReader struct {
156
	Name   string
157
	Reader io.Reader
158
}
159

160
func (fr FileReader) NeedsUpload() bool {
161
	return true
162
}
163

164
func (fr FileReader) UploadData() (string, io.Reader, error) {
165
	return fr.Name, fr.Reader, nil
166
}
167

168
func (fr FileReader) SendData() string {
169
	panic("FileReader must be uploaded")
170
}
171

172
// FilePath is a path to a local file.
173
type FilePath string
174

175
func (fp FilePath) NeedsUpload() bool {
176
	return true
177
}
178

179
func (fp FilePath) UploadData() (string, io.Reader, error) {
180
	fileHandle, err := os.Open(string(fp))
181
	if err != nil {
182
		return "", nil, err
183
	}
184

185
	name := fileHandle.Name()
186
	return name, fileHandle, err
187
}
188

189
func (fp FilePath) SendData() string {
190
	panic("FilePath must be uploaded")
191
}
192

193
// FileURL is a URL to use as a file for a request.
194
type FileURL string
195

196
func (fu FileURL) NeedsUpload() bool {
197
	return false
198
}
199

200
func (fu FileURL) UploadData() (string, io.Reader, error) {
201
	panic("FileURL cannot be uploaded")
202
}
203

204
func (fu FileURL) SendData() string {
205
	return string(fu)
206
}
207

208
// FileID is an ID of a file already uploaded to Telegram.
209
type FileID string
210

211
func (fi FileID) NeedsUpload() bool {
212
	return false
213
}
214

215
func (fi FileID) UploadData() (string, io.Reader, error) {
216
	panic("FileID cannot be uploaded")
217
}
218

219
func (fi FileID) SendData() string {
220
	return string(fi)
221
}
222

223
// fileAttach is an internal file type used for processed media groups.
224
type fileAttach string
225

226
func (fa fileAttach) NeedsUpload() bool {
227
	return false
228
}
229

230
func (fa fileAttach) UploadData() (string, io.Reader, error) {
231
	panic("fileAttach cannot be uploaded")
232
}
233

234
func (fa fileAttach) SendData() string {
235
	return string(fa)
236
}
237

238
// LogOutConfig is a request to log out of the cloud Bot API server.
239
//
240
// Note that you may not log back in for at least 10 minutes.
241
type LogOutConfig struct{}
242

243
func (LogOutConfig) method() string {
244
	return "logOut"
245
}
246

247
func (LogOutConfig) params() (Params, error) {
248
	return nil, nil
249
}
250

251
// CloseConfig is a request to close the bot instance on a local server.
252
//
253
// Note that you may not close an instance for the first 10 minutes after the
254
// bot has started.
255
type CloseConfig struct{}
256

257
func (CloseConfig) method() string {
258
	return "close"
259
}
260

261
func (CloseConfig) params() (Params, error) {
262
	return nil, nil
263
}
264

265
// BaseChat is base type for all chat config types.
266
type BaseChat struct {
267
	ChatID                   int64 // required
268
	ChannelUsername          string
269
	ReplyToMessageID         int
270
	ReplyMarkup              interface{}
271
	DisableNotification      bool
272
	AllowSendingWithoutReply bool
273
}
274

275
func (chat *BaseChat) params() (Params, error) {
276
	params := make(Params)
277

278
	params.AddFirstValid("chat_id", chat.ChatID, chat.ChannelUsername)
279
	params.AddNonZero("reply_to_message_id", chat.ReplyToMessageID)
280
	params.AddBool("disable_notification", chat.DisableNotification)
281
	params.AddBool("allow_sending_without_reply", chat.AllowSendingWithoutReply)
282

283
	err := params.AddInterface("reply_markup", chat.ReplyMarkup)
284

285
	return params, err
286
}
287

288
// BaseFile is a base type for all file config types.
289
type BaseFile struct {
290
	BaseChat
291
	File RequestFileData
292
}
293

294
func (file BaseFile) params() (Params, error) {
295
	return file.BaseChat.params()
296
}
297

298
// BaseEdit is base type of all chat edits.
299
type BaseEdit struct {
300
	ChatID          int64
301
	ChannelUsername string
302
	MessageID       int
303
	InlineMessageID string
304
	ReplyMarkup     *InlineKeyboardMarkup
305
}
306

307
func (edit BaseEdit) params() (Params, error) {
308
	params := make(Params)
309

310
	if edit.InlineMessageID != "" {
311
		params["inline_message_id"] = edit.InlineMessageID
312
	} else {
313
		params.AddFirstValid("chat_id", edit.ChatID, edit.ChannelUsername)
314
		params.AddNonZero("message_id", edit.MessageID)
315
	}
316

317
	err := params.AddInterface("reply_markup", edit.ReplyMarkup)
318

319
	return params, err
320
}
321

322
// MessageConfig contains information about a SendMessage request.
323
type MessageConfig struct {
324
	BaseChat
325
	Text                  string
326
	ParseMode             string
327
	Entities              []MessageEntity
328
	DisableWebPagePreview bool
329
}
330

331
func (config MessageConfig) params() (Params, error) {
332
	params, err := config.BaseChat.params()
333
	if err != nil {
334
		return params, err
335
	}
336

337
	params.AddNonEmpty("text", config.Text)
338
	params.AddBool("disable_web_page_preview", config.DisableWebPagePreview)
339
	params.AddNonEmpty("parse_mode", config.ParseMode)
340
	err = params.AddInterface("entities", config.Entities)
341

342
	return params, err
343
}
344

345
func (config MessageConfig) method() string {
346
	return "sendMessage"
347
}
348

349
// ForwardConfig contains information about a ForwardMessage request.
350
type ForwardConfig struct {
351
	BaseChat
352
	FromChatID          int64 // required
353
	FromChannelUsername string
354
	MessageID           int // required
355
}
356

357
func (config ForwardConfig) params() (Params, error) {
358
	params, err := config.BaseChat.params()
359
	if err != nil {
360
		return params, err
361
	}
362

363
	params.AddNonZero64("from_chat_id", config.FromChatID)
364
	params.AddNonZero("message_id", config.MessageID)
365

366
	return params, nil
367
}
368

369
func (config ForwardConfig) method() string {
370
	return "forwardMessage"
371
}
372

373
// CopyMessageConfig contains information about a copyMessage request.
374
type CopyMessageConfig struct {
375
	BaseChat
376
	FromChatID          int64
377
	FromChannelUsername string
378
	MessageID           int
379
	Caption             string
380
	ParseMode           string
381
	CaptionEntities     []MessageEntity
382
}
383

384
func (config CopyMessageConfig) params() (Params, error) {
385
	params, err := config.BaseChat.params()
386
	if err != nil {
387
		return params, err
388
	}
389

390
	params.AddFirstValid("from_chat_id", config.FromChatID, config.FromChannelUsername)
391
	params.AddNonZero("message_id", config.MessageID)
392
	params.AddNonEmpty("caption", config.Caption)
393
	params.AddNonEmpty("parse_mode", config.ParseMode)
394
	err = params.AddInterface("caption_entities", config.CaptionEntities)
395

396
	return params, err
397
}
398

399
func (config CopyMessageConfig) method() string {
400
	return "copyMessage"
401
}
402

403
// PhotoConfig contains information about a SendPhoto request.
404
type PhotoConfig struct {
405
	BaseFile
406
	Thumb           RequestFileData
407
	Caption         string
408
	ParseMode       string
409
	CaptionEntities []MessageEntity
410
}
411

412
func (config PhotoConfig) params() (Params, error) {
413
	params, err := config.BaseFile.params()
414
	if err != nil {
415
		return params, err
416
	}
417

418
	params.AddNonEmpty("caption", config.Caption)
419
	params.AddNonEmpty("parse_mode", config.ParseMode)
420
	err = params.AddInterface("caption_entities", config.CaptionEntities)
421

422
	return params, err
423
}
424

425
func (config PhotoConfig) method() string {
426
	return "sendPhoto"
427
}
428

429
func (config PhotoConfig) files() []RequestFile {
430
	files := []RequestFile{{
431
		Name: "photo",
432
		Data: config.File,
433
	}}
434

435
	if config.Thumb != nil {
436
		files = append(files, RequestFile{
437
			Name: "thumb",
438
			Data: config.Thumb,
439
		})
440
	}
441

442
	return files
443
}
444

445
// AudioConfig contains information about a SendAudio request.
446
type AudioConfig struct {
447
	BaseFile
448
	Thumb           RequestFileData
449
	Caption         string
450
	ParseMode       string
451
	CaptionEntities []MessageEntity
452
	Duration        int
453
	Performer       string
454
	Title           string
455
}
456

457
func (config AudioConfig) params() (Params, error) {
458
	params, err := config.BaseChat.params()
459
	if err != nil {
460
		return params, err
461
	}
462

463
	params.AddNonZero("duration", config.Duration)
464
	params.AddNonEmpty("performer", config.Performer)
465
	params.AddNonEmpty("title", config.Title)
466
	params.AddNonEmpty("caption", config.Caption)
467
	params.AddNonEmpty("parse_mode", config.ParseMode)
468
	err = params.AddInterface("caption_entities", config.CaptionEntities)
469

470
	return params, err
471
}
472

473
func (config AudioConfig) method() string {
474
	return "sendAudio"
475
}
476

477
func (config AudioConfig) files() []RequestFile {
478
	files := []RequestFile{{
479
		Name: "audio",
480
		Data: config.File,
481
	}}
482

483
	if config.Thumb != nil {
484
		files = append(files, RequestFile{
485
			Name: "thumb",
486
			Data: config.Thumb,
487
		})
488
	}
489

490
	return files
491
}
492

493
// DocumentConfig contains information about a SendDocument request.
494
type DocumentConfig struct {
495
	BaseFile
496
	Thumb                       RequestFileData
497
	Caption                     string
498
	ParseMode                   string
499
	CaptionEntities             []MessageEntity
500
	DisableContentTypeDetection bool
501
}
502

503
func (config DocumentConfig) params() (Params, error) {
504
	params, err := config.BaseFile.params()
505

506
	params.AddNonEmpty("caption", config.Caption)
507
	params.AddNonEmpty("parse_mode", config.ParseMode)
508
	params.AddBool("disable_content_type_detection", config.DisableContentTypeDetection)
509

510
	return params, err
511
}
512

513
func (config DocumentConfig) method() string {
514
	return "sendDocument"
515
}
516

517
func (config DocumentConfig) files() []RequestFile {
518
	files := []RequestFile{{
519
		Name: "document",
520
		Data: config.File,
521
	}}
522

523
	if config.Thumb != nil {
524
		files = append(files, RequestFile{
525
			Name: "thumb",
526
			Data: config.Thumb,
527
		})
528
	}
529

530
	return files
531
}
532

533
// StickerConfig contains information about a SendSticker request.
534
type StickerConfig struct {
535
	BaseFile
536
}
537

538
func (config StickerConfig) params() (Params, error) {
539
	return config.BaseChat.params()
540
}
541

542
func (config StickerConfig) method() string {
543
	return "sendSticker"
544
}
545

546
func (config StickerConfig) files() []RequestFile {
547
	return []RequestFile{{
548
		Name: "sticker",
549
		Data: config.File,
550
	}}
551
}
552

553
// VideoConfig contains information about a SendVideo request.
554
type VideoConfig struct {
555
	BaseFile
556
	Thumb             RequestFileData
557
	Duration          int
558
	Caption           string
559
	ParseMode         string
560
	CaptionEntities   []MessageEntity
561
	SupportsStreaming bool
562
}
563

564
func (config VideoConfig) params() (Params, error) {
565
	params, err := config.BaseChat.params()
566
	if err != nil {
567
		return params, err
568
	}
569

570
	params.AddNonZero("duration", config.Duration)
571
	params.AddNonEmpty("caption", config.Caption)
572
	params.AddNonEmpty("parse_mode", config.ParseMode)
573
	params.AddBool("supports_streaming", config.SupportsStreaming)
574
	err = params.AddInterface("caption_entities", config.CaptionEntities)
575

576
	return params, err
577
}
578

579
func (config VideoConfig) method() string {
580
	return "sendVideo"
581
}
582

583
func (config VideoConfig) files() []RequestFile {
584
	files := []RequestFile{{
585
		Name: "video",
586
		Data: config.File,
587
	}}
588

589
	if config.Thumb != nil {
590
		files = append(files, RequestFile{
591
			Name: "thumb",
592
			Data: config.Thumb,
593
		})
594
	}
595

596
	return files
597
}
598

599
// AnimationConfig contains information about a SendAnimation request.
600
type AnimationConfig struct {
601
	BaseFile
602
	Duration        int
603
	Thumb           RequestFileData
604
	Caption         string
605
	ParseMode       string
606
	CaptionEntities []MessageEntity
607
}
608

609
func (config AnimationConfig) params() (Params, error) {
610
	params, err := config.BaseChat.params()
611
	if err != nil {
612
		return params, err
613
	}
614

615
	params.AddNonZero("duration", config.Duration)
616
	params.AddNonEmpty("caption", config.Caption)
617
	params.AddNonEmpty("parse_mode", config.ParseMode)
618
	err = params.AddInterface("caption_entities", config.CaptionEntities)
619

620
	return params, err
621
}
622

623
func (config AnimationConfig) method() string {
624
	return "sendAnimation"
625
}
626

627
func (config AnimationConfig) files() []RequestFile {
628
	files := []RequestFile{{
629
		Name: "animation",
630
		Data: config.File,
631
	}}
632

633
	if config.Thumb != nil {
634
		files = append(files, RequestFile{
635
			Name: "thumb",
636
			Data: config.Thumb,
637
		})
638
	}
639

640
	return files
641
}
642

643
// VideoNoteConfig contains information about a SendVideoNote request.
644
type VideoNoteConfig struct {
645
	BaseFile
646
	Thumb    RequestFileData
647
	Duration int
648
	Length   int
649
}
650

651
func (config VideoNoteConfig) params() (Params, error) {
652
	params, err := config.BaseChat.params()
653

654
	params.AddNonZero("duration", config.Duration)
655
	params.AddNonZero("length", config.Length)
656

657
	return params, err
658
}
659

660
func (config VideoNoteConfig) method() string {
661
	return "sendVideoNote"
662
}
663

664
func (config VideoNoteConfig) files() []RequestFile {
665
	files := []RequestFile{{
666
		Name: "video_note",
667
		Data: config.File,
668
	}}
669

670
	if config.Thumb != nil {
671
		files = append(files, RequestFile{
672
			Name: "thumb",
673
			Data: config.Thumb,
674
		})
675
	}
676

677
	return files
678
}
679

680
// VoiceConfig contains information about a SendVoice request.
681
type VoiceConfig struct {
682
	BaseFile
683
	Thumb           RequestFileData
684
	Caption         string
685
	ParseMode       string
686
	CaptionEntities []MessageEntity
687
	Duration        int
688
}
689

690
func (config VoiceConfig) params() (Params, error) {
691
	params, err := config.BaseChat.params()
692
	if err != nil {
693
		return params, err
694
	}
695

696
	params.AddNonZero("duration", config.Duration)
697
	params.AddNonEmpty("caption", config.Caption)
698
	params.AddNonEmpty("parse_mode", config.ParseMode)
699
	err = params.AddInterface("caption_entities", config.CaptionEntities)
700

701
	return params, err
702
}
703

704
func (config VoiceConfig) method() string {
705
	return "sendVoice"
706
}
707

708
func (config VoiceConfig) files() []RequestFile {
709
	files := []RequestFile{{
710
		Name: "voice",
711
		Data: config.File,
712
	}}
713

714
	if config.Thumb != nil {
715
		files = append(files, RequestFile{
716
			Name: "thumb",
717
			Data: config.Thumb,
718
		})
719
	}
720

721
	return files
722
}
723

724
// LocationConfig contains information about a SendLocation request.
725
type LocationConfig struct {
726
	BaseChat
727
	Latitude             float64 // required
728
	Longitude            float64 // required
729
	HorizontalAccuracy   float64 // optional
730
	LivePeriod           int     // optional
731
	Heading              int     // optional
732
	ProximityAlertRadius int     // optional
733
}
734

735
func (config LocationConfig) params() (Params, error) {
736
	params, err := config.BaseChat.params()
737

738
	params.AddNonZeroFloat("latitude", config.Latitude)
739
	params.AddNonZeroFloat("longitude", config.Longitude)
740
	params.AddNonZeroFloat("horizontal_accuracy", config.HorizontalAccuracy)
741
	params.AddNonZero("live_period", config.LivePeriod)
742
	params.AddNonZero("heading", config.Heading)
743
	params.AddNonZero("proximity_alert_radius", config.ProximityAlertRadius)
744

745
	return params, err
746
}
747

748
func (config LocationConfig) method() string {
749
	return "sendLocation"
750
}
751

752
// EditMessageLiveLocationConfig allows you to update a live location.
753
type EditMessageLiveLocationConfig struct {
754
	BaseEdit
755
	Latitude             float64 // required
756
	Longitude            float64 // required
757
	HorizontalAccuracy   float64 // optional
758
	Heading              int     // optional
759
	ProximityAlertRadius int     // optional
760
}
761

762
func (config EditMessageLiveLocationConfig) params() (Params, error) {
763
	params, err := config.BaseEdit.params()
764

765
	params.AddNonZeroFloat("latitude", config.Latitude)
766
	params.AddNonZeroFloat("longitude", config.Longitude)
767
	params.AddNonZeroFloat("horizontal_accuracy", config.HorizontalAccuracy)
768
	params.AddNonZero("heading", config.Heading)
769
	params.AddNonZero("proximity_alert_radius", config.ProximityAlertRadius)
770

771
	return params, err
772
}
773

774
func (config EditMessageLiveLocationConfig) method() string {
775
	return "editMessageLiveLocation"
776
}
777

778
// StopMessageLiveLocationConfig stops updating a live location.
779
type StopMessageLiveLocationConfig struct {
780
	BaseEdit
781
}
782

783
func (config StopMessageLiveLocationConfig) params() (Params, error) {
784
	return config.BaseEdit.params()
785
}
786

787
func (config StopMessageLiveLocationConfig) method() string {
788
	return "stopMessageLiveLocation"
789
}
790

791
// VenueConfig contains information about a SendVenue request.
792
type VenueConfig struct {
793
	BaseChat
794
	Latitude        float64 // required
795
	Longitude       float64 // required
796
	Title           string  // required
797
	Address         string  // required
798
	FoursquareID    string
799
	FoursquareType  string
800
	GooglePlaceID   string
801
	GooglePlaceType string
802
}
803

804
func (config VenueConfig) params() (Params, error) {
805
	params, err := config.BaseChat.params()
806

807
	params.AddNonZeroFloat("latitude", config.Latitude)
808
	params.AddNonZeroFloat("longitude", config.Longitude)
809
	params["title"] = config.Title
810
	params["address"] = config.Address
811
	params.AddNonEmpty("foursquare_id", config.FoursquareID)
812
	params.AddNonEmpty("foursquare_type", config.FoursquareType)
813
	params.AddNonEmpty("google_place_id", config.GooglePlaceID)
814
	params.AddNonEmpty("google_place_type", config.GooglePlaceType)
815

816
	return params, err
817
}
818

819
func (config VenueConfig) method() string {
820
	return "sendVenue"
821
}
822

823
// ContactConfig allows you to send a contact.
824
type ContactConfig struct {
825
	BaseChat
826
	PhoneNumber string
827
	FirstName   string
828
	LastName    string
829
	VCard       string
830
}
831

832
func (config ContactConfig) params() (Params, error) {
833
	params, err := config.BaseChat.params()
834

835
	params["phone_number"] = config.PhoneNumber
836
	params["first_name"] = config.FirstName
837

838
	params.AddNonEmpty("last_name", config.LastName)
839
	params.AddNonEmpty("vcard", config.VCard)
840

841
	return params, err
842
}
843

844
func (config ContactConfig) method() string {
845
	return "sendContact"
846
}
847

848
// SendPollConfig allows you to send a poll.
849
type SendPollConfig struct {
850
	BaseChat
851
	Question              string
852
	Options               []string
853
	IsAnonymous           bool
854
	Type                  string
855
	AllowsMultipleAnswers bool
856
	CorrectOptionID       int64
857
	Explanation           string
858
	ExplanationParseMode  string
859
	ExplanationEntities   []MessageEntity
860
	OpenPeriod            int
861
	CloseDate             int
862
	IsClosed              bool
863
}
864

865
func (config SendPollConfig) params() (Params, error) {
866
	params, err := config.BaseChat.params()
867
	if err != nil {
868
		return params, err
869
	}
870

871
	params["question"] = config.Question
872
	if err = params.AddInterface("options", config.Options); err != nil {
873
		return params, err
874
	}
875
	params["is_anonymous"] = strconv.FormatBool(config.IsAnonymous)
876
	params.AddNonEmpty("type", config.Type)
877
	params["allows_multiple_answers"] = strconv.FormatBool(config.AllowsMultipleAnswers)
878
	params["correct_option_id"] = strconv.FormatInt(config.CorrectOptionID, 10)
879
	params.AddBool("is_closed", config.IsClosed)
880
	params.AddNonEmpty("explanation", config.Explanation)
881
	params.AddNonEmpty("explanation_parse_mode", config.ExplanationParseMode)
882
	params.AddNonZero("open_period", config.OpenPeriod)
883
	params.AddNonZero("close_date", config.CloseDate)
884
	err = params.AddInterface("explanation_entities", config.ExplanationEntities)
885

886
	return params, err
887
}
888

889
func (SendPollConfig) method() string {
890
	return "sendPoll"
891
}
892

893
// GameConfig allows you to send a game.
894
type GameConfig struct {
895
	BaseChat
896
	GameShortName string
897
}
898

899
func (config GameConfig) params() (Params, error) {
900
	params, err := config.BaseChat.params()
901

902
	params["game_short_name"] = config.GameShortName
903

904
	return params, err
905
}
906

907
func (config GameConfig) method() string {
908
	return "sendGame"
909
}
910

911
// SetGameScoreConfig allows you to update the game score in a chat.
912
type SetGameScoreConfig struct {
913
	UserID             int64
914
	Score              int
915
	Force              bool
916
	DisableEditMessage bool
917
	ChatID             int64
918
	ChannelUsername    string
919
	MessageID          int
920
	InlineMessageID    string
921
}
922

923
func (config SetGameScoreConfig) params() (Params, error) {
924
	params := make(Params)
925

926
	params.AddNonZero64("user_id", config.UserID)
927
	params.AddNonZero("scrore", config.Score)
928
	params.AddBool("disable_edit_message", config.DisableEditMessage)
929

930
	if config.InlineMessageID != "" {
931
		params["inline_message_id"] = config.InlineMessageID
932
	} else {
933
		params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
934
		params.AddNonZero("message_id", config.MessageID)
935
	}
936

937
	return params, nil
938
}
939

940
func (config SetGameScoreConfig) method() string {
941
	return "setGameScore"
942
}
943

944
// GetGameHighScoresConfig allows you to fetch the high scores for a game.
945
type GetGameHighScoresConfig struct {
946
	UserID          int64
947
	ChatID          int64
948
	ChannelUsername string
949
	MessageID       int
950
	InlineMessageID string
951
}
952

953
func (config GetGameHighScoresConfig) params() (Params, error) {
954
	params := make(Params)
955

956
	params.AddNonZero64("user_id", config.UserID)
957

958
	if config.InlineMessageID != "" {
959
		params["inline_message_id"] = config.InlineMessageID
960
	} else {
961
		params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
962
		params.AddNonZero("message_id", config.MessageID)
963
	}
964

965
	return params, nil
966
}
967

968
func (config GetGameHighScoresConfig) method() string {
969
	return "getGameHighScores"
970
}
971

972
// ChatActionConfig contains information about a SendChatAction request.
973
type ChatActionConfig struct {
974
	BaseChat
975
	Action string // required
976
}
977

978
func (config ChatActionConfig) params() (Params, error) {
979
	params, err := config.BaseChat.params()
980

981
	params["action"] = config.Action
982

983
	return params, err
984
}
985

986
func (config ChatActionConfig) method() string {
987
	return "sendChatAction"
988
}
989

990
// EditMessageTextConfig allows you to modify the text in a message.
991
type EditMessageTextConfig struct {
992
	BaseEdit
993
	Text                  string
994
	ParseMode             string
995
	Entities              []MessageEntity
996
	DisableWebPagePreview bool
997
}
998

999
func (config EditMessageTextConfig) params() (Params, error) {
1000
	params, err := config.BaseEdit.params()
1001
	if err != nil {
1002
		return params, err
1003
	}
1004

1005
	params["text"] = config.Text
1006
	params.AddNonEmpty("parse_mode", config.ParseMode)
1007
	params.AddBool("disable_web_page_preview", config.DisableWebPagePreview)
1008
	err = params.AddInterface("entities", config.Entities)
1009

1010
	return params, err
1011
}
1012

1013
func (config EditMessageTextConfig) method() string {
1014
	return "editMessageText"
1015
}
1016

1017
// EditMessageCaptionConfig allows you to modify the caption of a message.
1018
type EditMessageCaptionConfig struct {
1019
	BaseEdit
1020
	Caption         string
1021
	ParseMode       string
1022
	CaptionEntities []MessageEntity
1023
}
1024

1025
func (config EditMessageCaptionConfig) params() (Params, error) {
1026
	params, err := config.BaseEdit.params()
1027
	if err != nil {
1028
		return params, err
1029
	}
1030

1031
	params["caption"] = config.Caption
1032
	params.AddNonEmpty("parse_mode", config.ParseMode)
1033
	err = params.AddInterface("caption_entities", config.CaptionEntities)
1034

1035
	return params, err
1036
}
1037

1038
func (config EditMessageCaptionConfig) method() string {
1039
	return "editMessageCaption"
1040
}
1041

1042
// EditMessageMediaConfig allows you to make an editMessageMedia request.
1043
type EditMessageMediaConfig struct {
1044
	BaseEdit
1045

1046
	Media interface{}
1047
}
1048

1049
func (EditMessageMediaConfig) method() string {
1050
	return "editMessageMedia"
1051
}
1052

1053
func (config EditMessageMediaConfig) params() (Params, error) {
1054
	params, err := config.BaseEdit.params()
1055
	if err != nil {
1056
		return params, err
1057
	}
1058

1059
	err = params.AddInterface("media", prepareInputMediaParam(config.Media, 0))
1060

1061
	return params, err
1062
}
1063

1064
func (config EditMessageMediaConfig) files() []RequestFile {
1065
	return prepareInputMediaFile(config.Media, 0)
1066
}
1067

1068
// EditMessageReplyMarkupConfig allows you to modify the reply markup
1069
// of a message.
1070
type EditMessageReplyMarkupConfig struct {
1071
	BaseEdit
1072
}
1073

1074
func (config EditMessageReplyMarkupConfig) params() (Params, error) {
1075
	return config.BaseEdit.params()
1076
}
1077

1078
func (config EditMessageReplyMarkupConfig) method() string {
1079
	return "editMessageReplyMarkup"
1080
}
1081

1082
// StopPollConfig allows you to stop a poll sent by the bot.
1083
type StopPollConfig struct {
1084
	BaseEdit
1085
}
1086

1087
func (config StopPollConfig) params() (Params, error) {
1088
	return config.BaseEdit.params()
1089
}
1090

1091
func (StopPollConfig) method() string {
1092
	return "stopPoll"
1093
}
1094

1095
// UserProfilePhotosConfig contains information about a
1096
// GetUserProfilePhotos request.
1097
type UserProfilePhotosConfig struct {
1098
	UserID int64
1099
	Offset int
1100
	Limit  int
1101
}
1102

1103
func (UserProfilePhotosConfig) method() string {
1104
	return "getUserProfilePhotos"
1105
}
1106

1107
func (config UserProfilePhotosConfig) params() (Params, error) {
1108
	params := make(Params)
1109

1110
	params.AddNonZero64("user_id", config.UserID)
1111
	params.AddNonZero("offset", config.Offset)
1112
	params.AddNonZero("limit", config.Limit)
1113

1114
	return params, nil
1115
}
1116

1117
// FileConfig has information about a file hosted on Telegram.
1118
type FileConfig struct {
1119
	FileID string
1120
}
1121

1122
func (FileConfig) method() string {
1123
	return "getFile"
1124
}
1125

1126
func (config FileConfig) params() (Params, error) {
1127
	params := make(Params)
1128

1129
	params["file_id"] = config.FileID
1130

1131
	return params, nil
1132
}
1133

1134
// UpdateConfig contains information about a GetUpdates request.
1135
type UpdateConfig struct {
1136
	Offset         int
1137
	Limit          int
1138
	Timeout        int
1139
	AllowedUpdates []string
1140
}
1141

1142
func (UpdateConfig) method() string {
1143
	return "getUpdates"
1144
}
1145

1146
func (config UpdateConfig) params() (Params, error) {
1147
	params := make(Params)
1148

1149
	params.AddNonZero("offset", config.Offset)
1150
	params.AddNonZero("limit", config.Limit)
1151
	params.AddNonZero("timeout", config.Timeout)
1152
	params.AddInterface("allowed_updates", config.AllowedUpdates)
1153

1154
	return params, nil
1155
}
1156

1157
// WebhookConfig contains information about a SetWebhook request.
1158
type WebhookConfig struct {
1159
	URL                *url.URL
1160
	Certificate        RequestFileData
1161
	IPAddress          string
1162
	MaxConnections     int
1163
	AllowedUpdates     []string
1164
	DropPendingUpdates bool
1165
}
1166

1167
func (config WebhookConfig) method() string {
1168
	return "setWebhook"
1169
}
1170

1171
func (config WebhookConfig) params() (Params, error) {
1172
	params := make(Params)
1173

1174
	if config.URL != nil {
1175
		params["url"] = config.URL.String()
1176
	}
1177

1178
	params.AddNonEmpty("ip_address", config.IPAddress)
1179
	params.AddNonZero("max_connections", config.MaxConnections)
1180
	err := params.AddInterface("allowed_updates", config.AllowedUpdates)
1181
	params.AddBool("drop_pending_updates", config.DropPendingUpdates)
1182

1183
	return params, err
1184
}
1185

1186
func (config WebhookConfig) files() []RequestFile {
1187
	if config.Certificate != nil {
1188
		return []RequestFile{{
1189
			Name: "certificate",
1190
			Data: config.Certificate,
1191
		}}
1192
	}
1193

1194
	return nil
1195
}
1196

1197
// DeleteWebhookConfig is a helper to delete a webhook.
1198
type DeleteWebhookConfig struct {
1199
	DropPendingUpdates bool
1200
}
1201

1202
func (config DeleteWebhookConfig) method() string {
1203
	return "deleteWebhook"
1204
}
1205

1206
func (config DeleteWebhookConfig) params() (Params, error) {
1207
	params := make(Params)
1208

1209
	params.AddBool("drop_pending_updates", config.DropPendingUpdates)
1210

1211
	return params, nil
1212
}
1213

1214
// InlineConfig contains information on making an InlineQuery response.
1215
type InlineConfig struct {
1216
	InlineQueryID     string        `json:"inline_query_id"`
1217
	Results           []interface{} `json:"results"`
1218
	CacheTime         int           `json:"cache_time"`
1219
	IsPersonal        bool          `json:"is_personal"`
1220
	NextOffset        string        `json:"next_offset"`
1221
	SwitchPMText      string        `json:"switch_pm_text"`
1222
	SwitchPMParameter string        `json:"switch_pm_parameter"`
1223
}
1224

1225
func (config InlineConfig) method() string {
1226
	return "answerInlineQuery"
1227
}
1228

1229
func (config InlineConfig) params() (Params, error) {
1230
	params := make(Params)
1231

1232
	params["inline_query_id"] = config.InlineQueryID
1233
	params.AddNonZero("cache_time", config.CacheTime)
1234
	params.AddBool("is_personal", config.IsPersonal)
1235
	params.AddNonEmpty("next_offset", config.NextOffset)
1236
	params.AddNonEmpty("switch_pm_text", config.SwitchPMText)
1237
	params.AddNonEmpty("switch_pm_parameter", config.SwitchPMParameter)
1238
	err := params.AddInterface("results", config.Results)
1239

1240
	return params, err
1241
}
1242

1243
// CallbackConfig contains information on making a CallbackQuery response.
1244
type CallbackConfig struct {
1245
	CallbackQueryID string `json:"callback_query_id"`
1246
	Text            string `json:"text"`
1247
	ShowAlert       bool   `json:"show_alert"`
1248
	URL             string `json:"url"`
1249
	CacheTime       int    `json:"cache_time"`
1250
}
1251

1252
func (config CallbackConfig) method() string {
1253
	return "answerCallbackQuery"
1254
}
1255

1256
func (config CallbackConfig) params() (Params, error) {
1257
	params := make(Params)
1258

1259
	params["callback_query_id"] = config.CallbackQueryID
1260
	params.AddNonEmpty("text", config.Text)
1261
	params.AddBool("show_alert", config.ShowAlert)
1262
	params.AddNonEmpty("url", config.URL)
1263
	params.AddNonZero("cache_time", config.CacheTime)
1264

1265
	return params, nil
1266
}
1267

1268
// ChatMemberConfig contains information about a user in a chat for use
1269
// with administrative functions such as kicking or unbanning a user.
1270
type ChatMemberConfig struct {
1271
	ChatID             int64
1272
	SuperGroupUsername string
1273
	ChannelUsername    string
1274
	UserID             int64
1275
}
1276

1277
// UnbanChatMemberConfig allows you to unban a user.
1278
type UnbanChatMemberConfig struct {
1279
	ChatMemberConfig
1280
	OnlyIfBanned bool
1281
}
1282

1283
func (config UnbanChatMemberConfig) method() string {
1284
	return "unbanChatMember"
1285
}
1286

1287
func (config UnbanChatMemberConfig) params() (Params, error) {
1288
	params := make(Params)
1289

1290
	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername)
1291
	params.AddNonZero64("user_id", config.UserID)
1292
	params.AddBool("only_if_banned", config.OnlyIfBanned)
1293

1294
	return params, nil
1295
}
1296

1297
// BanChatMemberConfig contains extra fields to kick user.
1298
type BanChatMemberConfig struct {
1299
	ChatMemberConfig
1300
	UntilDate      int64
1301
	RevokeMessages bool
1302
}
1303

1304
func (config BanChatMemberConfig) method() string {
1305
	return "banChatMember"
1306
}
1307

1308
func (config BanChatMemberConfig) params() (Params, error) {
1309
	params := make(Params)
1310

1311
	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1312
	params.AddNonZero64("user_id", config.UserID)
1313
	params.AddNonZero64("until_date", config.UntilDate)
1314
	params.AddBool("revoke_messages", config.RevokeMessages)
1315

1316
	return params, nil
1317
}
1318

1319
// KickChatMemberConfig contains extra fields to ban user.
1320
//
1321
// This was renamed to BanChatMember in later versions of the Telegram Bot API.
1322
type KickChatMemberConfig = BanChatMemberConfig
1323

1324
// RestrictChatMemberConfig contains fields to restrict members of chat
1325
type RestrictChatMemberConfig struct {
1326
	ChatMemberConfig
1327
	UntilDate   int64
1328
	Permissions *ChatPermissions
1329
}
1330

1331
func (config RestrictChatMemberConfig) method() string {
1332
	return "restrictChatMember"
1333
}
1334

1335
func (config RestrictChatMemberConfig) params() (Params, error) {
1336
	params := make(Params)
1337

1338
	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername)
1339
	params.AddNonZero64("user_id", config.UserID)
1340

1341
	err := params.AddInterface("permissions", config.Permissions)
1342
	params.AddNonZero64("until_date", config.UntilDate)
1343

1344
	return params, err
1345
}
1346

1347
// PromoteChatMemberConfig contains fields to promote members of chat
1348
type PromoteChatMemberConfig struct {
1349
	ChatMemberConfig
1350
	IsAnonymous         bool
1351
	CanManageChat       bool
1352
	CanChangeInfo       bool
1353
	CanPostMessages     bool
1354
	CanEditMessages     bool
1355
	CanDeleteMessages   bool
1356
	CanManageVoiceChats bool
1357
	CanInviteUsers      bool
1358
	CanRestrictMembers  bool
1359
	CanPinMessages      bool
1360
	CanPromoteMembers   bool
1361
}
1362

1363
func (config PromoteChatMemberConfig) method() string {
1364
	return "promoteChatMember"
1365
}
1366

1367
func (config PromoteChatMemberConfig) params() (Params, error) {
1368
	params := make(Params)
1369

1370
	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername)
1371
	params.AddNonZero64("user_id", config.UserID)
1372

1373
	params.AddBool("is_anonymous", config.IsAnonymous)
1374
	params.AddBool("can_manage_chat", config.CanManageChat)
1375
	params.AddBool("can_change_info", config.CanChangeInfo)
1376
	params.AddBool("can_post_messages", config.CanPostMessages)
1377
	params.AddBool("can_edit_messages", config.CanEditMessages)
1378
	params.AddBool("can_delete_messages", config.CanDeleteMessages)
1379
	params.AddBool("can_manage_voice_chats", config.CanManageVoiceChats)
1380
	params.AddBool("can_invite_users", config.CanInviteUsers)
1381
	params.AddBool("can_restrict_members", config.CanRestrictMembers)
1382
	params.AddBool("can_pin_messages", config.CanPinMessages)
1383
	params.AddBool("can_promote_members", config.CanPromoteMembers)
1384

1385
	return params, nil
1386
}
1387

1388
// SetChatAdministratorCustomTitle sets the title of an administrative user
1389
// promoted by the bot for a chat.
1390
type SetChatAdministratorCustomTitle struct {
1391
	ChatMemberConfig
1392
	CustomTitle string
1393
}
1394

1395
func (SetChatAdministratorCustomTitle) method() string {
1396
	return "setChatAdministratorCustomTitle"
1397
}
1398

1399
func (config SetChatAdministratorCustomTitle) params() (Params, error) {
1400
	params := make(Params)
1401

1402
	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername)
1403
	params.AddNonZero64("user_id", config.UserID)
1404
	params.AddNonEmpty("custom_title", config.CustomTitle)
1405

1406
	return params, nil
1407
}
1408

1409
// BanChatSenderChatConfig bans a channel chat in a supergroup or a channel. The
1410
// owner of the chat will not be able to send messages and join live streams on
1411
// behalf of the chat, unless it is unbanned first. The bot must be an
1412
// administrator in the supergroup or channel for this to work and must have the
1413
// appropriate administrator rights.
1414
type BanChatSenderChatConfig struct {
1415
	ChatID          int64
1416
	ChannelUsername string
1417
	SenderChatID    int64
1418
	UntilDate       int
1419
}
1420

1421
func (config BanChatSenderChatConfig) method() string {
1422
	return "banChatSenderChat"
1423
}
1424

1425
func (config BanChatSenderChatConfig) params() (Params, error) {
1426
	params := make(Params)
1427

1428
	_ = params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1429
	params.AddNonZero64("sender_chat_id", config.SenderChatID)
1430
	params.AddNonZero("until_date", config.UntilDate)
1431

1432
	return params, nil
1433
}
1434

1435
// UnbanChatSenderChatConfig unbans a previously banned channel chat in a
1436
// supergroup or channel. The bot must be an administrator for this to work and
1437
// must have the appropriate administrator rights.
1438
type UnbanChatSenderChatConfig struct {
1439
	ChatID          int64
1440
	ChannelUsername string
1441
	SenderChatID    int64
1442
}
1443

1444
func (config UnbanChatSenderChatConfig) method() string {
1445
	return "unbanChatSenderChat"
1446
}
1447

1448
func (config UnbanChatSenderChatConfig) params() (Params, error) {
1449
	params := make(Params)
1450

1451
	_ = params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1452
	params.AddNonZero64("sender_chat_id", config.SenderChatID)
1453

1454
	return params, nil
1455
}
1456

1457
// ChatConfig contains information about getting information on a chat.
1458
type ChatConfig struct {
1459
	ChatID             int64
1460
	SuperGroupUsername string
1461
}
1462

1463
func (config ChatConfig) params() (Params, error) {
1464
	params := make(Params)
1465

1466
	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1467

1468
	return params, nil
1469
}
1470

1471
// ChatInfoConfig contains information about getting chat information.
1472
type ChatInfoConfig struct {
1473
	ChatConfig
1474
}
1475

1476
func (ChatInfoConfig) method() string {
1477
	return "getChat"
1478
}
1479

1480
// ChatMemberCountConfig contains information about getting the number of users in a chat.
1481
type ChatMemberCountConfig struct {
1482
	ChatConfig
1483
}
1484

1485
func (ChatMemberCountConfig) method() string {
1486
	return "getChatMembersCount"
1487
}
1488

1489
// ChatAdministratorsConfig contains information about getting chat administrators.
1490
type ChatAdministratorsConfig struct {
1491
	ChatConfig
1492
}
1493

1494
func (ChatAdministratorsConfig) method() string {
1495
	return "getChatAdministrators"
1496
}
1497

1498
// SetChatPermissionsConfig allows you to set default permissions for the
1499
// members in a group. The bot must be an administrator and have rights to
1500
// restrict members.
1501
type SetChatPermissionsConfig struct {
1502
	ChatConfig
1503
	Permissions *ChatPermissions
1504
}
1505

1506
func (SetChatPermissionsConfig) method() string {
1507
	return "setChatPermissions"
1508
}
1509

1510
func (config SetChatPermissionsConfig) params() (Params, error) {
1511
	params := make(Params)
1512

1513
	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1514
	err := params.AddInterface("permissions", config.Permissions)
1515

1516
	return params, err
1517
}
1518

1519
// ChatInviteLinkConfig contains information about getting a chat link.
1520
//
1521
// Note that generating a new link will revoke any previous links.
1522
type ChatInviteLinkConfig struct {
1523
	ChatConfig
1524
}
1525

1526
func (ChatInviteLinkConfig) method() string {
1527
	return "exportChatInviteLink"
1528
}
1529

1530
func (config ChatInviteLinkConfig) params() (Params, error) {
1531
	params := make(Params)
1532

1533
	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1534

1535
	return params, nil
1536
}
1537

1538
// CreateChatInviteLinkConfig allows you to create an additional invite link for
1539
// a chat. The bot must be an administrator in the chat for this to work and
1540
// must have the appropriate admin rights. The link can be revoked using the
1541
// RevokeChatInviteLinkConfig.
1542
type CreateChatInviteLinkConfig struct {
1543
	ChatConfig
1544
	Name               string
1545
	ExpireDate         int
1546
	MemberLimit        int
1547
	CreatesJoinRequest bool
1548
}
1549

1550
func (CreateChatInviteLinkConfig) method() string {
1551
	return "createChatInviteLink"
1552
}
1553

1554
func (config CreateChatInviteLinkConfig) params() (Params, error) {
1555
	params := make(Params)
1556

1557
	params.AddNonEmpty("name", config.Name)
1558
	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1559
	params.AddNonZero("expire_date", config.ExpireDate)
1560
	params.AddNonZero("member_limit", config.MemberLimit)
1561
	params.AddBool("creates_join_request", config.CreatesJoinRequest)
1562

1563
	return params, nil
1564
}
1565

1566
// EditChatInviteLinkConfig allows you to edit a non-primary invite link created
1567
// by the bot. The bot must be an administrator in the chat for this to work and
1568
// must have the appropriate admin rights.
1569
type EditChatInviteLinkConfig struct {
1570
	ChatConfig
1571
	InviteLink         string
1572
	Name               string
1573
	ExpireDate         int
1574
	MemberLimit        int
1575
	CreatesJoinRequest bool
1576
}
1577

1578
func (EditChatInviteLinkConfig) method() string {
1579
	return "editChatInviteLink"
1580
}
1581

1582
func (config EditChatInviteLinkConfig) params() (Params, error) {
1583
	params := make(Params)
1584

1585
	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1586
	params.AddNonEmpty("name", config.Name)
1587
	params["invite_link"] = config.InviteLink
1588
	params.AddNonZero("expire_date", config.ExpireDate)
1589
	params.AddNonZero("member_limit", config.MemberLimit)
1590
	params.AddBool("creates_join_request", config.CreatesJoinRequest)
1591

1592
	return params, nil
1593
}
1594

1595
// RevokeChatInviteLinkConfig allows you to revoke an invite link created by the
1596
// bot. If the primary link is revoked, a new link is automatically generated.
1597
// The bot must be an administrator in the chat for this to work and must have
1598
// the appropriate admin rights.
1599
type RevokeChatInviteLinkConfig struct {
1600
	ChatConfig
1601
	InviteLink string
1602
}
1603

1604
func (RevokeChatInviteLinkConfig) method() string {
1605
	return "revokeChatInviteLink"
1606
}
1607

1608
func (config RevokeChatInviteLinkConfig) params() (Params, error) {
1609
	params := make(Params)
1610

1611
	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1612
	params["invite_link"] = config.InviteLink
1613

1614
	return params, nil
1615
}
1616

1617
// ApproveChatJoinRequestConfig allows you to approve a chat join request.
1618
type ApproveChatJoinRequestConfig struct {
1619
	ChatConfig
1620
	UserID int64
1621
}
1622

1623
func (ApproveChatJoinRequestConfig) method() string {
1624
	return "approveChatJoinRequest"
1625
}
1626

1627
func (config ApproveChatJoinRequestConfig) params() (Params, error) {
1628
	params := make(Params)
1629

1630
	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1631
	params.AddNonZero("user_id", int(config.UserID))
1632

1633
	return params, nil
1634
}
1635

1636
// DeclineChatJoinRequest allows you to decline a chat join request.
1637
type DeclineChatJoinRequest struct {
1638
	ChatConfig
1639
	UserID int64
1640
}
1641

1642
func (DeclineChatJoinRequest) method() string {
1643
	return "declineChatJoinRequest"
1644
}
1645

1646
func (config DeclineChatJoinRequest) params() (Params, error) {
1647
	params := make(Params)
1648

1649
	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1650
	params.AddNonZero("user_id", int(config.UserID))
1651

1652
	return params, nil
1653
}
1654

1655
// LeaveChatConfig allows you to leave a chat.
1656
type LeaveChatConfig struct {
1657
	ChatID          int64
1658
	ChannelUsername string
1659
}
1660

1661
func (config LeaveChatConfig) method() string {
1662
	return "leaveChat"
1663
}
1664

1665
func (config LeaveChatConfig) params() (Params, error) {
1666
	params := make(Params)
1667

1668
	params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1669

1670
	return params, nil
1671
}
1672

1673
// ChatConfigWithUser contains information about a chat and a user.
1674
type ChatConfigWithUser struct {
1675
	ChatID             int64
1676
	SuperGroupUsername string
1677
	UserID             int64
1678
}
1679

1680
func (config ChatConfigWithUser) params() (Params, error) {
1681
	params := make(Params)
1682

1683
	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
1684
	params.AddNonZero64("user_id", config.UserID)
1685

1686
	return params, nil
1687
}
1688

1689
// GetChatMemberConfig is information about getting a specific member in a chat.
1690
type GetChatMemberConfig struct {
1691
	ChatConfigWithUser
1692
}
1693

1694
func (GetChatMemberConfig) method() string {
1695
	return "getChatMember"
1696
}
1697

1698
// InvoiceConfig contains information for sendInvoice request.
1699
type InvoiceConfig struct {
1700
	BaseChat
1701
	Title                     string         // required
1702
	Description               string         // required
1703
	Payload                   string         // required
1704
	ProviderToken             string         // required
1705
	Currency                  string         // required
1706
	Prices                    []LabeledPrice // required
1707
	MaxTipAmount              int
1708
	SuggestedTipAmounts       []int
1709
	StartParameter            string
1710
	ProviderData              string
1711
	PhotoURL                  string
1712
	PhotoSize                 int
1713
	PhotoWidth                int
1714
	PhotoHeight               int
1715
	NeedName                  bool
1716
	NeedPhoneNumber           bool
1717
	NeedEmail                 bool
1718
	NeedShippingAddress       bool
1719
	SendPhoneNumberToProvider bool
1720
	SendEmailToProvider       bool
1721
	IsFlexible                bool
1722
}
1723

1724
func (config InvoiceConfig) params() (Params, error) {
1725
	params, err := config.BaseChat.params()
1726
	if err != nil {
1727
		return params, err
1728
	}
1729

1730
	params["title"] = config.Title
1731
	params["description"] = config.Description
1732
	params["payload"] = config.Payload
1733
	params["provider_token"] = config.ProviderToken
1734
	params["currency"] = config.Currency
1735
	if err = params.AddInterface("prices", config.Prices); err != nil {
1736
		return params, err
1737
	}
1738

1739
	params.AddNonZero("max_tip_amount", config.MaxTipAmount)
1740
	err = params.AddInterface("suggested_tip_amounts", config.SuggestedTipAmounts)
1741
	params.AddNonEmpty("start_parameter", config.StartParameter)
1742
	params.AddNonEmpty("provider_data", config.ProviderData)
1743
	params.AddNonEmpty("photo_url", config.PhotoURL)
1744
	params.AddNonZero("photo_size", config.PhotoSize)
1745
	params.AddNonZero("photo_width", config.PhotoWidth)
1746
	params.AddNonZero("photo_height", config.PhotoHeight)
1747
	params.AddBool("need_name", config.NeedName)
1748
	params.AddBool("need_phone_number", config.NeedPhoneNumber)
1749
	params.AddBool("need_email", config.NeedEmail)
1750
	params.AddBool("need_shipping_address", config.NeedShippingAddress)
1751
	params.AddBool("is_flexible", config.IsFlexible)
1752
	params.AddBool("send_phone_number_to_provider", config.SendPhoneNumberToProvider)
1753
	params.AddBool("send_email_to_provider", config.SendEmailToProvider)
1754

1755
	return params, err
1756
}
1757

1758
func (config InvoiceConfig) method() string {
1759
	return "sendInvoice"
1760
}
1761

1762
// ShippingConfig contains information for answerShippingQuery request.
1763
type ShippingConfig struct {
1764
	ShippingQueryID string // required
1765
	OK              bool   // required
1766
	ShippingOptions []ShippingOption
1767
	ErrorMessage    string
1768
}
1769

1770
func (config ShippingConfig) method() string {
1771
	return "answerShippingQuery"
1772
}
1773

1774
func (config ShippingConfig) params() (Params, error) {
1775
	params := make(Params)
1776

1777
	params["shipping_query_id"] = config.ShippingQueryID
1778
	params.AddBool("ok", config.OK)
1779
	err := params.AddInterface("shipping_options", config.ShippingOptions)
1780
	params.AddNonEmpty("error_message", config.ErrorMessage)
1781

1782
	return params, err
1783
}
1784

1785
// PreCheckoutConfig conatins information for answerPreCheckoutQuery request.
1786
type PreCheckoutConfig struct {
1787
	PreCheckoutQueryID string // required
1788
	OK                 bool   // required
1789
	ErrorMessage       string
1790
}
1791

1792
func (config PreCheckoutConfig) method() string {
1793
	return "answerPreCheckoutQuery"
1794
}
1795

1796
func (config PreCheckoutConfig) params() (Params, error) {
1797
	params := make(Params)
1798

1799
	params["pre_checkout_query_id"] = config.PreCheckoutQueryID
1800
	params.AddBool("ok", config.OK)
1801
	params.AddNonEmpty("error_message", config.ErrorMessage)
1802

1803
	return params, nil
1804
}
1805

1806
// DeleteMessageConfig contains information of a message in a chat to delete.
1807
type DeleteMessageConfig struct {
1808
	ChannelUsername string
1809
	ChatID          int64
1810
	MessageID       int
1811
}
1812

1813
func (config DeleteMessageConfig) method() string {
1814
	return "deleteMessage"
1815
}
1816

1817
func (config DeleteMessageConfig) params() (Params, error) {
1818
	params := make(Params)
1819

1820
	params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1821
	params.AddNonZero("message_id", config.MessageID)
1822

1823
	return params, nil
1824
}
1825

1826
// PinChatMessageConfig contains information of a message in a chat to pin.
1827
type PinChatMessageConfig struct {
1828
	ChatID              int64
1829
	ChannelUsername     string
1830
	MessageID           int
1831
	DisableNotification bool
1832
}
1833

1834
func (config PinChatMessageConfig) method() string {
1835
	return "pinChatMessage"
1836
}
1837

1838
func (config PinChatMessageConfig) params() (Params, error) {
1839
	params := make(Params)
1840

1841
	params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1842
	params.AddNonZero("message_id", config.MessageID)
1843
	params.AddBool("disable_notification", config.DisableNotification)
1844

1845
	return params, nil
1846
}
1847

1848
// UnpinChatMessageConfig contains information of a chat message to unpin.
1849
//
1850
// If MessageID is not specified, it will unpin the most recent pin.
1851
type UnpinChatMessageConfig struct {
1852
	ChatID          int64
1853
	ChannelUsername string
1854
	MessageID       int
1855
}
1856

1857
func (config UnpinChatMessageConfig) method() string {
1858
	return "unpinChatMessage"
1859
}
1860

1861
func (config UnpinChatMessageConfig) params() (Params, error) {
1862
	params := make(Params)
1863

1864
	params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1865
	params.AddNonZero("message_id", config.MessageID)
1866

1867
	return params, nil
1868
}
1869

1870
// UnpinAllChatMessagesConfig contains information of all messages to unpin in
1871
// a chat.
1872
type UnpinAllChatMessagesConfig struct {
1873
	ChatID          int64
1874
	ChannelUsername string
1875
}
1876

1877
func (config UnpinAllChatMessagesConfig) method() string {
1878
	return "unpinAllChatMessages"
1879
}
1880

1881
func (config UnpinAllChatMessagesConfig) params() (Params, error) {
1882
	params := make(Params)
1883

1884
	params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1885

1886
	return params, nil
1887
}
1888

1889
// SetChatPhotoConfig allows you to set a group, supergroup, or channel's photo.
1890
type SetChatPhotoConfig struct {
1891
	BaseFile
1892
}
1893

1894
func (config SetChatPhotoConfig) method() string {
1895
	return "setChatPhoto"
1896
}
1897

1898
func (config SetChatPhotoConfig) files() []RequestFile {
1899
	return []RequestFile{{
1900
		Name: "photo",
1901
		Data: config.File,
1902
	}}
1903
}
1904

1905
// DeleteChatPhotoConfig allows you to delete a group, supergroup, or channel's photo.
1906
type DeleteChatPhotoConfig struct {
1907
	ChatID          int64
1908
	ChannelUsername string
1909
}
1910

1911
func (config DeleteChatPhotoConfig) method() string {
1912
	return "deleteChatPhoto"
1913
}
1914

1915
func (config DeleteChatPhotoConfig) params() (Params, error) {
1916
	params := make(Params)
1917

1918
	params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1919

1920
	return params, nil
1921
}
1922

1923
// SetChatTitleConfig allows you to set the title of something other than a private chat.
1924
type SetChatTitleConfig struct {
1925
	ChatID          int64
1926
	ChannelUsername string
1927

1928
	Title string
1929
}
1930

1931
func (config SetChatTitleConfig) method() string {
1932
	return "setChatTitle"
1933
}
1934

1935
func (config SetChatTitleConfig) params() (Params, error) {
1936
	params := make(Params)
1937

1938
	params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1939
	params["title"] = config.Title
1940

1941
	return params, nil
1942
}
1943

1944
// SetChatDescriptionConfig allows you to set the description of a supergroup or channel.
1945
type SetChatDescriptionConfig struct {
1946
	ChatID          int64
1947
	ChannelUsername string
1948

1949
	Description string
1950
}
1951

1952
func (config SetChatDescriptionConfig) method() string {
1953
	return "setChatDescription"
1954
}
1955

1956
func (config SetChatDescriptionConfig) params() (Params, error) {
1957
	params := make(Params)
1958

1959
	params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
1960
	params["description"] = config.Description
1961

1962
	return params, nil
1963
}
1964

1965
// GetStickerSetConfig allows you to get the stickers in a set.
1966
type GetStickerSetConfig struct {
1967
	Name string
1968
}
1969

1970
func (config GetStickerSetConfig) method() string {
1971
	return "getStickerSet"
1972
}
1973

1974
func (config GetStickerSetConfig) params() (Params, error) {
1975
	params := make(Params)
1976

1977
	params["name"] = config.Name
1978

1979
	return params, nil
1980
}
1981

1982
// UploadStickerConfig allows you to upload a sticker for use in a set later.
1983
type UploadStickerConfig struct {
1984
	UserID     int64
1985
	PNGSticker RequestFileData
1986
}
1987

1988
func (config UploadStickerConfig) method() string {
1989
	return "uploadStickerFile"
1990
}
1991

1992
func (config UploadStickerConfig) params() (Params, error) {
1993
	params := make(Params)
1994

1995
	params.AddNonZero64("user_id", config.UserID)
1996

1997
	return params, nil
1998
}
1999

2000
func (config UploadStickerConfig) files() []RequestFile {
2001
	return []RequestFile{{
2002
		Name: "png_sticker",
2003
		Data: config.PNGSticker,
2004
	}}
2005
}
2006

2007
// NewStickerSetConfig allows creating a new sticker set.
2008
//
2009
// You must set either PNGSticker or TGSSticker.
2010
type NewStickerSetConfig struct {
2011
	UserID        int64
2012
	Name          string
2013
	Title         string
2014
	PNGSticker    RequestFileData
2015
	TGSSticker    RequestFileData
2016
	Emojis        string
2017
	ContainsMasks bool
2018
	MaskPosition  *MaskPosition
2019
}
2020

2021
func (config NewStickerSetConfig) method() string {
2022
	return "createNewStickerSet"
2023
}
2024

2025
func (config NewStickerSetConfig) params() (Params, error) {
2026
	params := make(Params)
2027

2028
	params.AddNonZero64("user_id", config.UserID)
2029
	params["name"] = config.Name
2030
	params["title"] = config.Title
2031

2032
	params["emojis"] = config.Emojis
2033

2034
	params.AddBool("contains_masks", config.ContainsMasks)
2035

2036
	err := params.AddInterface("mask_position", config.MaskPosition)
2037

2038
	return params, err
2039
}
2040

2041
func (config NewStickerSetConfig) files() []RequestFile {
2042
	if config.PNGSticker != nil {
2043
		return []RequestFile{{
2044
			Name: "png_sticker",
2045
			Data: config.PNGSticker,
2046
		}}
2047
	}
2048

2049
	return []RequestFile{{
2050
		Name: "tgs_sticker",
2051
		Data: config.TGSSticker,
2052
	}}
2053
}
2054

2055
// AddStickerConfig allows you to add a sticker to a set.
2056
type AddStickerConfig struct {
2057
	UserID       int64
2058
	Name         string
2059
	PNGSticker   RequestFileData
2060
	TGSSticker   RequestFileData
2061
	Emojis       string
2062
	MaskPosition *MaskPosition
2063
}
2064

2065
func (config AddStickerConfig) method() string {
2066
	return "addStickerToSet"
2067
}
2068

2069
func (config AddStickerConfig) params() (Params, error) {
2070
	params := make(Params)
2071

2072
	params.AddNonZero64("user_id", config.UserID)
2073
	params["name"] = config.Name
2074
	params["emojis"] = config.Emojis
2075

2076
	err := params.AddInterface("mask_position", config.MaskPosition)
2077

2078
	return params, err
2079
}
2080

2081
func (config AddStickerConfig) files() []RequestFile {
2082
	if config.PNGSticker != nil {
2083
		return []RequestFile{{
2084
			Name: "png_sticker",
2085
			Data: config.PNGSticker,
2086
		}}
2087
	}
2088

2089
	return []RequestFile{{
2090
		Name: "tgs_sticker",
2091
		Data: config.TGSSticker,
2092
	}}
2093

2094
}
2095

2096
// SetStickerPositionConfig allows you to change the position of a sticker in a set.
2097
type SetStickerPositionConfig struct {
2098
	Sticker  string
2099
	Position int
2100
}
2101

2102
func (config SetStickerPositionConfig) method() string {
2103
	return "setStickerPositionInSet"
2104
}
2105

2106
func (config SetStickerPositionConfig) params() (Params, error) {
2107
	params := make(Params)
2108

2109
	params["sticker"] = config.Sticker
2110
	params.AddNonZero("position", config.Position)
2111

2112
	return params, nil
2113
}
2114

2115
// DeleteStickerConfig allows you to delete a sticker from a set.
2116
type DeleteStickerConfig struct {
2117
	Sticker string
2118
}
2119

2120
func (config DeleteStickerConfig) method() string {
2121
	return "deleteStickerFromSet"
2122
}
2123

2124
func (config DeleteStickerConfig) params() (Params, error) {
2125
	params := make(Params)
2126

2127
	params["sticker"] = config.Sticker
2128

2129
	return params, nil
2130
}
2131

2132
// SetStickerSetThumbConfig allows you to set the thumbnail for a sticker set.
2133
type SetStickerSetThumbConfig struct {
2134
	Name   string
2135
	UserID int64
2136
	Thumb  RequestFileData
2137
}
2138

2139
func (config SetStickerSetThumbConfig) method() string {
2140
	return "setStickerSetThumb"
2141
}
2142

2143
func (config SetStickerSetThumbConfig) params() (Params, error) {
2144
	params := make(Params)
2145

2146
	params["name"] = config.Name
2147
	params.AddNonZero64("user_id", config.UserID)
2148

2149
	return params, nil
2150
}
2151

2152
func (config SetStickerSetThumbConfig) files() []RequestFile {
2153
	return []RequestFile{{
2154
		Name: "thumb",
2155
		Data: config.Thumb,
2156
	}}
2157
}
2158

2159
// SetChatStickerSetConfig allows you to set the sticker set for a supergroup.
2160
type SetChatStickerSetConfig struct {
2161
	ChatID             int64
2162
	SuperGroupUsername string
2163

2164
	StickerSetName string
2165
}
2166

2167
func (config SetChatStickerSetConfig) method() string {
2168
	return "setChatStickerSet"
2169
}
2170

2171
func (config SetChatStickerSetConfig) params() (Params, error) {
2172
	params := make(Params)
2173

2174
	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
2175
	params["sticker_set_name"] = config.StickerSetName
2176

2177
	return params, nil
2178
}
2179

2180
// DeleteChatStickerSetConfig allows you to remove a supergroup's sticker set.
2181
type DeleteChatStickerSetConfig struct {
2182
	ChatID             int64
2183
	SuperGroupUsername string
2184
}
2185

2186
func (config DeleteChatStickerSetConfig) method() string {
2187
	return "deleteChatStickerSet"
2188
}
2189

2190
func (config DeleteChatStickerSetConfig) params() (Params, error) {
2191
	params := make(Params)
2192

2193
	params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
2194

2195
	return params, nil
2196
}
2197

2198
// MediaGroupConfig allows you to send a group of media.
2199
//
2200
// Media consist of InputMedia items (InputMediaPhoto, InputMediaVideo).
2201
type MediaGroupConfig struct {
2202
	ChatID          int64
2203
	ChannelUsername string
2204

2205
	Media               []interface{}
2206
	DisableNotification bool
2207
	ReplyToMessageID    int
2208
}
2209

2210
func (config MediaGroupConfig) method() string {
2211
	return "sendMediaGroup"
2212
}
2213

2214
func (config MediaGroupConfig) params() (Params, error) {
2215
	params := make(Params)
2216

2217
	params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
2218
	params.AddBool("disable_notification", config.DisableNotification)
2219
	params.AddNonZero("reply_to_message_id", config.ReplyToMessageID)
2220

2221
	err := params.AddInterface("media", prepareInputMediaForParams(config.Media))
2222

2223
	return params, err
2224
}
2225

2226
func (config MediaGroupConfig) files() []RequestFile {
2227
	return prepareInputMediaForFiles(config.Media)
2228
}
2229

2230
// DiceConfig contains information about a sendDice request.
2231
type DiceConfig struct {
2232
	BaseChat
2233
	// Emoji on which the dice throw animation is based.
2234
	// Currently, must be one of 🎲, 🎯, 🏀, ⚽, 🎳, or 🎰.
2235
	// Dice can have values 1-6 for 🎲, 🎯, and 🎳, values 1-5 for 🏀 and ⚽,
2236
	// and values 1-64 for 🎰.
2237
	// Defaults to “🎲”
2238
	Emoji string
2239
}
2240

2241
func (config DiceConfig) method() string {
2242
	return "sendDice"
2243
}
2244

2245
func (config DiceConfig) params() (Params, error) {
2246
	params, err := config.BaseChat.params()
2247
	if err != nil {
2248
		return params, err
2249
	}
2250

2251
	params.AddNonEmpty("emoji", config.Emoji)
2252

2253
	return params, err
2254
}
2255

2256
// GetMyCommandsConfig gets a list of the currently registered commands.
2257
type GetMyCommandsConfig struct {
2258
	Scope        *BotCommandScope
2259
	LanguageCode string
2260
}
2261

2262
func (config GetMyCommandsConfig) method() string {
2263
	return "getMyCommands"
2264
}
2265

2266
func (config GetMyCommandsConfig) params() (Params, error) {
2267
	params := make(Params)
2268

2269
	err := params.AddInterface("scope", config.Scope)
2270
	params.AddNonEmpty("language_code", config.LanguageCode)
2271

2272
	return params, err
2273
}
2274

2275
// SetMyCommandsConfig sets a list of commands the bot understands.
2276
type SetMyCommandsConfig struct {
2277
	Commands     []BotCommand
2278
	Scope        *BotCommandScope
2279
	LanguageCode string
2280
}
2281

2282
func (config SetMyCommandsConfig) method() string {
2283
	return "setMyCommands"
2284
}
2285

2286
func (config SetMyCommandsConfig) params() (Params, error) {
2287
	params := make(Params)
2288

2289
	if err := params.AddInterface("commands", config.Commands); err != nil {
2290
		return params, err
2291
	}
2292
	err := params.AddInterface("scope", config.Scope)
2293
	params.AddNonEmpty("language_code", config.LanguageCode)
2294

2295
	return params, err
2296
}
2297

2298
type DeleteMyCommandsConfig struct {
2299
	Scope        *BotCommandScope
2300
	LanguageCode string
2301
}
2302

2303
func (config DeleteMyCommandsConfig) method() string {
2304
	return "deleteMyCommands"
2305
}
2306

2307
func (config DeleteMyCommandsConfig) params() (Params, error) {
2308
	params := make(Params)
2309

2310
	err := params.AddInterface("scope", config.Scope)
2311
	params.AddNonEmpty("language_code", config.LanguageCode)
2312

2313
	return params, err
2314
}
2315

2316
// prepareInputMediaParam evaluates a single InputMedia and determines if it
2317
// needs to be modified for a successful upload. If it returns nil, then the
2318
// value does not need to be included in the params. Otherwise, it will return
2319
// the same type as was originally provided.
2320
//
2321
// The idx is used to calculate the file field name. If you only have a single
2322
// file, 0 may be used. It is formatted into "attach://file-%d" for the primary
2323
// media and "attach://file-%d-thumb" for thumbnails.
2324
//
2325
// It is expected to be used in conjunction with prepareInputMediaFile.
2326
func prepareInputMediaParam(inputMedia interface{}, idx int) interface{} {
2327
	switch m := inputMedia.(type) {
2328
	case InputMediaPhoto:
2329
		if m.Media.NeedsUpload() {
2330
			m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
2331
		}
2332

2333
		return m
2334
	case InputMediaVideo:
2335
		if m.Media.NeedsUpload() {
2336
			m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
2337
		}
2338

2339
		if m.Thumb != nil && m.Thumb.NeedsUpload() {
2340
			m.Thumb = fileAttach(fmt.Sprintf("attach://file-%d-thumb", idx))
2341
		}
2342

2343
		return m
2344
	case InputMediaAudio:
2345
		if m.Media.NeedsUpload() {
2346
			m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
2347
		}
2348

2349
		if m.Thumb != nil && m.Thumb.NeedsUpload() {
2350
			m.Thumb = fileAttach(fmt.Sprintf("attach://file-%d-thumb", idx))
2351
		}
2352

2353
		return m
2354
	case InputMediaDocument:
2355
		if m.Media.NeedsUpload() {
2356
			m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
2357
		}
2358

2359
		if m.Thumb != nil && m.Thumb.NeedsUpload() {
2360
			m.Thumb = fileAttach(fmt.Sprintf("attach://file-%d-thumb", idx))
2361
		}
2362

2363
		return m
2364
	}
2365

2366
	return nil
2367
}
2368

2369
// prepareInputMediaFile generates an array of RequestFile to provide for
2370
// Fileable's files method. It returns an array as a single InputMedia may have
2371
// multiple files, for the primary media and a thumbnail.
2372
//
2373
// The idx parameter is used to generate file field names. It uses the names
2374
// "file-%d" for the main file and "file-%d-thumb" for the thumbnail.
2375
//
2376
// It is expected to be used in conjunction with prepareInputMediaParam.
2377
func prepareInputMediaFile(inputMedia interface{}, idx int) []RequestFile {
2378
	files := []RequestFile{}
2379

2380
	switch m := inputMedia.(type) {
2381
	case InputMediaPhoto:
2382
		if m.Media.NeedsUpload() {
2383
			files = append(files, RequestFile{
2384
				Name: fmt.Sprintf("file-%d", idx),
2385
				Data: m.Media,
2386
			})
2387
		}
2388
	case InputMediaVideo:
2389
		if m.Media.NeedsUpload() {
2390
			files = append(files, RequestFile{
2391
				Name: fmt.Sprintf("file-%d", idx),
2392
				Data: m.Media,
2393
			})
2394
		}
2395

2396
		if m.Thumb != nil && m.Thumb.NeedsUpload() {
2397
			files = append(files, RequestFile{
2398
				Name: fmt.Sprintf("file-%d", idx),
2399
				Data: m.Thumb,
2400
			})
2401
		}
2402
	case InputMediaDocument:
2403
		if m.Media.NeedsUpload() {
2404
			files = append(files, RequestFile{
2405
				Name: fmt.Sprintf("file-%d", idx),
2406
				Data: m.Media,
2407
			})
2408
		}
2409

2410
		if m.Thumb != nil && m.Thumb.NeedsUpload() {
2411
			files = append(files, RequestFile{
2412
				Name: fmt.Sprintf("file-%d", idx),
2413
				Data: m.Thumb,
2414
			})
2415
		}
2416
	case InputMediaAudio:
2417
		if m.Media.NeedsUpload() {
2418
			files = append(files, RequestFile{
2419
				Name: fmt.Sprintf("file-%d", idx),
2420
				Data: m.Media,
2421
			})
2422
		}
2423

2424
		if m.Thumb != nil && m.Thumb.NeedsUpload() {
2425
			files = append(files, RequestFile{
2426
				Name: fmt.Sprintf("file-%d", idx),
2427
				Data: m.Thumb,
2428
			})
2429
		}
2430
	}
2431

2432
	return files
2433
}
2434

2435
// prepareInputMediaForParams calls prepareInputMediaParam for each item
2436
// provided and returns a new array with the correct params for a request.
2437
//
2438
// It is expected that files will get data from the associated function,
2439
// prepareInputMediaForFiles.
2440
func prepareInputMediaForParams(inputMedia []interface{}) []interface{} {
2441
	newMedia := make([]interface{}, len(inputMedia))
2442
	copy(newMedia, inputMedia)
2443

2444
	for idx, media := range inputMedia {
2445
		if param := prepareInputMediaParam(media, idx); param != nil {
2446
			newMedia[idx] = param
2447
		}
2448
	}
2449

2450
	return newMedia
2451
}
2452

2453
// prepareInputMediaForFiles calls prepareInputMediaFile for each item
2454
// provided and returns a new array with the correct files for a request.
2455
//
2456
// It is expected that params will get data from the associated function,
2457
// prepareInputMediaForParams.
2458
func prepareInputMediaForFiles(inputMedia []interface{}) []RequestFile {
2459
	files := []RequestFile{}
2460

2461
	for idx, media := range inputMedia {
2462
		if file := prepareInputMediaFile(media, idx); file != nil {
2463
			files = append(files, file...)
2464
		}
2465
	}
2466

2467
	return files
2468
}
2469

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.