I am trying to upload a single PNG file to a Discord channel using a webhook using vanilla javascript because I cannot use Discord.js.
In Chrome's JavaScript console, I get the following error message:
POST https://discordapp.com/api/webhooks/<my discord webhook> 400
Followed by this console.log() output:
Success: {message: "Cannot send an empty message", code: 50006}
I include my code and the Network console transcript at the end, but I have 1 question:
- what am I doing wrong? I see that
Content-Dispositionfor the file is of typeform-data, any connection to my problem?
Before that, I managed to post messages (json only, no files) using both XMLHttpRequest and fetch.
I did not try using JQuery although I could and would prefer a pure Javascript solution.
Below is the code I wrote, to send a single PNG image as well as a payload_json JSON data payload (same error without the payload):
const filename = 'image.png';
domtoimage.toBlob(document.querySelector('<element to snapshot selector>'))
.then(function (blob) {
const formData = new FormData();
var params = {
username: "My bot name",
avatar_url: "",
content: "another test 2",
embeds: [{
"image": {
"url": "https://i.imgur.com/ZGPxFN2.jpg"
}
}]
};
formData.append('payload_json',JSON.stringify(params))
formData.append('file',blob);
fetch('https://discordapp.com/api/webhooks/<my discord webhook>', {
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data',
},
body: formData,
})
.then(response => response.json())
.then(result => {
console.log('Success:', result);
})
.catch(error => {
console.error('Error:', error);
});
});
In Chrome's Network console, I get the following information:
General
Request URL: https://discordapp.com/api/webhooks/<my discord webhook>
Request Method: POST
Status Code: 400
Remote Address: 162.159.134.233:443
Referrer Policy: no-referrer-when-downgrade
Response Headers
access-control-allow-credentials: true
access-control-allow-headers: Content-Type, Authorization, X-Track, X-Super-Properties, X-Context-Properties, X-Failed-Requests, X-Fingerprint, X-RPC-Proxy, X-Debug-Options, x-client-trace-id, If-None-Match, X-RateLimit-Precision
access-control-allow-methods: POST, GET, PUT, PATCH, DELETE
access-control-allow-origin: <access-control-allow-origin>
access-control-expose-headers: Retry-After, X-RateLimit-Global, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-RateLimit-Bucket, Date
cf-cache-status: DYNAMIC
cf-ray: <cf-ray>
cf-request-id: <cf-request-id>
content-length: 58
content-type: application/json
date: Thu, 16 Jul 2020 04:23:41 GMT
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
set-cookie: __cfduid=<__cfduid>; expires=Sat, 15-Aug-20 04:23:40 GMT; path=/; domain=.discordapp.com; HttpOnly; SameSite=Lax
set-cookie: __cfruid=<__cfduid>; path=/; domain=.discordapp.com; HttpOnly; Secure; SameSite=None
status: 400
strict-transport-security: max-age=31536000; includeSubDomains
via: 1.1 google
x-envoy-upstream-service-time: 27
x-ratelimit-bucket: <x-ratelimit-bucket>
x-ratelimit-limit: 5
x-ratelimit-remaining: 4
x-ratelimit-reset: <x-ratelimit-reset>
x-ratelimit-reset-after: 2
Request Headers
:authority: discordapp.com
:method: POST
:path: /api/webhooks/<my discord webhook>
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: en,en-US;q=0.9,ja;q=0.8
content-length: 50696
content-type: multipart/form-data
origin: https://<origin>
referer: https://<referer>
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: cross-site
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Request Payload
------WebKitFormBoundarypu7GvABzASKKKTQF
Content-Disposition: form-data; name="payload_json"
{"username":"WhiteBoard","avatar_url":"https://i.imgur.com/ZGPxFN2.jpg","content":"another test 2","embeds":[{"image":{"url":"https://i.imgur.com/ZGPxFN2.jpg"}}]}
------WebKitFormBoundarypu7GvABzASKKKTQF
Content-Disposition: form-data; name="file"; filename="blob"
Content-Type: image/png
‰PNG
IHDRpíã IDAT[...]
[...]:cjIEND®B`‚
------WebKitFormBoundarypu7GvABzASKKKTQF--
-------- Edit (2020/07/16 14:30): Answering my secondary question myself --------
- why is the filename part in the request payload "blob"?
FormData.append()accepts a third parameter with the filename, my code should look like below:
formData.append('file',blob,filename);