-
Notifications
You must be signed in to change notification settings - Fork 120
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Compile-time inputfile validation (#163)
* Cleanup and improve inputfile interfaces * Update sample bots to work with new typesafe inputfile logic * Media should be of type inputfileorstring * fix lint * Make sure thumbnails cannot be strings * Improve inputfile logic to properly handle values json value marshalling * Add missing thumbnail logic to certain inputmedia types and improve error messages * remove unnecessary InputString type which turned out to be unnecessary * regenerate after merge
- Loading branch information
1 parent
4a42cea
commit a8e2c08
Showing
11 changed files
with
382 additions
and
641 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package gotgbot | ||
|
||
import ( | ||
"encoding/json" | ||
"errors" | ||
"io" | ||
) | ||
|
||
// InputFile (https://core.telegram.org/bots/api#inputfile) | ||
// | ||
// 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 { | ||
InputFileOrString | ||
justFiles() | ||
} | ||
|
||
// InputFileOrString (https://core.telegram.org/bots/api#inputfile) | ||
// | ||
// 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) error | ||
getValue() string | ||
} | ||
|
||
var ( | ||
_ InputFileOrString = &FileReader{} | ||
_ InputFile = &FileReader{} | ||
) | ||
|
||
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) justFiles() {} | ||
|
||
func (f *FileReader) Attach(key string, data map[string]FileReader) error { | ||
if f.Data == nil { | ||
// if no data, this must be a string; nothing to "attach". | ||
return nil | ||
} | ||
|
||
if _, ok := data[key]; ok { | ||
return ErrAttachmentKeyAlreadyExists | ||
} | ||
f.value = "attach://" + key | ||
data[key] = *f | ||
return nil | ||
} | ||
|
||
// getValue returns the file attach reference for the relevant multipart form. | ||
// Make sure to only call getValue after having called Attach(), to ensure any files have been included. | ||
func (f *FileReader) getValue() string { | ||
return f.value | ||
} | ||
|
||
// InputFileByURL is used to send a file on the internet via a publicly accessible HTTP URL. | ||
func InputFileByURL(url string) InputFileOrString { | ||
return &FileReader{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 &FileReader{value: fileID} | ||
} | ||
|
||
// InputFileByReader is used to send a file by a reader interface; such as a filehandle from os.Open(), or from a byte | ||
// buffer. | ||
// | ||
// For example: | ||
// | ||
// f, err := os.Open("some_file.go") | ||
// if err != nil { | ||
// return fmt.Errorf("failed to open file: %w", err) | ||
// } | ||
// | ||
// m, err := b.SendDocument(<chat_id>, gotgbot.InputFileByReader("source.go", f), nil) | ||
// | ||
// Or | ||
// | ||
// 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} | ||
} |
Oops, something went wrong.