Skip to content

Commit

Permalink
Improve inputfile logic to properly handle values json value marshalling
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulSonOfLars committed Jun 11, 2024
1 parent 67ef470 commit a22257a
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 77 deletions.
58 changes: 38 additions & 20 deletions file.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ import (
// This object represents the contents of a file to be uploaded.
// Must be posted using multipart/form-data in the usual way that files are uploaded via the browser.
type InputFile interface {
Attach(name string, data map[string]FileReader) (string, error)
InputFileOrString
justFiles()
}

// InputString (https://core.telegram.org/bots/api#inputfile)
//
// This object represents a publicly accessible URL to be reused, or a file_id already available on telegram servers.
type InputString interface {
Attach(name string, data map[string]FileReader) (string, error)
InputFileOrString
justStrings()
}

Expand All @@ -28,56 +28,74 @@ type InputString interface {
// This object represents the contents of a file to be uploaded, or a publicly accessible URL to be reused.
// Files must be posted using multipart/form-data in the usual way that files are uploaded via the browser.
type InputFileOrString interface {
Attach(name string, data map[string]FileReader) (string, error)
Attach(name string, data map[string]FileReader) error
getValue() string
}

var (
_ InputFileOrString = FileString{}
_ InputString = FileString{}
_ InputFileOrString = &FileString{}
_ InputString = &FileString{}

_ InputFileOrString = FileReader{}
_ InputFile = FileReader{}
_ InputFileOrString = &FileReader{}
_ InputFile = &FileReader{}
)

type FileString struct {
Value string
}

func (f FileString) justStrings() {}
func (f *FileString) justStrings() {}

func (f FileString) MarshalJSON() ([]byte, error) {
return json.Marshal(f.Value)
func (f *FileString) MarshalJSON() ([]byte, error) {
return json.Marshal(f.getValue())
}

func (f FileString) Attach(_ string, _ map[string]FileReader) (string, error) {
return f.Value, nil
func (f *FileString) Attach(_ string, _ map[string]FileReader) error {
return nil
}

func (f *FileString) getValue() string {
return f.Value
}

type FileReader struct {
Name string
Data io.Reader

value string
}

func (f *FileReader) MarshalJSON() ([]byte, error) {
return json.Marshal(f.getValue())
}

var ErrAttachmentKeyAlreadyExists = errors.New("key already exists")

func (f FileReader) Attach(key string, data map[string]FileReader) (string, error) {
func (f *FileReader) justFiles() {}

func (f *FileReader) Attach(key string, data map[string]FileReader) error {
if _, ok := data[key]; ok {
return "", ErrAttachmentKeyAlreadyExists
return ErrAttachmentKeyAlreadyExists
}
data[key] = f
return "attach://" + key, nil
f.value = key
data[key] = *f
return nil
}

func (f FileReader) justFiles() {}
// getValue returns the file attach reference for the relevant multipart form.
// Calling getValue is only valid after having called Attach on this struct.
func (f *FileReader) getValue() string {
return "attach://" + f.value
}

// InputFileByURL is used to send a file on the internet via a publicly accessible HTTP URL.
func InputFileByURL(url string) InputFileOrString {
return FileString{Value: url}
return &FileString{Value: url}
}

// InputFileByID is used to send a file that is already present on telegram's servers, using its telegram file_id.
func InputFileByID(fileID string) InputFileOrString {
return FileString{Value: fileID}
return &FileString{Value: fileID}
}

// InputFileByReader is used to send a file by a reader interface; such as a filehandle from os.Open(), or from a byte
Expand All @@ -96,5 +114,5 @@ func InputFileByID(fileID string) InputFileOrString {
//
// m, err := b.SendDocument(<chat_id>, gotgbot.InputFileByReader("file.txt", strings.NewReader("Some file contents")), nil)
func InputFileByReader(name string, r io.Reader) InputFile {
return FileReader{Name: name, Data: r}
return &FileReader{Name: name, Data: r}
}
68 changes: 34 additions & 34 deletions gen_methods.go
Original file line number Diff line number Diff line change
Expand Up @@ -2925,11 +2925,11 @@ func (bot *Bot) SendAnimation(chatId int64, animation InputFileOrString, opts *S
data := map[string]FileReader{}
v["chat_id"] = strconv.FormatInt(chatId, 10)
if animation != nil {
key, err := animation.Attach("animation", data)
err := animation.Attach("animation", data)
if err != nil {
return nil, err
}
v["animation"] = key
v["animation"] = animation.getValue()
}
if opts != nil {
v["business_connection_id"] = opts.BusinessConnectionId
Expand All @@ -2946,11 +2946,11 @@ func (bot *Bot) SendAnimation(chatId int64, animation InputFileOrString, opts *S
v["height"] = strconv.FormatInt(opts.Height, 10)
}
if opts.Thumbnail != nil {
key, err := opts.Thumbnail.Attach("thumbnail", data)
err := opts.Thumbnail.Attach("thumbnail", data)
if err != nil {
return nil, err
}
v["thumbnail"] = key
v["thumbnail"] = opts.Thumbnail.getValue()
}
v["caption"] = opts.Caption
v["parse_mode"] = opts.ParseMode
Expand Down Expand Up @@ -3042,11 +3042,11 @@ func (bot *Bot) SendAudio(chatId int64, audio InputFileOrString, opts *SendAudio
data := map[string]FileReader{}
v["chat_id"] = strconv.FormatInt(chatId, 10)
if audio != nil {
key, err := audio.Attach("audio", data)
err := audio.Attach("audio", data)
if err != nil {
return nil, err
}
v["audio"] = key
v["audio"] = audio.getValue()
}
if opts != nil {
v["business_connection_id"] = opts.BusinessConnectionId
Expand All @@ -3068,11 +3068,11 @@ func (bot *Bot) SendAudio(chatId int64, audio InputFileOrString, opts *SendAudio
v["performer"] = opts.Performer
v["title"] = opts.Title
if opts.Thumbnail != nil {
key, err := opts.Thumbnail.Attach("thumbnail", data)
err := opts.Thumbnail.Attach("thumbnail", data)
if err != nil {
return nil, err
}
v["thumbnail"] = key
v["thumbnail"] = opts.Thumbnail.getValue()
}
v["disable_notification"] = strconv.FormatBool(opts.DisableNotification)
v["protect_content"] = strconv.FormatBool(opts.ProtectContent)
Expand Down Expand Up @@ -3335,23 +3335,23 @@ func (bot *Bot) SendDocument(chatId int64, document InputFileOrString, opts *Sen
data := map[string]FileReader{}
v["chat_id"] = strconv.FormatInt(chatId, 10)
if document != nil {
key, err := document.Attach("document", data)
err := document.Attach("document", data)
if err != nil {
return nil, err
}
v["document"] = key
v["document"] = document.getValue()
}
if opts != nil {
v["business_connection_id"] = opts.BusinessConnectionId
if opts.MessageThreadId != 0 {
v["message_thread_id"] = strconv.FormatInt(opts.MessageThreadId, 10)
}
if opts.Thumbnail != nil {
key, err := opts.Thumbnail.Attach("thumbnail", data)
err := opts.Thumbnail.Attach("thumbnail", data)
if err != nil {
return nil, err
}
v["thumbnail"] = key
v["thumbnail"] = opts.Thumbnail.getValue()
}
v["caption"] = opts.Caption
v["parse_mode"] = opts.ParseMode
Expand Down Expand Up @@ -3895,11 +3895,11 @@ func (bot *Bot) SendPhoto(chatId int64, photo InputFileOrString, opts *SendPhoto
data := map[string]FileReader{}
v["chat_id"] = strconv.FormatInt(chatId, 10)
if photo != nil {
key, err := photo.Attach("photo", data)
err := photo.Attach("photo", data)
if err != nil {
return nil, err
}
v["photo"] = key
v["photo"] = photo.getValue()
}
if opts != nil {
v["business_connection_id"] = opts.BusinessConnectionId
Expand Down Expand Up @@ -4114,11 +4114,11 @@ func (bot *Bot) SendSticker(chatId int64, sticker InputFileOrString, opts *SendS
data := map[string]FileReader{}
v["chat_id"] = strconv.FormatInt(chatId, 10)
if sticker != nil {
key, err := sticker.Attach("sticker", data)
err := sticker.Attach("sticker", data)
if err != nil {
return nil, err
}
v["sticker"] = key
v["sticker"] = sticker.getValue()
}
if opts != nil {
v["business_connection_id"] = opts.BusinessConnectionId
Expand Down Expand Up @@ -4296,11 +4296,11 @@ func (bot *Bot) SendVideo(chatId int64, video InputFileOrString, opts *SendVideo
data := map[string]FileReader{}
v["chat_id"] = strconv.FormatInt(chatId, 10)
if video != nil {
key, err := video.Attach("video", data)
err := video.Attach("video", data)
if err != nil {
return nil, err
}
v["video"] = key
v["video"] = video.getValue()
}
if opts != nil {
v["business_connection_id"] = opts.BusinessConnectionId
Expand All @@ -4317,11 +4317,11 @@ func (bot *Bot) SendVideo(chatId int64, video InputFileOrString, opts *SendVideo
v["height"] = strconv.FormatInt(opts.Height, 10)
}
if opts.Thumbnail != nil {
key, err := opts.Thumbnail.Attach("thumbnail", data)
err := opts.Thumbnail.Attach("thumbnail", data)
if err != nil {
return nil, err
}
v["thumbnail"] = key
v["thumbnail"] = opts.Thumbnail.getValue()
}
v["caption"] = opts.Caption
v["parse_mode"] = opts.ParseMode
Expand Down Expand Up @@ -4405,11 +4405,11 @@ func (bot *Bot) SendVideoNote(chatId int64, videoNote InputFileOrString, opts *S
data := map[string]FileReader{}
v["chat_id"] = strconv.FormatInt(chatId, 10)
if videoNote != nil {
key, err := videoNote.Attach("video_note", data)
err := videoNote.Attach("video_note", data)
if err != nil {
return nil, err
}
v["video_note"] = key
v["video_note"] = videoNote.getValue()
}
if opts != nil {
v["business_connection_id"] = opts.BusinessConnectionId
Expand All @@ -4423,11 +4423,11 @@ func (bot *Bot) SendVideoNote(chatId int64, videoNote InputFileOrString, opts *S
v["length"] = strconv.FormatInt(opts.Length, 10)
}
if opts.Thumbnail != nil {
key, err := opts.Thumbnail.Attach("thumbnail", data)
err := opts.Thumbnail.Attach("thumbnail", data)
if err != nil {
return nil, err
}
v["thumbnail"] = key
v["thumbnail"] = opts.Thumbnail.getValue()
}
v["disable_notification"] = strconv.FormatBool(opts.DisableNotification)
v["protect_content"] = strconv.FormatBool(opts.ProtectContent)
Expand Down Expand Up @@ -4501,11 +4501,11 @@ func (bot *Bot) SendVoice(chatId int64, voice InputFileOrString, opts *SendVoice
data := map[string]FileReader{}
v["chat_id"] = strconv.FormatInt(chatId, 10)
if voice != nil {
key, err := voice.Attach("voice", data)
err := voice.Attach("voice", data)
if err != nil {
return nil, err
}
v["voice"] = key
v["voice"] = voice.getValue()
}
if opts != nil {
v["business_connection_id"] = opts.BusinessConnectionId
Expand Down Expand Up @@ -4722,11 +4722,11 @@ func (bot *Bot) SetChatPhoto(chatId int64, photo InputFile, opts *SetChatPhotoOp
data := map[string]FileReader{}
v["chat_id"] = strconv.FormatInt(chatId, 10)
if photo != nil {
key, err := photo.Attach("photo", data)
err := photo.Attach("photo", data)
if err != nil {
return false, err
}
v["photo"] = key
v["photo"] = photo.getValue()
}

var reqOpts *RequestOpts
Expand Down Expand Up @@ -5346,11 +5346,11 @@ func (bot *Bot) SetStickerSetThumbnail(name string, userId int64, format string,
v["format"] = format
if opts != nil {
if opts.Thumbnail != nil {
key, err := opts.Thumbnail.Attach("thumbnail", data)
err := opts.Thumbnail.Attach("thumbnail", data)
if err != nil {
return false, err
}
v["thumbnail"] = key
v["thumbnail"] = opts.Thumbnail.getValue()
}
}

Expand Down Expand Up @@ -5429,11 +5429,11 @@ func (bot *Bot) SetWebhook(url string, opts *SetWebhookOpts) (bool, error) {
v["url"] = url
if opts != nil {
if opts.Certificate != nil {
key, err := opts.Certificate.Attach("certificate", data)
err := opts.Certificate.Attach("certificate", data)
if err != nil {
return false, err
}
v["certificate"] = key
v["certificate"] = opts.Certificate.getValue()
}
v["ip_address"] = opts.IpAddress
if opts.MaxConnections != 0 {
Expand Down Expand Up @@ -5800,11 +5800,11 @@ func (bot *Bot) UploadStickerFile(userId int64, sticker InputFile, stickerFormat
data := map[string]FileReader{}
v["user_id"] = strconv.FormatInt(userId, 10)
if sticker != nil {
key, err := sticker.Attach("sticker", data)
err := sticker.Attach("sticker", data)
if err != nil {
return nil, err
}
v["sticker"] = key
v["sticker"] = sticker.getValue()
}
v["sticker_format"] = stickerFormat

Expand Down
Loading

0 comments on commit a22257a

Please sign in to comment.