From 182d9b48f34b19f51cc5a88868a5477e52c02776 Mon Sep 17 00:00:00 2001 From: Carson Hoffman Date: Sun, 14 Mar 2021 12:27:22 -0400 Subject: [PATCH] Add more robust file support for webhooks --- restapi.go | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++- webhook.go | 2 +- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/restapi.go b/restapi.go index 654579fcb..8afc1e47c 100644 --- a/restapi.go +++ b/restapi.go @@ -2174,7 +2174,60 @@ func (s *Session) WebhookExecute(webhookID, token string, wait bool, data *Webho uri += "?wait=true" } - response, err := s.RequestWithBucketID("POST", uri, data, EndpointWebhookToken("", "")) + var response []byte + if len(data.Files) > 0 { + body := &bytes.Buffer{} + bodywriter := multipart.NewWriter(body) + + var payload []byte + payload, err = json.Marshal(data) + if err != nil { + return + } + + var p io.Writer + + h := make(textproto.MIMEHeader) + h.Set("Content-Disposition", `form-data; name="payload_json"`) + h.Set("Content-Type", "application/json") + + p, err = bodywriter.CreatePart(h) + if err != nil { + return + } + + if _, err = p.Write(payload); err != nil { + return + } + + for i, file := range data.Files { + h := make(textproto.MIMEHeader) + h.Set("Content-Disposition", fmt.Sprintf(`form-data; name="file%d"; filename="%s"`, i, quoteEscaper.Replace(file.Name))) + contentType := file.ContentType + if contentType == "" { + contentType = "application/octet-stream" + } + h.Set("Content-Type", contentType) + + p, err = bodywriter.CreatePart(h) + if err != nil { + return + } + + if _, err = io.Copy(p, file.Reader); err != nil { + return + } + } + + err = bodywriter.Close() + if err != nil { + return + } + + response, err = s.request("POST", uri, bodywriter.FormDataContentType(), body.Bytes(), uri, 0) + } else { + response, err = s.RequestWithBucketID("POST", uri, data, uri) + } if !wait || err != nil { return } diff --git a/webhook.go b/webhook.go index b8b3abcde..1fc4c4f24 100644 --- a/webhook.go +++ b/webhook.go @@ -31,7 +31,7 @@ type WebhookParams struct { Username string `json:"username,omitempty"` AvatarURL string `json:"avatar_url,omitempty"` TTS bool `json:"tts,omitempty"` - File string `json:"file,omitempty"` + Files []*File `json:"-"` Embeds []*MessageEmbed `json:"embeds,omitempty"` AllowedMentions *MessageAllowedMentions `json:"allowed_mentions,omitempty"` }