discord / discord-api-docs

Official Discord API Documentation
https://discord.com/developers/docs/intro
Other
5.95k stars 1.26k forks source link

`image/apng` is unsupported when uploading stickers #5390

Closed didinele closed 2 years ago

didinele commented 2 years ago

Description

Perhaps this would be better fitted as a feature request? I'm unsure, so I'll just go on ahead and flag this as an issue:

Using POST /guilds/guild.id/stickers with the type of the file set to image/apng yields a 400 with the error code 50046 - Invalid Asset.

For clarity, I do not mean the actual Content-Type header in the request - that is correctly set to multipart/form-data.

image/png works, so I'd generally not bother opening such an issue, but in the context of a library, we allow our users to pass in file data with no other metadata about it, in which case we rely on the magic bytes to infer its type. Our package of choice for inference, file-type yields image/apng for this sort of file.

User flagged issue in question: https://github.com/discordjs/discord.js/issues/8557

Steps to Reproduce

Unfortunately I can't think of an easy way to produce this with cURL when it comes to embedding the binary data into the request, so I'll be providing a very barebones node.js script using just undici to make the HTTP request.

mkdir content-type-repro cd content-type-repro npm init -y npm install undici touch index.js & copy the following into it:

const { Blob } = require('node:buffer');
const { FormData, request } = require('undici');
const { readFileSync } = require('node:fs');

const GUILD_ID = '<GUILD_ID>';
const BOT_TOKEN = '<SOME BOT TOKEN WITH PERMISSIOSN IN THE GIVEN GUILD>';
const PATH_TO_FILE = './path/to/some/animated/png';
const TYPE = 'image/apng';

async function main() {
    const content = readFileSync(PATH_TO_FILE);

    const formData = new FormData();
    formData.append('file', new Blob([content], { type: TYPE }), 'something');
    formData.append('name', 'test');
    formData.append('description', 'also a test');
    formData.append('tags', 'so much test');

    const { statusCode, body } = await request(`https://discord.com/api/v10/guilds/${GUILD_ID}/stickers`, {
        method: 'POST',
        headers: {
            authorization: `Bot ${BOT_TOKEN}`,
        },
        body: formData,
    });

    console.log(statusCode, await body.json());
}

main();

node index.js

Now, if we were to do the following:

- const TYPE = 'image/apng';
+ const TYPE = 'image/png';

The sticker would be created successfully.

Expected Behavior

The sticker is created successfully even with image/apng.

Current Behavior

The API returns a 400 with the following JSON body: 400 { message: 'Invalid Asset', code: 50046 }

Screenshots/Videos

No response

Client and System Information

This issue can be reproduced with discord.js 14.3.0 (@discordjs/rest 1.1.0) due to the described content-type inference we do.

My repro script uses undici 5.8.2 and node.js 16.11.0.

MinnDevelopment commented 2 years ago

I also opened a discussion related to this a while ago https://github.com/discord/discord-api-docs/discussions/4941

It would be better if the type is automatically determined by discord.

Mehgugs commented 2 years ago

image/apng is not a mime type sadly, which is an example of why #4941 should be implemented.