mirror of
https://github.com/diamondburned/arikawa.git
synced 2024-12-03 20:32:55 +00:00
diamondburned
525d0bb3f6
This commit moved ExecuteWebhookData from package api to package webhook inside package api. This change required splitting the multipart abstractions away from package api, so they are now inside package sendpart in utils. This commit will break code that uploads anything, as the type name is now sendpart.File from api.SendMessageFile. The behavior should be the same as before.
81 lines
1.9 KiB
Go
81 lines
1.9 KiB
Go
package sendpart
|
|
|
|
import (
|
|
"io"
|
|
"mime/multipart"
|
|
"strconv"
|
|
|
|
"github.com/diamondburned/arikawa/v2/utils/httputil"
|
|
"github.com/diamondburned/arikawa/v2/utils/json"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
// File represents a file to be uploaded to Discord.
|
|
type File struct {
|
|
Name string
|
|
Reader io.Reader
|
|
}
|
|
|
|
// DataMultipartWriter is a MultipartWriter that also contains data that's
|
|
// JSON-marshalable.
|
|
type DataMultipartWriter interface {
|
|
// NeedsMultipart returns true if the data interface must be sent using
|
|
// multipart form.
|
|
NeedsMultipart() bool
|
|
|
|
httputil.MultipartWriter
|
|
}
|
|
|
|
// POST sends a POST request using client to the given URL and unmarshal the
|
|
// body into v if it's not nil. It will only send using multipart if files is
|
|
// true.
|
|
func POST(c *httputil.Client, data DataMultipartWriter, v interface{}, url string) error {
|
|
if !data.NeedsMultipart() {
|
|
// No files, so no need for streaming.
|
|
return c.RequestJSON(v, "POST", url, httputil.WithJSONBody(data))
|
|
}
|
|
|
|
resp, err := c.MeanwhileMultipart(data, "POST", url)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var body = resp.GetBody()
|
|
defer body.Close()
|
|
|
|
if v == nil {
|
|
return nil
|
|
}
|
|
|
|
return json.DecodeStream(body, v)
|
|
}
|
|
|
|
// Write writes the item into payload_json and the list of files into the
|
|
// multipart writer. Write does not close the body.
|
|
func Write(body *multipart.Writer, item interface{}, files []File) error {
|
|
// Encode the JSON body first
|
|
w, err := body.CreateFormField("payload_json")
|
|
if err != nil {
|
|
return errors.Wrap(err, "failed to create bodypart for JSON")
|
|
}
|
|
|
|
if err := json.EncodeStream(w, item); err != nil {
|
|
return errors.Wrap(err, "failed to encode JSON")
|
|
}
|
|
|
|
for i, file := range files {
|
|
num := strconv.Itoa(i)
|
|
|
|
w, err := body.CreateFormFile("file"+num, file.Name)
|
|
if err != nil {
|
|
return errors.Wrap(err, "failed to create bodypart for "+num)
|
|
}
|
|
|
|
if _, err := io.Copy(w, file.Reader); err != nil {
|
|
return errors.Wrap(err, "failed to write for file "+num)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|