commit
7c82078b7a
65
bot.go
65
bot.go
|
@ -3,7 +3,6 @@
|
||||||
package tgbotapi
|
package tgbotapi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -12,7 +11,6 @@ import (
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -185,54 +183,37 @@ func (bot *BotAPI) UploadFiles(endpoint string, params Params, files []RequestFi
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
switch f := file.File.(type) {
|
if file.Data.NeedsUpload() {
|
||||||
case string:
|
name, reader, err := file.Data.UploadData()
|
||||||
fileHandle, err := os.Open(f)
|
|
||||||
if err != nil {
|
|
||||||
w.CloseWithError(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer fileHandle.Close()
|
|
||||||
|
|
||||||
part, err := m.CreateFormFile(file.Name, fileHandle.Name())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.CloseWithError(err)
|
w.CloseWithError(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
io.Copy(part, fileHandle)
|
part, err := m.CreateFormFile(file.Name, name)
|
||||||
case FileBytes:
|
|
||||||
part, err := m.CreateFormFile(file.Name, f.Name)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.CloseWithError(err)
|
w.CloseWithError(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := bytes.NewBuffer(f.Bytes)
|
if _, err := io.Copy(part, reader); err != nil {
|
||||||
io.Copy(part, buf)
|
|
||||||
case FileReader:
|
|
||||||
part, err := m.CreateFormFile(file.Name, f.Name)
|
|
||||||
if err != nil {
|
|
||||||
w.CloseWithError(err)
|
w.CloseWithError(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
io.Copy(part, f.Reader)
|
if closer, ok := reader.(io.ReadCloser); ok {
|
||||||
case FileURL:
|
if err = closer.Close(); err != nil {
|
||||||
val := string(f)
|
w.CloseWithError(err)
|
||||||
if err := m.WriteField(file.Name, val); err != nil {
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
value := file.Data.SendData()
|
||||||
|
|
||||||
|
if err := m.WriteField(file.Name, value); err != nil {
|
||||||
w.CloseWithError(err)
|
w.CloseWithError(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
case FileID:
|
|
||||||
val := string(f)
|
|
||||||
if err := m.WriteField(file.Name, val); err != nil {
|
|
||||||
w.CloseWithError(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
w.CloseWithError(errors.New(ErrBadFileType))
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@ -321,8 +302,7 @@ func (bot *BotAPI) IsMessageToMe(message Message) bool {
|
||||||
|
|
||||||
func hasFilesNeedingUpload(files []RequestFile) bool {
|
func hasFilesNeedingUpload(files []RequestFile) bool {
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
switch file.File.(type) {
|
if file.Data.NeedsUpload() {
|
||||||
case string, FileBytes, FileReader:
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -349,20 +329,7 @@ func (bot *BotAPI) Request(c Chattable) (*APIResponse, error) {
|
||||||
// However, if there are no files to be uploaded, there's likely things
|
// However, if there are no files to be uploaded, there's likely things
|
||||||
// that need to be turned into params instead.
|
// that need to be turned into params instead.
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
var s string
|
params[file.Name] = file.Data.SendData()
|
||||||
|
|
||||||
switch f := file.File.(type) {
|
|
||||||
case string:
|
|
||||||
s = f
|
|
||||||
case FileID:
|
|
||||||
s = string(f)
|
|
||||||
case FileURL:
|
|
||||||
s = string(f)
|
|
||||||
default:
|
|
||||||
return nil, errors.New(ErrBadFileType)
|
|
||||||
}
|
|
||||||
|
|
||||||
params[file.Name] = s
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
48
bot_test.go
48
bot_test.go
|
@ -127,7 +127,7 @@ func TestCopyMessage(t *testing.T) {
|
||||||
func TestSendWithNewPhoto(t *testing.T) {
|
func TestSendWithNewPhoto(t *testing.T) {
|
||||||
bot, _ := getBot(t)
|
bot, _ := getBot(t)
|
||||||
|
|
||||||
msg := NewPhoto(ChatID, "tests/image.jpg")
|
msg := NewPhoto(ChatID, FilePath("tests/image.jpg"))
|
||||||
msg.Caption = "Test"
|
msg.Caption = "Test"
|
||||||
_, err := bot.Send(msg)
|
_, err := bot.Send(msg)
|
||||||
|
|
||||||
|
@ -169,7 +169,7 @@ func TestSendWithNewPhotoWithFileReader(t *testing.T) {
|
||||||
func TestSendWithNewPhotoReply(t *testing.T) {
|
func TestSendWithNewPhotoReply(t *testing.T) {
|
||||||
bot, _ := getBot(t)
|
bot, _ := getBot(t)
|
||||||
|
|
||||||
msg := NewPhoto(ChatID, "tests/image.jpg")
|
msg := NewPhoto(ChatID, FilePath("tests/image.jpg"))
|
||||||
msg.ReplyToMessageID = ReplyToMessageID
|
msg.ReplyToMessageID = ReplyToMessageID
|
||||||
|
|
||||||
_, err := bot.Send(msg)
|
_, err := bot.Send(msg)
|
||||||
|
@ -182,7 +182,7 @@ func TestSendWithNewPhotoReply(t *testing.T) {
|
||||||
func TestSendNewPhotoToChannel(t *testing.T) {
|
func TestSendNewPhotoToChannel(t *testing.T) {
|
||||||
bot, _ := getBot(t)
|
bot, _ := getBot(t)
|
||||||
|
|
||||||
msg := NewPhotoToChannel(Channel, "tests/image.jpg")
|
msg := NewPhotoToChannel(Channel, FilePath("tests/image.jpg"))
|
||||||
msg.Caption = "Test"
|
msg.Caption = "Test"
|
||||||
_, err := bot.Send(msg)
|
_, err := bot.Send(msg)
|
||||||
|
|
||||||
|
@ -239,7 +239,7 @@ func TestSendWithExistingPhoto(t *testing.T) {
|
||||||
func TestSendWithNewDocument(t *testing.T) {
|
func TestSendWithNewDocument(t *testing.T) {
|
||||||
bot, _ := getBot(t)
|
bot, _ := getBot(t)
|
||||||
|
|
||||||
msg := NewDocument(ChatID, "tests/image.jpg")
|
msg := NewDocument(ChatID, FilePath("tests/image.jpg"))
|
||||||
_, err := bot.Send(msg)
|
_, err := bot.Send(msg)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -250,8 +250,8 @@ func TestSendWithNewDocument(t *testing.T) {
|
||||||
func TestSendWithNewDocumentAndThumb(t *testing.T) {
|
func TestSendWithNewDocumentAndThumb(t *testing.T) {
|
||||||
bot, _ := getBot(t)
|
bot, _ := getBot(t)
|
||||||
|
|
||||||
msg := NewDocument(ChatID, "tests/voice.ogg")
|
msg := NewDocument(ChatID, FilePath("tests/voice.ogg"))
|
||||||
msg.Thumb = "tests/image.jpg"
|
msg.Thumb = FilePath("tests/image.jpg")
|
||||||
_, err := bot.Send(msg)
|
_, err := bot.Send(msg)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -273,7 +273,7 @@ func TestSendWithExistingDocument(t *testing.T) {
|
||||||
func TestSendWithNewAudio(t *testing.T) {
|
func TestSendWithNewAudio(t *testing.T) {
|
||||||
bot, _ := getBot(t)
|
bot, _ := getBot(t)
|
||||||
|
|
||||||
msg := NewAudio(ChatID, "tests/audio.mp3")
|
msg := NewAudio(ChatID, FilePath("tests/audio.mp3"))
|
||||||
msg.Title = "TEST"
|
msg.Title = "TEST"
|
||||||
msg.Duration = 10
|
msg.Duration = 10
|
||||||
msg.Performer = "TEST"
|
msg.Performer = "TEST"
|
||||||
|
@ -302,7 +302,7 @@ func TestSendWithExistingAudio(t *testing.T) {
|
||||||
func TestSendWithNewVoice(t *testing.T) {
|
func TestSendWithNewVoice(t *testing.T) {
|
||||||
bot, _ := getBot(t)
|
bot, _ := getBot(t)
|
||||||
|
|
||||||
msg := NewVoice(ChatID, "tests/voice.ogg")
|
msg := NewVoice(ChatID, FilePath("tests/voice.ogg"))
|
||||||
msg.Duration = 10
|
msg.Duration = 10
|
||||||
_, err := bot.Send(msg)
|
_, err := bot.Send(msg)
|
||||||
|
|
||||||
|
@ -356,7 +356,7 @@ func TestSendWithVenue(t *testing.T) {
|
||||||
func TestSendWithNewVideo(t *testing.T) {
|
func TestSendWithNewVideo(t *testing.T) {
|
||||||
bot, _ := getBot(t)
|
bot, _ := getBot(t)
|
||||||
|
|
||||||
msg := NewVideo(ChatID, "tests/video.mp4")
|
msg := NewVideo(ChatID, FilePath("tests/video.mp4"))
|
||||||
msg.Duration = 10
|
msg.Duration = 10
|
||||||
msg.Caption = "TEST"
|
msg.Caption = "TEST"
|
||||||
|
|
||||||
|
@ -384,7 +384,7 @@ func TestSendWithExistingVideo(t *testing.T) {
|
||||||
func TestSendWithNewVideoNote(t *testing.T) {
|
func TestSendWithNewVideoNote(t *testing.T) {
|
||||||
bot, _ := getBot(t)
|
bot, _ := getBot(t)
|
||||||
|
|
||||||
msg := NewVideoNote(ChatID, 240, "tests/videonote.mp4")
|
msg := NewVideoNote(ChatID, 240, FilePath("tests/videonote.mp4"))
|
||||||
msg.Duration = 10
|
msg.Duration = 10
|
||||||
|
|
||||||
_, err := bot.Send(msg)
|
_, err := bot.Send(msg)
|
||||||
|
@ -410,7 +410,7 @@ func TestSendWithExistingVideoNote(t *testing.T) {
|
||||||
func TestSendWithNewSticker(t *testing.T) {
|
func TestSendWithNewSticker(t *testing.T) {
|
||||||
bot, _ := getBot(t)
|
bot, _ := getBot(t)
|
||||||
|
|
||||||
msg := NewSticker(ChatID, "tests/image.jpg")
|
msg := NewSticker(ChatID, FilePath("tests/image.jpg"))
|
||||||
|
|
||||||
_, err := bot.Send(msg)
|
_, err := bot.Send(msg)
|
||||||
|
|
||||||
|
@ -434,7 +434,7 @@ func TestSendWithExistingSticker(t *testing.T) {
|
||||||
func TestSendWithNewStickerAndKeyboardHide(t *testing.T) {
|
func TestSendWithNewStickerAndKeyboardHide(t *testing.T) {
|
||||||
bot, _ := getBot(t)
|
bot, _ := getBot(t)
|
||||||
|
|
||||||
msg := NewSticker(ChatID, "tests/image.jpg")
|
msg := NewSticker(ChatID, FilePath("tests/image.jpg"))
|
||||||
msg.ReplyMarkup = ReplyKeyboardRemove{
|
msg.ReplyMarkup = ReplyKeyboardRemove{
|
||||||
RemoveKeyboard: true,
|
RemoveKeyboard: true,
|
||||||
Selective: false,
|
Selective: false,
|
||||||
|
@ -550,7 +550,7 @@ func TestSetWebhookWithCert(t *testing.T) {
|
||||||
|
|
||||||
bot.Request(DeleteWebhookConfig{})
|
bot.Request(DeleteWebhookConfig{})
|
||||||
|
|
||||||
wh, err := NewWebhookWithCert("https://example.com/tgbotapi-test/"+bot.Token, "tests/cert.pem")
|
wh, err := NewWebhookWithCert("https://example.com/tgbotapi-test/"+bot.Token, FilePath("tests/cert.pem"))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
|
@ -609,8 +609,8 @@ func TestSendWithMediaGroupPhotoVideo(t *testing.T) {
|
||||||
|
|
||||||
cfg := NewMediaGroup(ChatID, []interface{}{
|
cfg := NewMediaGroup(ChatID, []interface{}{
|
||||||
NewInputMediaPhoto(FileURL("https://github.com/go-telegram-bot-api/telegram-bot-api/raw/0a3a1c8716c4cd8d26a262af9f12dcbab7f3f28c/tests/image.jpg")),
|
NewInputMediaPhoto(FileURL("https://github.com/go-telegram-bot-api/telegram-bot-api/raw/0a3a1c8716c4cd8d26a262af9f12dcbab7f3f28c/tests/image.jpg")),
|
||||||
NewInputMediaPhoto("tests/image.jpg"),
|
NewInputMediaPhoto(FilePath("tests/image.jpg")),
|
||||||
NewInputMediaVideo("tests/video.mp4"),
|
NewInputMediaVideo(FilePath("tests/video.mp4")),
|
||||||
})
|
})
|
||||||
|
|
||||||
messages, err := bot.SendMediaGroup(cfg)
|
messages, err := bot.SendMediaGroup(cfg)
|
||||||
|
@ -632,7 +632,7 @@ func TestSendWithMediaGroupDocument(t *testing.T) {
|
||||||
|
|
||||||
cfg := NewMediaGroup(ChatID, []interface{}{
|
cfg := NewMediaGroup(ChatID, []interface{}{
|
||||||
NewInputMediaDocument(FileURL("https://i.imgur.com/unQLJIb.jpg")),
|
NewInputMediaDocument(FileURL("https://i.imgur.com/unQLJIb.jpg")),
|
||||||
NewInputMediaDocument("tests/image.jpg"),
|
NewInputMediaDocument(FilePath("tests/image.jpg")),
|
||||||
})
|
})
|
||||||
|
|
||||||
messages, err := bot.SendMediaGroup(cfg)
|
messages, err := bot.SendMediaGroup(cfg)
|
||||||
|
@ -653,8 +653,8 @@ func TestSendWithMediaGroupAudio(t *testing.T) {
|
||||||
bot, _ := getBot(t)
|
bot, _ := getBot(t)
|
||||||
|
|
||||||
cfg := NewMediaGroup(ChatID, []interface{}{
|
cfg := NewMediaGroup(ChatID, []interface{}{
|
||||||
NewInputMediaAudio("tests/audio.mp3"),
|
NewInputMediaAudio(FilePath("tests/audio.mp3")),
|
||||||
NewInputMediaAudio("tests/audio.mp3"),
|
NewInputMediaAudio(FilePath("tests/audio.mp3")),
|
||||||
})
|
})
|
||||||
|
|
||||||
messages, err := bot.SendMediaGroup(cfg)
|
messages, err := bot.SendMediaGroup(cfg)
|
||||||
|
@ -715,7 +715,7 @@ func ExampleNewWebhook() {
|
||||||
|
|
||||||
log.Printf("Authorized on account %s", bot.Self.UserName)
|
log.Printf("Authorized on account %s", bot.Self.UserName)
|
||||||
|
|
||||||
wh, err := NewWebhookWithCert("https://www.google.com:8443/"+bot.Token, "cert.pem")
|
wh, err := NewWebhookWithCert("https://www.google.com:8443/"+bot.Token, FilePath("cert.pem"))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -755,7 +755,7 @@ func ExampleWebhookHandler() {
|
||||||
|
|
||||||
log.Printf("Authorized on account %s", bot.Self.UserName)
|
log.Printf("Authorized on account %s", bot.Self.UserName)
|
||||||
|
|
||||||
wh, err := NewWebhookWithCert("https://www.google.com:8443/"+bot.Token, "cert.pem")
|
wh, err := NewWebhookWithCert("https://www.google.com:8443/"+bot.Token, FilePath("cert.pem"))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -1019,7 +1019,7 @@ func TestCommands(t *testing.T) {
|
||||||
// ChatID: ChatID,
|
// ChatID: ChatID,
|
||||||
// MessageID: m.MessageID,
|
// MessageID: m.MessageID,
|
||||||
// },
|
// },
|
||||||
// Media: NewInputMediaVideo("tests/video.mp4"),
|
// Media: NewInputMediaVideo(FilePath("tests/video.mp4")),
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// _, err = bot.Request(edit)
|
// _, err = bot.Request(edit)
|
||||||
|
@ -1030,17 +1030,17 @@ func TestCommands(t *testing.T) {
|
||||||
|
|
||||||
func TestPrepareInputMediaForParams(t *testing.T) {
|
func TestPrepareInputMediaForParams(t *testing.T) {
|
||||||
media := []interface{}{
|
media := []interface{}{
|
||||||
NewInputMediaPhoto("tests/image.jpg"),
|
NewInputMediaPhoto(FilePath("tests/image.jpg")),
|
||||||
NewInputMediaVideo(FileID("test")),
|
NewInputMediaVideo(FileID("test")),
|
||||||
}
|
}
|
||||||
|
|
||||||
prepared := prepareInputMediaForParams(media)
|
prepared := prepareInputMediaForParams(media)
|
||||||
|
|
||||||
if media[0].(InputMediaPhoto).Media != "tests/image.jpg" {
|
if media[0].(InputMediaPhoto).Media != FilePath("tests/image.jpg") {
|
||||||
t.Error("Original media was changed")
|
t.Error("Original media was changed")
|
||||||
}
|
}
|
||||||
|
|
||||||
if prepared[0].(InputMediaPhoto).Media != "attach://file-0" {
|
if prepared[0].(InputMediaPhoto).Media != fileAttach("attach://file-0") {
|
||||||
t.Error("New media was not replaced")
|
t.Error("New media was not replaced")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
306
configs.go
306
configs.go
|
@ -1,9 +1,11 @@
|
||||||
package tgbotapi
|
package tgbotapi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -98,9 +100,7 @@ const (
|
||||||
|
|
||||||
// Library errors
|
// Library errors
|
||||||
const (
|
const (
|
||||||
// ErrBadFileType happens when you pass an unknown type
|
ErrBadURL = "bad or empty url"
|
||||||
ErrBadFileType = "bad file type"
|
|
||||||
ErrBadURL = "bad or empty url"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Chattable is any config type that can be sent.
|
// Chattable is any config type that can be sent.
|
||||||
|
@ -109,21 +109,136 @@ type Chattable interface {
|
||||||
method() string
|
method() string
|
||||||
}
|
}
|
||||||
|
|
||||||
// RequestFile represents a file associated with a request. May involve
|
|
||||||
// uploading a file, or passing an existing ID.
|
|
||||||
type RequestFile struct {
|
|
||||||
// The multipart upload field name.
|
|
||||||
Name string
|
|
||||||
// The file to upload.
|
|
||||||
File interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fileable is any config type that can be sent that includes a file.
|
// Fileable is any config type that can be sent that includes a file.
|
||||||
type Fileable interface {
|
type Fileable interface {
|
||||||
Chattable
|
Chattable
|
||||||
files() []RequestFile
|
files() []RequestFile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RequestFile represents a file associated with a field name.
|
||||||
|
type RequestFile struct {
|
||||||
|
// The file field name.
|
||||||
|
Name string
|
||||||
|
// The file data to include.
|
||||||
|
Data RequestFileData
|
||||||
|
}
|
||||||
|
|
||||||
|
// RequestFileData represents the data to be used for a file.
|
||||||
|
type RequestFileData interface {
|
||||||
|
// If the file needs to be uploaded.
|
||||||
|
NeedsUpload() bool
|
||||||
|
|
||||||
|
// Get the file name and an `io.Reader` for the file to be uploaded. This
|
||||||
|
// must only be called when the file needs to be uploaded.
|
||||||
|
UploadData() (string, io.Reader, error)
|
||||||
|
// Get the file data to send when a file does not need to be uploaded. This
|
||||||
|
// must only be called when the file does not need to be uploaded.
|
||||||
|
SendData() string
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileBytes contains information about a set of bytes to upload
|
||||||
|
// as a File.
|
||||||
|
type FileBytes struct {
|
||||||
|
Name string
|
||||||
|
Bytes []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fb FileBytes) NeedsUpload() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fb FileBytes) UploadData() (string, io.Reader, error) {
|
||||||
|
return fb.Name, bytes.NewReader(fb.Bytes), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fb FileBytes) SendData() string {
|
||||||
|
panic("FileBytes must be uploaded")
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileReader contains information about a reader to upload as a File.
|
||||||
|
type FileReader struct {
|
||||||
|
Name string
|
||||||
|
Reader io.Reader
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fr FileReader) NeedsUpload() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fr FileReader) UploadData() (string, io.Reader, error) {
|
||||||
|
return fr.Name, fr.Reader, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fr FileReader) SendData() string {
|
||||||
|
panic("FileReader must be uploaded")
|
||||||
|
}
|
||||||
|
|
||||||
|
// FilePath is a path to a local file.
|
||||||
|
type FilePath string
|
||||||
|
|
||||||
|
func (fp FilePath) NeedsUpload() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fp FilePath) UploadData() (string, io.Reader, error) {
|
||||||
|
fileHandle, err := os.Open(string(fp))
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
name := fileHandle.Name()
|
||||||
|
return name, fileHandle, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fp FilePath) SendData() string {
|
||||||
|
panic("FilePath must be uploaded")
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileURL is a URL to use as a file for a request.
|
||||||
|
type FileURL string
|
||||||
|
|
||||||
|
func (fu FileURL) NeedsUpload() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fu FileURL) UploadData() (string, io.Reader, error) {
|
||||||
|
panic("FileURL cannot be uploaded")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fu FileURL) SendData() string {
|
||||||
|
return string(fu)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileID is an ID of a file already uploaded to Telegram.
|
||||||
|
type FileID string
|
||||||
|
|
||||||
|
func (fi FileID) NeedsUpload() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fi FileID) UploadData() (string, io.Reader, error) {
|
||||||
|
panic("FileID cannot be uploaded")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fi FileID) SendData() string {
|
||||||
|
return string(fi)
|
||||||
|
}
|
||||||
|
|
||||||
|
// fileAttach is a internal file type used for processed media groups.
|
||||||
|
type fileAttach string
|
||||||
|
|
||||||
|
func (fa fileAttach) NeedsUpload() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fa fileAttach) UploadData() (string, io.Reader, error) {
|
||||||
|
panic("fileAttach cannot be uploaded")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fa fileAttach) SendData() string {
|
||||||
|
return string(fa)
|
||||||
|
}
|
||||||
|
|
||||||
// LogOutConfig is a request to log out of the cloud Bot API server.
|
// LogOutConfig is a request to log out of the cloud Bot API server.
|
||||||
//
|
//
|
||||||
// Note that you may not log back in for at least 10 minutes.
|
// Note that you may not log back in for at least 10 minutes.
|
||||||
|
@ -177,7 +292,7 @@ func (chat *BaseChat) params() (Params, error) {
|
||||||
// BaseFile is a base type for all file config types.
|
// BaseFile is a base type for all file config types.
|
||||||
type BaseFile struct {
|
type BaseFile struct {
|
||||||
BaseChat
|
BaseChat
|
||||||
File interface{}
|
File RequestFileData
|
||||||
}
|
}
|
||||||
|
|
||||||
func (file BaseFile) params() (Params, error) {
|
func (file BaseFile) params() (Params, error) {
|
||||||
|
@ -292,7 +407,7 @@ func (config CopyMessageConfig) method() string {
|
||||||
// PhotoConfig contains information about a SendPhoto request.
|
// PhotoConfig contains information about a SendPhoto request.
|
||||||
type PhotoConfig struct {
|
type PhotoConfig struct {
|
||||||
BaseFile
|
BaseFile
|
||||||
Thumb interface{}
|
Thumb RequestFileData
|
||||||
Caption string
|
Caption string
|
||||||
ParseMode string
|
ParseMode string
|
||||||
CaptionEntities []MessageEntity
|
CaptionEntities []MessageEntity
|
||||||
|
@ -318,13 +433,13 @@ func (config PhotoConfig) method() string {
|
||||||
func (config PhotoConfig) files() []RequestFile {
|
func (config PhotoConfig) files() []RequestFile {
|
||||||
files := []RequestFile{{
|
files := []RequestFile{{
|
||||||
Name: "photo",
|
Name: "photo",
|
||||||
File: config.File,
|
Data: config.File,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
if config.Thumb != nil {
|
if config.Thumb != nil {
|
||||||
files = append(files, RequestFile{
|
files = append(files, RequestFile{
|
||||||
Name: "thumb",
|
Name: "thumb",
|
||||||
File: config.Thumb,
|
Data: config.Thumb,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,7 +449,7 @@ func (config PhotoConfig) files() []RequestFile {
|
||||||
// AudioConfig contains information about a SendAudio request.
|
// AudioConfig contains information about a SendAudio request.
|
||||||
type AudioConfig struct {
|
type AudioConfig struct {
|
||||||
BaseFile
|
BaseFile
|
||||||
Thumb interface{}
|
Thumb RequestFileData
|
||||||
Caption string
|
Caption string
|
||||||
ParseMode string
|
ParseMode string
|
||||||
CaptionEntities []MessageEntity
|
CaptionEntities []MessageEntity
|
||||||
|
@ -366,13 +481,13 @@ func (config AudioConfig) method() string {
|
||||||
func (config AudioConfig) files() []RequestFile {
|
func (config AudioConfig) files() []RequestFile {
|
||||||
files := []RequestFile{{
|
files := []RequestFile{{
|
||||||
Name: "audio",
|
Name: "audio",
|
||||||
File: config.File,
|
Data: config.File,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
if config.Thumb != nil {
|
if config.Thumb != nil {
|
||||||
files = append(files, RequestFile{
|
files = append(files, RequestFile{
|
||||||
Name: "thumb",
|
Name: "thumb",
|
||||||
File: config.Thumb,
|
Data: config.Thumb,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,7 +497,7 @@ func (config AudioConfig) files() []RequestFile {
|
||||||
// DocumentConfig contains information about a SendDocument request.
|
// DocumentConfig contains information about a SendDocument request.
|
||||||
type DocumentConfig struct {
|
type DocumentConfig struct {
|
||||||
BaseFile
|
BaseFile
|
||||||
Thumb interface{}
|
Thumb RequestFileData
|
||||||
Caption string
|
Caption string
|
||||||
ParseMode string
|
ParseMode string
|
||||||
CaptionEntities []MessageEntity
|
CaptionEntities []MessageEntity
|
||||||
|
@ -406,13 +521,13 @@ func (config DocumentConfig) method() string {
|
||||||
func (config DocumentConfig) files() []RequestFile {
|
func (config DocumentConfig) files() []RequestFile {
|
||||||
files := []RequestFile{{
|
files := []RequestFile{{
|
||||||
Name: "document",
|
Name: "document",
|
||||||
File: config.File,
|
Data: config.File,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
if config.Thumb != nil {
|
if config.Thumb != nil {
|
||||||
files = append(files, RequestFile{
|
files = append(files, RequestFile{
|
||||||
Name: "thumb",
|
Name: "thumb",
|
||||||
File: config.Thumb,
|
Data: config.Thumb,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,14 +550,14 @@ func (config StickerConfig) method() string {
|
||||||
func (config StickerConfig) files() []RequestFile {
|
func (config StickerConfig) files() []RequestFile {
|
||||||
return []RequestFile{{
|
return []RequestFile{{
|
||||||
Name: "sticker",
|
Name: "sticker",
|
||||||
File: config.File,
|
Data: config.File,
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// VideoConfig contains information about a SendVideo request.
|
// VideoConfig contains information about a SendVideo request.
|
||||||
type VideoConfig struct {
|
type VideoConfig struct {
|
||||||
BaseFile
|
BaseFile
|
||||||
Thumb interface{}
|
Thumb RequestFileData
|
||||||
Duration int
|
Duration int
|
||||||
Caption string
|
Caption string
|
||||||
ParseMode string
|
ParseMode string
|
||||||
|
@ -472,13 +587,13 @@ func (config VideoConfig) method() string {
|
||||||
func (config VideoConfig) files() []RequestFile {
|
func (config VideoConfig) files() []RequestFile {
|
||||||
files := []RequestFile{{
|
files := []RequestFile{{
|
||||||
Name: "video",
|
Name: "video",
|
||||||
File: config.File,
|
Data: config.File,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
if config.Thumb != nil {
|
if config.Thumb != nil {
|
||||||
files = append(files, RequestFile{
|
files = append(files, RequestFile{
|
||||||
Name: "thumb",
|
Name: "thumb",
|
||||||
File: config.Thumb,
|
Data: config.Thumb,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -489,7 +604,7 @@ func (config VideoConfig) files() []RequestFile {
|
||||||
type AnimationConfig struct {
|
type AnimationConfig struct {
|
||||||
BaseFile
|
BaseFile
|
||||||
Duration int
|
Duration int
|
||||||
Thumb interface{}
|
Thumb RequestFileData
|
||||||
Caption string
|
Caption string
|
||||||
ParseMode string
|
ParseMode string
|
||||||
CaptionEntities []MessageEntity
|
CaptionEntities []MessageEntity
|
||||||
|
@ -516,13 +631,13 @@ func (config AnimationConfig) method() string {
|
||||||
func (config AnimationConfig) files() []RequestFile {
|
func (config AnimationConfig) files() []RequestFile {
|
||||||
files := []RequestFile{{
|
files := []RequestFile{{
|
||||||
Name: "animation",
|
Name: "animation",
|
||||||
File: config.File,
|
Data: config.File,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
if config.Thumb != nil {
|
if config.Thumb != nil {
|
||||||
files = append(files, RequestFile{
|
files = append(files, RequestFile{
|
||||||
Name: "thumb",
|
Name: "thumb",
|
||||||
File: config.Thumb,
|
Data: config.Thumb,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -532,7 +647,7 @@ func (config AnimationConfig) files() []RequestFile {
|
||||||
// VideoNoteConfig contains information about a SendVideoNote request.
|
// VideoNoteConfig contains information about a SendVideoNote request.
|
||||||
type VideoNoteConfig struct {
|
type VideoNoteConfig struct {
|
||||||
BaseFile
|
BaseFile
|
||||||
Thumb interface{}
|
Thumb RequestFileData
|
||||||
Duration int
|
Duration int
|
||||||
Length int
|
Length int
|
||||||
}
|
}
|
||||||
|
@ -553,13 +668,13 @@ func (config VideoNoteConfig) method() string {
|
||||||
func (config VideoNoteConfig) files() []RequestFile {
|
func (config VideoNoteConfig) files() []RequestFile {
|
||||||
files := []RequestFile{{
|
files := []RequestFile{{
|
||||||
Name: "video_note",
|
Name: "video_note",
|
||||||
File: config.File,
|
Data: config.File,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
if config.Thumb != nil {
|
if config.Thumb != nil {
|
||||||
files = append(files, RequestFile{
|
files = append(files, RequestFile{
|
||||||
Name: "thumb",
|
Name: "thumb",
|
||||||
File: config.Thumb,
|
Data: config.Thumb,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -569,7 +684,7 @@ func (config VideoNoteConfig) files() []RequestFile {
|
||||||
// VoiceConfig contains information about a SendVoice request.
|
// VoiceConfig contains information about a SendVoice request.
|
||||||
type VoiceConfig struct {
|
type VoiceConfig struct {
|
||||||
BaseFile
|
BaseFile
|
||||||
Thumb interface{}
|
Thumb RequestFileData
|
||||||
Caption string
|
Caption string
|
||||||
ParseMode string
|
ParseMode string
|
||||||
CaptionEntities []MessageEntity
|
CaptionEntities []MessageEntity
|
||||||
|
@ -597,13 +712,13 @@ func (config VoiceConfig) method() string {
|
||||||
func (config VoiceConfig) files() []RequestFile {
|
func (config VoiceConfig) files() []RequestFile {
|
||||||
files := []RequestFile{{
|
files := []RequestFile{{
|
||||||
Name: "voice",
|
Name: "voice",
|
||||||
File: config.File,
|
Data: config.File,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
if config.Thumb != nil {
|
if config.Thumb != nil {
|
||||||
files = append(files, RequestFile{
|
files = append(files, RequestFile{
|
||||||
Name: "thumb",
|
Name: "thumb",
|
||||||
File: config.Thumb,
|
Data: config.Thumb,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1046,7 +1161,7 @@ func (config UpdateConfig) params() (Params, error) {
|
||||||
// WebhookConfig contains information about a SetWebhook request.
|
// WebhookConfig contains information about a SetWebhook request.
|
||||||
type WebhookConfig struct {
|
type WebhookConfig struct {
|
||||||
URL *url.URL
|
URL *url.URL
|
||||||
Certificate interface{}
|
Certificate RequestFileData
|
||||||
IPAddress string
|
IPAddress string
|
||||||
MaxConnections int
|
MaxConnections int
|
||||||
AllowedUpdates []string
|
AllowedUpdates []string
|
||||||
|
@ -1076,7 +1191,7 @@ func (config WebhookConfig) files() []RequestFile {
|
||||||
if config.Certificate != nil {
|
if config.Certificate != nil {
|
||||||
return []RequestFile{{
|
return []RequestFile{{
|
||||||
Name: "certificate",
|
Name: "certificate",
|
||||||
File: config.Certificate,
|
Data: config.Certificate,
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1100,25 +1215,6 @@ func (config DeleteWebhookConfig) params() (Params, error) {
|
||||||
return params, nil
|
return params, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FileBytes contains information about a set of bytes to upload
|
|
||||||
// as a File.
|
|
||||||
type FileBytes struct {
|
|
||||||
Name string
|
|
||||||
Bytes []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// FileReader contains information about a reader to upload as a File.
|
|
||||||
type FileReader struct {
|
|
||||||
Name string
|
|
||||||
Reader io.Reader
|
|
||||||
}
|
|
||||||
|
|
||||||
// FileURL is a URL to use as a file for a request.
|
|
||||||
type FileURL string
|
|
||||||
|
|
||||||
// FileID is an ID of a file already uploaded to Telegram.
|
|
||||||
type FileID string
|
|
||||||
|
|
||||||
// InlineConfig contains information on making an InlineQuery response.
|
// InlineConfig contains information on making an InlineQuery response.
|
||||||
type InlineConfig struct {
|
type InlineConfig struct {
|
||||||
InlineQueryID string `json:"inline_query_id"`
|
InlineQueryID string `json:"inline_query_id"`
|
||||||
|
@ -1753,7 +1849,7 @@ func (config SetChatPhotoConfig) method() string {
|
||||||
func (config SetChatPhotoConfig) files() []RequestFile {
|
func (config SetChatPhotoConfig) files() []RequestFile {
|
||||||
return []RequestFile{{
|
return []RequestFile{{
|
||||||
Name: "photo",
|
Name: "photo",
|
||||||
File: config.File,
|
Data: config.File,
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1837,7 +1933,7 @@ func (config GetStickerSetConfig) params() (Params, error) {
|
||||||
// UploadStickerConfig allows you to upload a sticker for use in a set later.
|
// UploadStickerConfig allows you to upload a sticker for use in a set later.
|
||||||
type UploadStickerConfig struct {
|
type UploadStickerConfig struct {
|
||||||
UserID int64
|
UserID int64
|
||||||
PNGSticker interface{}
|
PNGSticker RequestFileData
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config UploadStickerConfig) method() string {
|
func (config UploadStickerConfig) method() string {
|
||||||
|
@ -1855,7 +1951,7 @@ func (config UploadStickerConfig) params() (Params, error) {
|
||||||
func (config UploadStickerConfig) files() []RequestFile {
|
func (config UploadStickerConfig) files() []RequestFile {
|
||||||
return []RequestFile{{
|
return []RequestFile{{
|
||||||
Name: "png_sticker",
|
Name: "png_sticker",
|
||||||
File: config.PNGSticker,
|
Data: config.PNGSticker,
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1866,8 +1962,8 @@ type NewStickerSetConfig struct {
|
||||||
UserID int64
|
UserID int64
|
||||||
Name string
|
Name string
|
||||||
Title string
|
Title string
|
||||||
PNGSticker interface{}
|
PNGSticker RequestFileData
|
||||||
TGSSticker interface{}
|
TGSSticker RequestFileData
|
||||||
Emojis string
|
Emojis string
|
||||||
ContainsMasks bool
|
ContainsMasks bool
|
||||||
MaskPosition *MaskPosition
|
MaskPosition *MaskPosition
|
||||||
|
@ -1897,13 +1993,13 @@ func (config NewStickerSetConfig) files() []RequestFile {
|
||||||
if config.PNGSticker != nil {
|
if config.PNGSticker != nil {
|
||||||
return []RequestFile{{
|
return []RequestFile{{
|
||||||
Name: "png_sticker",
|
Name: "png_sticker",
|
||||||
File: config.PNGSticker,
|
Data: config.PNGSticker,
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
return []RequestFile{{
|
return []RequestFile{{
|
||||||
Name: "tgs_sticker",
|
Name: "tgs_sticker",
|
||||||
File: config.TGSSticker,
|
Data: config.TGSSticker,
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1911,8 +2007,8 @@ func (config NewStickerSetConfig) files() []RequestFile {
|
||||||
type AddStickerConfig struct {
|
type AddStickerConfig struct {
|
||||||
UserID int64
|
UserID int64
|
||||||
Name string
|
Name string
|
||||||
PNGSticker interface{}
|
PNGSticker RequestFileData
|
||||||
TGSSticker interface{}
|
TGSSticker RequestFileData
|
||||||
Emojis string
|
Emojis string
|
||||||
MaskPosition *MaskPosition
|
MaskPosition *MaskPosition
|
||||||
}
|
}
|
||||||
|
@ -1937,13 +2033,13 @@ func (config AddStickerConfig) files() []RequestFile {
|
||||||
if config.PNGSticker != nil {
|
if config.PNGSticker != nil {
|
||||||
return []RequestFile{{
|
return []RequestFile{{
|
||||||
Name: "png_sticker",
|
Name: "png_sticker",
|
||||||
File: config.PNGSticker,
|
Data: config.PNGSticker,
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
return []RequestFile{{
|
return []RequestFile{{
|
||||||
Name: "tgs_sticker",
|
Name: "tgs_sticker",
|
||||||
File: config.TGSSticker,
|
Data: config.TGSSticker,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1988,7 +2084,7 @@ func (config DeleteStickerConfig) params() (Params, error) {
|
||||||
type SetStickerSetThumbConfig struct {
|
type SetStickerSetThumbConfig struct {
|
||||||
Name string
|
Name string
|
||||||
UserID int64
|
UserID int64
|
||||||
Thumb interface{}
|
Thumb RequestFileData
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config SetStickerSetThumbConfig) method() string {
|
func (config SetStickerSetThumbConfig) method() string {
|
||||||
|
@ -2007,7 +2103,7 @@ func (config SetStickerSetThumbConfig) params() (Params, error) {
|
||||||
func (config SetStickerSetThumbConfig) files() []RequestFile {
|
func (config SetStickerSetThumbConfig) files() []RequestFile {
|
||||||
return []RequestFile{{
|
return []RequestFile{{
|
||||||
Name: "thumb",
|
Name: "thumb",
|
||||||
File: config.Thumb,
|
Data: config.Thumb,
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2181,45 +2277,38 @@ func (config DeleteMyCommandsConfig) params() (Params, error) {
|
||||||
func prepareInputMediaParam(inputMedia interface{}, idx int) interface{} {
|
func prepareInputMediaParam(inputMedia interface{}, idx int) interface{} {
|
||||||
switch m := inputMedia.(type) {
|
switch m := inputMedia.(type) {
|
||||||
case InputMediaPhoto:
|
case InputMediaPhoto:
|
||||||
switch m.Media.(type) {
|
if m.Media.NeedsUpload() {
|
||||||
case string, FileBytes, FileReader:
|
m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
|
||||||
m.Media = fmt.Sprintf("attach://file-%d", idx)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return m
|
return m
|
||||||
case InputMediaVideo:
|
case InputMediaVideo:
|
||||||
switch m.Media.(type) {
|
if m.Media.NeedsUpload() {
|
||||||
case string, FileBytes, FileReader:
|
m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
|
||||||
m.Media = fmt.Sprintf("attach://file-%d", idx)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch m.Thumb.(type) {
|
if m.Thumb != nil && m.Thumb.NeedsUpload() {
|
||||||
case string, FileBytes, FileReader:
|
m.Thumb = fileAttach(fmt.Sprintf("attach://file-%d-thumb", idx))
|
||||||
m.Thumb = fmt.Sprintf("attach://file-%d-thumb", idx)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return m
|
return m
|
||||||
case InputMediaAudio:
|
case InputMediaAudio:
|
||||||
switch m.Media.(type) {
|
if m.Media.NeedsUpload() {
|
||||||
case string, FileBytes, FileReader:
|
m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
|
||||||
m.Media = fmt.Sprintf("attach://file-%d", idx)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch m.Thumb.(type) {
|
if m.Thumb != nil && m.Thumb.NeedsUpload() {
|
||||||
case string, FileBytes, FileReader:
|
m.Thumb = fileAttach(fmt.Sprintf("attach://file-%d-thumb", idx))
|
||||||
m.Thumb = fmt.Sprintf("attach://file-%d-thumb", idx)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return m
|
return m
|
||||||
case InputMediaDocument:
|
case InputMediaDocument:
|
||||||
switch m.Media.(type) {
|
if m.Media.NeedsUpload() {
|
||||||
case string, FileBytes, FileReader:
|
m.Media = fileAttach(fmt.Sprintf("attach://file-%d", idx))
|
||||||
m.Media = fmt.Sprintf("attach://file-%d", idx)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch m.Thumb.(type) {
|
if m.Thumb != nil && m.Thumb.NeedsUpload() {
|
||||||
case string, FileBytes, FileReader:
|
m.Thumb = fileAttach(fmt.Sprintf("attach://file-%d-thumb", idx))
|
||||||
m.Thumb = fmt.Sprintf("attach://file-%d-thumb", idx)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return m
|
return m
|
||||||
|
@ -2241,59 +2330,52 @@ func prepareInputMediaFile(inputMedia interface{}, idx int) []RequestFile {
|
||||||
|
|
||||||
switch m := inputMedia.(type) {
|
switch m := inputMedia.(type) {
|
||||||
case InputMediaPhoto:
|
case InputMediaPhoto:
|
||||||
switch f := m.Media.(type) {
|
if m.Media.NeedsUpload() {
|
||||||
case string, FileBytes, FileReader:
|
|
||||||
files = append(files, RequestFile{
|
files = append(files, RequestFile{
|
||||||
Name: fmt.Sprintf("file-%d", idx),
|
Name: fmt.Sprintf("file-%d", idx),
|
||||||
File: f,
|
Data: m.Media,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
case InputMediaVideo:
|
case InputMediaVideo:
|
||||||
switch f := m.Media.(type) {
|
if m.Media.NeedsUpload() {
|
||||||
case string, FileBytes, FileReader:
|
|
||||||
files = append(files, RequestFile{
|
files = append(files, RequestFile{
|
||||||
Name: fmt.Sprintf("file-%d", idx),
|
Name: fmt.Sprintf("file-%d", idx),
|
||||||
File: f,
|
Data: m.Media,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
switch f := m.Thumb.(type) {
|
if m.Thumb != nil && m.Thumb.NeedsUpload() {
|
||||||
case string, FileBytes, FileReader:
|
|
||||||
files = append(files, RequestFile{
|
files = append(files, RequestFile{
|
||||||
Name: fmt.Sprintf("file-%d-thumb", idx),
|
Name: fmt.Sprintf("file-%d", idx),
|
||||||
File: f,
|
Data: m.Thumb,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
case InputMediaDocument:
|
case InputMediaDocument:
|
||||||
switch f := m.Media.(type) {
|
if m.Media.NeedsUpload() {
|
||||||
case string, FileBytes, FileReader:
|
|
||||||
files = append(files, RequestFile{
|
files = append(files, RequestFile{
|
||||||
Name: fmt.Sprintf("file-%d", idx),
|
Name: fmt.Sprintf("file-%d", idx),
|
||||||
File: f,
|
Data: m.Media,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
switch f := m.Thumb.(type) {
|
if m.Thumb != nil && m.Thumb.NeedsUpload() {
|
||||||
case string, FileBytes, FileReader:
|
|
||||||
files = append(files, RequestFile{
|
files = append(files, RequestFile{
|
||||||
Name: fmt.Sprintf("file-%d", idx),
|
Name: fmt.Sprintf("file-%d", idx),
|
||||||
File: f,
|
Data: m.Thumb,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
case InputMediaAudio:
|
case InputMediaAudio:
|
||||||
switch f := m.Media.(type) {
|
if m.Media.NeedsUpload() {
|
||||||
case string, FileBytes, FileReader:
|
|
||||||
files = append(files, RequestFile{
|
files = append(files, RequestFile{
|
||||||
Name: fmt.Sprintf("file-%d", idx),
|
Name: fmt.Sprintf("file-%d", idx),
|
||||||
File: f,
|
Data: m.Media,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
switch f := m.Thumb.(type) {
|
if m.Thumb != nil && m.Thumb.NeedsUpload() {
|
||||||
case string, FileBytes, FileReader:
|
|
||||||
files = append(files, RequestFile{
|
files = append(files, RequestFile{
|
||||||
Name: fmt.Sprintf("file-%d", idx),
|
Name: fmt.Sprintf("file-%d", idx),
|
||||||
File: f,
|
Data: m.Thumb,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,20 +3,22 @@
|
||||||
Telegram supports specifying files in many different formats. In order to
|
Telegram supports specifying files in many different formats. In order to
|
||||||
accommodate them all, there are multiple structs and type aliases required.
|
accommodate them all, there are multiple structs and type aliases required.
|
||||||
|
|
||||||
|
All of these types implement the `RequestFileData` interface.
|
||||||
|
|
||||||
| Type | Description |
|
| Type | Description |
|
||||||
| ------------ | ------------------------------------------------------------------------- |
|
| ------------ | ------------------------------------------------------------------------- |
|
||||||
| `string` | Used as a local path to a file |
|
| `FilePath` | A local path to a file |
|
||||||
| `FileID` | Existing file ID on Telegram's servers |
|
| `FileID` | Existing file ID on Telegram's servers |
|
||||||
| `FileURL` | URL to file, must be served with expected MIME type |
|
| `FileURL` | URL to file, must be served with expected MIME type |
|
||||||
| `FileReader` | Use an `io.Reader` to provide a file. Lazily read to save memory. |
|
| `FileReader` | Use an `io.Reader` to provide a file. Lazily read to save memory. |
|
||||||
| `FileBytes` | `[]byte` containing file data. Prefer to use `FileReader` to save memory. |
|
| `FileBytes` | `[]byte` containing file data. Prefer to use `FileReader` to save memory. |
|
||||||
|
|
||||||
## `string`
|
## `FilePath`
|
||||||
|
|
||||||
A path to a local file.
|
A path to a local file.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
file := "tests/image.jpg"
|
file := tgbotapi.FilePath("tests/image.jpg")
|
||||||
```
|
```
|
||||||
|
|
||||||
## `FileID`
|
## `FileID`
|
||||||
|
|
|
@ -19,7 +19,8 @@ type DeleteMessageConfig struct {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
What type should `ChatID` be? Telegram allows specifying numeric chat IDs or channel usernames. Golang doesn't have union types, and interfaces are entirely
|
What type should `ChatID` be? Telegram allows specifying numeric chat IDs or
|
||||||
|
channel usernames. Golang doesn't have union types, and interfaces are entirely
|
||||||
untyped. This library solves this by adding two fields, a `ChatID` and a
|
untyped. This library solves this by adding two fields, a `ChatID` and a
|
||||||
`ChannelUsername`. We can now write the struct as follows.
|
`ChannelUsername`. We can now write the struct as follows.
|
||||||
|
|
||||||
|
@ -103,8 +104,8 @@ have similar fields for their files.
|
||||||
ChannelUsername string
|
ChannelUsername string
|
||||||
ChatID int64
|
ChatID int64
|
||||||
MessageID int
|
MessageID int
|
||||||
+ Delete interface{}
|
+ Delete RequestFileData
|
||||||
+ Thumb interface{}
|
+ Thumb RequestFileData
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -115,13 +116,13 @@ and add the `thumb` file if we have one.
|
||||||
func (config DeleteMessageConfig) files() []RequestFile {
|
func (config DeleteMessageConfig) files() []RequestFile {
|
||||||
files := []RequestFile{{
|
files := []RequestFile{{
|
||||||
Name: "delete",
|
Name: "delete",
|
||||||
File: config.Delete,
|
Data: config.Delete,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
if config.Thumb != nil {
|
if config.Thumb != nil {
|
||||||
files = append(files, RequestFile{
|
files = append(files, RequestFile{
|
||||||
Name: "thumb",
|
Name: "thumb",
|
||||||
File: config.Thumb,
|
Data: config.Thumb,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,7 +130,8 @@ func (config DeleteMessageConfig) files() []RequestFile {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
And now our files will upload! It will transparently handle uploads whether File is a string with a path to a file, `FileURL`, `FileBytes`, `FileReader`, or `FileID`.
|
And now our files will upload! It will transparently handle uploads whether File
|
||||||
|
is a `FilePath`, `FileURL`, `FileBytes`, `FileReader`, or `FileID`.
|
||||||
|
|
||||||
### Base Configs
|
### Base Configs
|
||||||
|
|
||||||
|
|
|
@ -28,14 +28,14 @@ func (config DocumentConfig) files() []RequestFile {
|
||||||
// there always is a document file, so initialize the array with that.
|
// there always is a document file, so initialize the array with that.
|
||||||
files := []RequestFile{{
|
files := []RequestFile{{
|
||||||
Name: "document",
|
Name: "document",
|
||||||
File: config.File,
|
Data: config.File,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
// We'll only add a file if we have one.
|
// We'll only add a file if we have one.
|
||||||
if config.Thumb != nil {
|
if config.Thumb != nil {
|
||||||
files = append(files, RequestFile{
|
files = append(files, RequestFile{
|
||||||
Name: "thumb",
|
Name: "thumb",
|
||||||
File: config.Thumb,
|
Data: config.Thumb,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ Let's follow through creating a new media group with string and file uploads.
|
||||||
First, we start by creating some `InputMediaPhoto`.
|
First, we start by creating some `InputMediaPhoto`.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
photo := tgbotapi.NewInputMediaPhoto("tests/image.jpg")
|
photo := tgbotapi.NewInputMediaPhoto(tgbotapi.FilePath("tests/image.jpg"))
|
||||||
url := tgbotapi.NewInputMediaPhoto(tgbotapi.FileURL("https://i.imgur.com/unQLJIb.jpg"))
|
url := tgbotapi.NewInputMediaPhoto(tgbotapi.FileURL("https://i.imgur.com/unQLJIb.jpg"))
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -85,24 +85,3 @@ are all changed into `attach://file-%d`. When collecting a list of files to
|
||||||
upload, it names them the same way. This creates a nearly transparent way of
|
upload, it names them the same way. This creates a nearly transparent way of
|
||||||
handling multiple files in the background without the user having to consider
|
handling multiple files in the background without the user having to consider
|
||||||
what's going on.
|
what's going on.
|
||||||
|
|
||||||
## Library Processing
|
|
||||||
|
|
||||||
If at some point in the future new upload types are required, let's talk about
|
|
||||||
where the current types are used.
|
|
||||||
|
|
||||||
Upload types are defined in `configs.go`. Where possible, type aliases are
|
|
||||||
preferred. Structs can be used when multiple fields are required.
|
|
||||||
|
|
||||||
The main usage of the upload types happens in `UploadFiles`. It switches on each
|
|
||||||
file's type in order to determine how to upload it. Files that aren't uploaded
|
|
||||||
(file IDs, URLs) are converted back into strings and passed through as strings
|
|
||||||
into the correct field. Uploaded types are processed as needed (opening files,
|
|
||||||
etc.) and written into the form using a copy approach in a goroutine to reduce
|
|
||||||
memory usage.
|
|
||||||
|
|
||||||
In addition to `UploadFiles`, there's more processing of upload types in the
|
|
||||||
`prepareInputMediaParam` and `prepareInputMediaFile` functions. These look at
|
|
||||||
the `InputMedia` types to determine which files are uploaded and which are
|
|
||||||
passed through as strings. They only need to be aware of which files need to be
|
|
||||||
replaced with `attach://` fields.
|
|
||||||
|
|
34
helpers.go
34
helpers.go
|
@ -70,7 +70,7 @@ func NewCopyMessage(chatID int64, fromChatID int64, messageID int) CopyMessageCo
|
||||||
// FileReader, or FileBytes.
|
// FileReader, or FileBytes.
|
||||||
//
|
//
|
||||||
// Note that you must send animated GIFs as a document.
|
// Note that you must send animated GIFs as a document.
|
||||||
func NewPhoto(chatID int64, file interface{}) PhotoConfig {
|
func NewPhoto(chatID int64, file RequestFileData) PhotoConfig {
|
||||||
return PhotoConfig{
|
return PhotoConfig{
|
||||||
BaseFile: BaseFile{
|
BaseFile: BaseFile{
|
||||||
BaseChat: BaseChat{ChatID: chatID},
|
BaseChat: BaseChat{ChatID: chatID},
|
||||||
|
@ -82,7 +82,7 @@ func NewPhoto(chatID int64, file interface{}) PhotoConfig {
|
||||||
// NewPhotoToChannel creates a new photo uploader to send a photo to a channel.
|
// NewPhotoToChannel creates a new photo uploader to send a photo to a channel.
|
||||||
//
|
//
|
||||||
// Note that you must send animated GIFs as a document.
|
// Note that you must send animated GIFs as a document.
|
||||||
func NewPhotoToChannel(username string, file interface{}) PhotoConfig {
|
func NewPhotoToChannel(username string, file RequestFileData) PhotoConfig {
|
||||||
return PhotoConfig{
|
return PhotoConfig{
|
||||||
BaseFile: BaseFile{
|
BaseFile: BaseFile{
|
||||||
BaseChat: BaseChat{
|
BaseChat: BaseChat{
|
||||||
|
@ -94,7 +94,7 @@ func NewPhotoToChannel(username string, file interface{}) PhotoConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAudio creates a new sendAudio request.
|
// NewAudio creates a new sendAudio request.
|
||||||
func NewAudio(chatID int64, file interface{}) AudioConfig {
|
func NewAudio(chatID int64, file RequestFileData) AudioConfig {
|
||||||
return AudioConfig{
|
return AudioConfig{
|
||||||
BaseFile: BaseFile{
|
BaseFile: BaseFile{
|
||||||
BaseChat: BaseChat{ChatID: chatID},
|
BaseChat: BaseChat{ChatID: chatID},
|
||||||
|
@ -104,7 +104,7 @@ func NewAudio(chatID int64, file interface{}) AudioConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDocument creates a new sendDocument request.
|
// NewDocument creates a new sendDocument request.
|
||||||
func NewDocument(chatID int64, file interface{}) DocumentConfig {
|
func NewDocument(chatID int64, file RequestFileData) DocumentConfig {
|
||||||
return DocumentConfig{
|
return DocumentConfig{
|
||||||
BaseFile: BaseFile{
|
BaseFile: BaseFile{
|
||||||
BaseChat: BaseChat{ChatID: chatID},
|
BaseChat: BaseChat{ChatID: chatID},
|
||||||
|
@ -114,7 +114,7 @@ func NewDocument(chatID int64, file interface{}) DocumentConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSticker creates a new sendSticker request.
|
// NewSticker creates a new sendSticker request.
|
||||||
func NewSticker(chatID int64, file interface{}) StickerConfig {
|
func NewSticker(chatID int64, file RequestFileData) StickerConfig {
|
||||||
return StickerConfig{
|
return StickerConfig{
|
||||||
BaseFile: BaseFile{
|
BaseFile: BaseFile{
|
||||||
BaseChat: BaseChat{ChatID: chatID},
|
BaseChat: BaseChat{ChatID: chatID},
|
||||||
|
@ -124,7 +124,7 @@ func NewSticker(chatID int64, file interface{}) StickerConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewVideo creates a new sendVideo request.
|
// NewVideo creates a new sendVideo request.
|
||||||
func NewVideo(chatID int64, file interface{}) VideoConfig {
|
func NewVideo(chatID int64, file RequestFileData) VideoConfig {
|
||||||
return VideoConfig{
|
return VideoConfig{
|
||||||
BaseFile: BaseFile{
|
BaseFile: BaseFile{
|
||||||
BaseChat: BaseChat{ChatID: chatID},
|
BaseChat: BaseChat{ChatID: chatID},
|
||||||
|
@ -134,7 +134,7 @@ func NewVideo(chatID int64, file interface{}) VideoConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAnimation creates a new sendAnimation request.
|
// NewAnimation creates a new sendAnimation request.
|
||||||
func NewAnimation(chatID int64, file interface{}) AnimationConfig {
|
func NewAnimation(chatID int64, file RequestFileData) AnimationConfig {
|
||||||
return AnimationConfig{
|
return AnimationConfig{
|
||||||
BaseFile: BaseFile{
|
BaseFile: BaseFile{
|
||||||
BaseChat: BaseChat{ChatID: chatID},
|
BaseChat: BaseChat{ChatID: chatID},
|
||||||
|
@ -147,7 +147,7 @@ func NewAnimation(chatID int64, file interface{}) AnimationConfig {
|
||||||
//
|
//
|
||||||
// chatID is where to send it, file is a string path to the file,
|
// chatID is where to send it, file is a string path to the file,
|
||||||
// FileReader, or FileBytes.
|
// FileReader, or FileBytes.
|
||||||
func NewVideoNote(chatID int64, length int, file interface{}) VideoNoteConfig {
|
func NewVideoNote(chatID int64, length int, file RequestFileData) VideoNoteConfig {
|
||||||
return VideoNoteConfig{
|
return VideoNoteConfig{
|
||||||
BaseFile: BaseFile{
|
BaseFile: BaseFile{
|
||||||
BaseChat: BaseChat{ChatID: chatID},
|
BaseChat: BaseChat{ChatID: chatID},
|
||||||
|
@ -158,7 +158,7 @@ func NewVideoNote(chatID int64, length int, file interface{}) VideoNoteConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewVoice creates a new sendVoice request.
|
// NewVoice creates a new sendVoice request.
|
||||||
func NewVoice(chatID int64, file interface{}) VoiceConfig {
|
func NewVoice(chatID int64, file RequestFileData) VoiceConfig {
|
||||||
return VoiceConfig{
|
return VoiceConfig{
|
||||||
BaseFile: BaseFile{
|
BaseFile: BaseFile{
|
||||||
BaseChat: BaseChat{ChatID: chatID},
|
BaseChat: BaseChat{ChatID: chatID},
|
||||||
|
@ -177,7 +177,7 @@ func NewMediaGroup(chatID int64, files []interface{}) MediaGroupConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInputMediaPhoto creates a new InputMediaPhoto.
|
// NewInputMediaPhoto creates a new InputMediaPhoto.
|
||||||
func NewInputMediaPhoto(media interface{}) InputMediaPhoto {
|
func NewInputMediaPhoto(media RequestFileData) InputMediaPhoto {
|
||||||
return InputMediaPhoto{
|
return InputMediaPhoto{
|
||||||
BaseInputMedia{
|
BaseInputMedia{
|
||||||
Type: "photo",
|
Type: "photo",
|
||||||
|
@ -187,7 +187,7 @@ func NewInputMediaPhoto(media interface{}) InputMediaPhoto {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInputMediaVideo creates a new InputMediaVideo.
|
// NewInputMediaVideo creates a new InputMediaVideo.
|
||||||
func NewInputMediaVideo(media interface{}) InputMediaVideo {
|
func NewInputMediaVideo(media RequestFileData) InputMediaVideo {
|
||||||
return InputMediaVideo{
|
return InputMediaVideo{
|
||||||
BaseInputMedia: BaseInputMedia{
|
BaseInputMedia: BaseInputMedia{
|
||||||
Type: "video",
|
Type: "video",
|
||||||
|
@ -197,7 +197,7 @@ func NewInputMediaVideo(media interface{}) InputMediaVideo {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInputMediaAnimation creates a new InputMediaAnimation.
|
// NewInputMediaAnimation creates a new InputMediaAnimation.
|
||||||
func NewInputMediaAnimation(media interface{}) InputMediaAnimation {
|
func NewInputMediaAnimation(media RequestFileData) InputMediaAnimation {
|
||||||
return InputMediaAnimation{
|
return InputMediaAnimation{
|
||||||
BaseInputMedia: BaseInputMedia{
|
BaseInputMedia: BaseInputMedia{
|
||||||
Type: "animation",
|
Type: "animation",
|
||||||
|
@ -207,7 +207,7 @@ func NewInputMediaAnimation(media interface{}) InputMediaAnimation {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInputMediaAudio creates a new InputMediaAudio.
|
// NewInputMediaAudio creates a new InputMediaAudio.
|
||||||
func NewInputMediaAudio(media interface{}) InputMediaAudio {
|
func NewInputMediaAudio(media RequestFileData) InputMediaAudio {
|
||||||
return InputMediaAudio{
|
return InputMediaAudio{
|
||||||
BaseInputMedia: BaseInputMedia{
|
BaseInputMedia: BaseInputMedia{
|
||||||
Type: "audio",
|
Type: "audio",
|
||||||
|
@ -217,7 +217,7 @@ func NewInputMediaAudio(media interface{}) InputMediaAudio {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInputMediaDocument creates a new InputMediaDocument.
|
// NewInputMediaDocument creates a new InputMediaDocument.
|
||||||
func NewInputMediaDocument(media interface{}) InputMediaDocument {
|
func NewInputMediaDocument(media RequestFileData) InputMediaDocument {
|
||||||
return InputMediaDocument{
|
return InputMediaDocument{
|
||||||
BaseInputMedia: BaseInputMedia{
|
BaseInputMedia: BaseInputMedia{
|
||||||
Type: "document",
|
Type: "document",
|
||||||
|
@ -316,7 +316,7 @@ func NewWebhook(link string) (WebhookConfig, error) {
|
||||||
//
|
//
|
||||||
// link is the url you wish to get webhooks,
|
// link is the url you wish to get webhooks,
|
||||||
// file contains a string to a file, FileReader, or FileBytes.
|
// file contains a string to a file, FileReader, or FileBytes.
|
||||||
func NewWebhookWithCert(link string, file interface{}) (WebhookConfig, error) {
|
func NewWebhookWithCert(link string, file RequestFileData) (WebhookConfig, error) {
|
||||||
u, err := url.Parse(link)
|
u, err := url.Parse(link)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -769,7 +769,7 @@ func NewChatDescription(chatID int64, description string) SetChatDescriptionConf
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewChatPhoto allows you to update the photo for a chat.
|
// NewChatPhoto allows you to update the photo for a chat.
|
||||||
func NewChatPhoto(chatID int64, photo interface{}) SetChatPhotoConfig {
|
func NewChatPhoto(chatID int64, photo RequestFileData) SetChatPhotoConfig {
|
||||||
return SetChatPhotoConfig{
|
return SetChatPhotoConfig{
|
||||||
BaseFile: BaseFile{
|
BaseFile: BaseFile{
|
||||||
BaseChat: BaseChat{
|
BaseChat: BaseChat{
|
||||||
|
@ -781,7 +781,7 @@ func NewChatPhoto(chatID int64, photo interface{}) SetChatPhotoConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDeleteChatPhoto allows you to delete the photo for a chat.
|
// NewDeleteChatPhoto allows you to delete the photo for a chat.
|
||||||
func NewDeleteChatPhoto(chatID int64, photo interface{}) DeleteChatPhotoConfig {
|
func NewDeleteChatPhoto(chatID int64) DeleteChatPhotoConfig {
|
||||||
return DeleteChatPhotoConfig{
|
return DeleteChatPhotoConfig{
|
||||||
ChatID: chatID,
|
ChatID: chatID,
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ func TestNewWebhook(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewWebhookWithCert(t *testing.T) {
|
func TestNewWebhookWithCert(t *testing.T) {
|
||||||
exampleFile := File{FileID: "123"}
|
exampleFile := FileID("123")
|
||||||
result, err := NewWebhookWithCert("https://example.com/token", exampleFile)
|
result, err := NewWebhookWithCert("https://example.com/token", exampleFile)
|
||||||
|
|
||||||
if err != nil ||
|
if err != nil ||
|
||||||
|
|
10
types.go
10
types.go
|
@ -1723,7 +1723,7 @@ type BaseInputMedia struct {
|
||||||
// pass an HTTP URL for Telegram to get a file from the Internet,
|
// pass an HTTP URL for Telegram to get a file from the Internet,
|
||||||
// or pass “attach://<file_attach_name>” to upload a new one
|
// or pass “attach://<file_attach_name>” to upload a new one
|
||||||
// using multipart/form-data under <file_attach_name> name.
|
// using multipart/form-data under <file_attach_name> name.
|
||||||
Media interface{} `json:"media"`
|
Media RequestFileData `json:"media"`
|
||||||
// thumb intentionally missing as it is not currently compatible
|
// thumb intentionally missing as it is not currently compatible
|
||||||
|
|
||||||
// Caption of the video to be sent, 0-1024 characters after entities parsing.
|
// Caption of the video to be sent, 0-1024 characters after entities parsing.
|
||||||
|
@ -1755,7 +1755,7 @@ type InputMediaVideo struct {
|
||||||
// the file is supported server-side.
|
// the file is supported server-side.
|
||||||
//
|
//
|
||||||
// optional
|
// optional
|
||||||
Thumb interface{} `json:"thumb,omitempty"`
|
Thumb RequestFileData `json:"thumb,omitempty"`
|
||||||
// Width video width
|
// Width video width
|
||||||
//
|
//
|
||||||
// optional
|
// optional
|
||||||
|
@ -1781,7 +1781,7 @@ type InputMediaAnimation struct {
|
||||||
// the file is supported server-side.
|
// the file is supported server-side.
|
||||||
//
|
//
|
||||||
// optional
|
// optional
|
||||||
Thumb interface{} `json:"thumb,omitempty"`
|
Thumb RequestFileData `json:"thumb,omitempty"`
|
||||||
// Width video width
|
// Width video width
|
||||||
//
|
//
|
||||||
// optional
|
// optional
|
||||||
|
@ -1803,7 +1803,7 @@ type InputMediaAudio struct {
|
||||||
// the file is supported server-side.
|
// the file is supported server-side.
|
||||||
//
|
//
|
||||||
// optional
|
// optional
|
||||||
Thumb interface{} `json:"thumb,omitempty"`
|
Thumb RequestFileData `json:"thumb,omitempty"`
|
||||||
// Duration of the audio in seconds
|
// Duration of the audio in seconds
|
||||||
//
|
//
|
||||||
// optional
|
// optional
|
||||||
|
@ -1825,7 +1825,7 @@ type InputMediaDocument struct {
|
||||||
// the file is supported server-side.
|
// the file is supported server-side.
|
||||||
//
|
//
|
||||||
// optional
|
// optional
|
||||||
Thumb interface{} `json:"thumb,omitempty"`
|
Thumb RequestFileData `json:"thumb,omitempty"`
|
||||||
// DisableContentTypeDetection disables automatic server-side content type
|
// DisableContentTypeDetection disables automatic server-side content type
|
||||||
// detection for files uploaded using multipart/form-data. Always true, if
|
// detection for files uploaded using multipart/form-data. Always true, if
|
||||||
// the document is sent as part of an album
|
// the document is sent as part of an album
|
||||||
|
|
|
@ -361,3 +361,13 @@ var (
|
||||||
_ Fileable = (*WebhookConfig)(nil)
|
_ Fileable = (*WebhookConfig)(nil)
|
||||||
_ Fileable = (*SetStickerSetThumbConfig)(nil)
|
_ Fileable = (*SetStickerSetThumbConfig)(nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Ensure all RequestFileData types are correct.
|
||||||
|
var (
|
||||||
|
_ RequestFileData = (*FilePath)(nil)
|
||||||
|
_ RequestFileData = (*FileBytes)(nil)
|
||||||
|
_ RequestFileData = (*FileReader)(nil)
|
||||||
|
_ RequestFileData = (*FileURL)(nil)
|
||||||
|
_ RequestFileData = (*FileID)(nil)
|
||||||
|
_ RequestFileData = (*fileAttach)(nil)
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in New Issue