2020-01-02 05:39:52 +00:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io"
|
|
|
|
"mime/multipart"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
|
2020-01-02 19:55:45 +00:00
|
|
|
"github.com/diamondburned/arikawa/discord"
|
2020-02-17 17:28:52 +00:00
|
|
|
"github.com/diamondburned/arikawa/internal/httputil"
|
2020-01-15 18:32:54 +00:00
|
|
|
"github.com/diamondburned/arikawa/internal/json"
|
2020-01-02 05:39:52 +00:00
|
|
|
"github.com/pkg/errors"
|
|
|
|
)
|
|
|
|
|
2020-02-17 17:28:52 +00:00
|
|
|
func (c *Client) SendMessageComplex(
|
|
|
|
channelID discord.Snowflake,
|
|
|
|
data SendMessageData) (*discord.Message, error) {
|
|
|
|
|
|
|
|
if data.Embed != nil {
|
|
|
|
if err := data.Embed.Validate(); err != nil {
|
|
|
|
return nil, errors.Wrap(err, "Embed error")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var URL = EndpointChannels + channelID.String() + "/messages"
|
|
|
|
var msg *discord.Message
|
|
|
|
|
|
|
|
if len(data.Files) == 0 {
|
|
|
|
// No files, so no need for streaming.
|
|
|
|
return msg, c.RequestJSON(&msg, "POST", URL,
|
|
|
|
httputil.WithJSONBody(c, data))
|
|
|
|
}
|
|
|
|
|
|
|
|
writer := func(mw *multipart.Writer) error {
|
|
|
|
return data.WriteMultipart(c, mw)
|
|
|
|
}
|
|
|
|
|
|
|
|
resp, err := c.MeanwhileMultipart(writer, "POST", URL)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
return msg, c.DecodeStream(resp.Body, &msg)
|
|
|
|
}
|
|
|
|
|
2020-01-19 03:12:08 +00:00
|
|
|
const AttachmentSpoilerPrefix = "SPOILER_"
|
|
|
|
|
2020-01-19 02:27:30 +00:00
|
|
|
var quoteEscaper = strings.NewReplacer(`\`, `\\`, `"`, `\"`)
|
|
|
|
|
|
|
|
type SendMessageFile struct {
|
2020-01-19 03:12:08 +00:00
|
|
|
Name string
|
|
|
|
Reader io.Reader
|
2020-01-19 02:27:30 +00:00
|
|
|
}
|
|
|
|
|
2020-01-02 05:39:52 +00:00
|
|
|
type SendMessageData struct {
|
2020-01-19 02:27:30 +00:00
|
|
|
Content string `json:"content,omitempty"`
|
|
|
|
Nonce string `json:"nonce,omitempty"`
|
2020-01-02 05:39:52 +00:00
|
|
|
TTS bool `json:"tts"`
|
2020-01-02 19:53:08 +00:00
|
|
|
|
2020-01-19 02:27:30 +00:00
|
|
|
Embed *discord.Embed `json:"embed,omitempty"`
|
2020-01-02 05:39:52 +00:00
|
|
|
|
|
|
|
Files []SendMessageFile `json:"-"`
|
|
|
|
}
|
|
|
|
|
2020-01-19 02:27:30 +00:00
|
|
|
func (data *SendMessageData) WriteMultipart(
|
2020-01-19 03:12:08 +00:00
|
|
|
c json.Driver, body *multipart.Writer) error {
|
2020-01-19 02:27:30 +00:00
|
|
|
|
2020-01-19 03:12:08 +00:00
|
|
|
return writeMultipart(c, body, data, data.Files)
|
2020-01-02 05:39:52 +00:00
|
|
|
}
|
|
|
|
|
2020-01-19 02:27:30 +00:00
|
|
|
type ExecuteWebhookData struct {
|
2020-01-24 06:05:09 +00:00
|
|
|
Content string `json:"content,omitempty"`
|
|
|
|
Nonce string `json:"nonce,omitempty"`
|
|
|
|
TTS bool `json:"tts"`
|
|
|
|
|
|
|
|
Embeds []discord.Embed `json:"embeds,omitempty"`
|
|
|
|
|
|
|
|
Files []SendMessageFile `json:"-"`
|
2020-01-19 02:27:30 +00:00
|
|
|
|
|
|
|
Username string `json:"username,omitempty"`
|
|
|
|
AvatarURL discord.URL `json:"avatar_url,omitempty"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (data *ExecuteWebhookData) WriteMultipart(
|
2020-01-19 03:12:08 +00:00
|
|
|
c json.Driver, body *multipart.Writer) error {
|
2020-01-19 02:27:30 +00:00
|
|
|
|
2020-01-19 03:12:08 +00:00
|
|
|
return writeMultipart(c, body, data, data.Files)
|
2020-01-19 02:27:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func writeMultipart(
|
2020-01-19 03:12:08 +00:00
|
|
|
c json.Driver, body *multipart.Writer,
|
2020-01-19 02:27:30 +00:00
|
|
|
item interface{}, files []SendMessageFile) error {
|
2020-01-02 05:39:52 +00:00
|
|
|
|
2020-01-19 03:12:08 +00:00
|
|
|
defer body.Close()
|
2020-01-02 05:39:52 +00:00
|
|
|
|
|
|
|
// Encode the JSON body first
|
2020-01-19 03:12:08 +00:00
|
|
|
w, err := body.CreateFormField("payload_json")
|
2020-01-02 05:39:52 +00:00
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "Failed to create bodypart for JSON")
|
|
|
|
}
|
|
|
|
|
2020-01-19 02:27:30 +00:00
|
|
|
if err := c.EncodeStream(w, item); err != nil {
|
2020-01-02 05:39:52 +00:00
|
|
|
return errors.Wrap(err, "Failed to encode JSON")
|
|
|
|
}
|
|
|
|
|
2020-01-19 02:27:30 +00:00
|
|
|
for i, file := range files {
|
2020-01-19 03:12:08 +00:00
|
|
|
num := strconv.Itoa(i)
|
2020-01-19 02:27:30 +00:00
|
|
|
|
2020-01-19 03:12:08 +00:00
|
|
|
w, err := body.CreateFormFile("file"+num, file.Name)
|
2020-01-19 02:27:30 +00:00
|
|
|
if err != nil {
|
2020-01-19 03:12:08 +00:00
|
|
|
return errors.Wrap(err, "Failed to create bodypart for "+num)
|
2020-01-02 05:39:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if _, err := io.Copy(w, file.Reader); err != nil {
|
2020-01-19 03:12:08 +00:00
|
|
|
return errors.Wrap(err, "Failed to write for file "+num)
|
2020-01-02 05:39:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|