discord/discord-api-docs

Apps Unable to Send Attachments with Special Characters

Opened this issue · 1 comments

Description

Overview

As the name suggests, apps unable to send attachments with special characters like users do. Even when utilizing URL encoding (e.g. %20 to space character), Discord treats them literally. As Discord expects similar name as with the URL, it's impossible to send attachments with special characters due to the block.

Steps to Reproduce

Request attachments from Discord apps with special characters.

Code snippet:

if (shouldMoveToAttachment) {
    const numPart = diffsToProcess.length > 1 ? `%20%28${diffsAttachedCount + 1}%29` : ''; // Should converts to ` (${diffsAttached Count + 1})`
    
    const filename = `%5B${sha.slice(0, 7)}%5D%20%40${author}%20-%20${commentId}${numPart}.txt`; // Should converts to `[${sha.slice(0, 7)}] @${author} - ${commentId}${numPart}.txt`
      
    files.push(new AttachmentBuilder(Buffer.from(diff.content, 'utf8'), { name: filename }));
    comps.push({ type: 13, file: { url: `attachment://${filename}`, name: filename } });
    
    trimmed = trimmed.replace(diff.fullMatch, '');
    diffsAttachedCount++;
}

Same issue will be replicated if done by normally inputting the characters:

if (shouldMoveToAttachment) {
    const numPart = diffsToProcess.length > 1 ? ` (${diffsAttachedCount + 1})` : '';
    
    const filename = `[${sha.slice(0, 7)}] @${author} - ${commentId}${numPart}.txt`;
      
    files.push(new AttachmentBuilder(Buffer.from(diff.content, 'utf8'), { name: filename }));
    comps.push({ type: 13, file: { url: `attachment://${filename}`, name: filename } });
    
    trimmed = trimmed.replace(diff.fullMatch, '');
    diffsAttachedCount++;
}

or raw unicodes:

if (shouldMoveToAttachment) {
    const numPart = diffsToProcess.length > 1 ? `\u0020\u0028${diffsAttachedCount + 1}\u0029` : ''; // Converts to ` (${diffsAttached Count + 1})`
    
    const filename = `\u005B${sha.slice(0, 7)}\u005D\u0020\u0040${author}\u0020\u002D\u0020${commentId}${numPart}.txt`; // Converts to `[${sha.slice(0, 7)}] @${author} - ${commentId}${numPart}.txt`
      
    files.push(new AttachmentBuilder(Buffer.from(diff.content, 'utf8'), { name: filename }));
    comps.push({ type: 13, file: { url: `attachment://${filename}`, name: filename } });
    
    trimmed = trimmed.replace(diff.fullMatch, '');
    diffsAttachedCount++;
}

Expected Behavior

[This is an example]
it'll prompt the title property1 for the display name keeping the original name intact with the sanitized filename1 and URL
Image

Current Behavior

Printed error:

Failed to send preview: DiscordAPIError[50035]: Invalid Form Body
components[0].components[4].file.url[UNFURLED_MEDIA_ITEM_REFERENCED_ATTACHMENT_NOT_FOUND]: The referenced attachment ("attachment://%5Befbe7bd%5D%20%40aamiaa%20-%20166533405.txt") was not found
    at handleErrors (/home/container/node_modules/@discordjs/rest/dist/index.js:762:13)
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
    at async SequentialHandler.runRequest (/home/container/node_modules/@discordjs/rest/dist/index.js:1163:23)
    at async SequentialHandler.queueRequest (/home/container/node_modules/@discordjs/rest/dist/index.js:994:14)
    at async _REST.request (/home/container/node_modules/@discordjs/rest/dist/index.js:1307:22)
    at async InteractionWebhook.editMessage (/home/container/node_modules/discord.js/src/structures/Webhook.js:351:15)
    at async ChatInputCommandInteraction.editReply (/home/container/node_modules/discord.js/src/structures/interfaces/InteractionResponses.js:254:17)
    at async Object.execute (file:///home/container/root/dist/Commands/send.js:181:17)
    at async Client.<anonymous> (file:///home/container/root/dist/bot.js:159:17) {
  requestBody: {
    files: [ [Object] ],
    json: {
      content: undefined,
      tts: false,
      nonce: undefined,
      enforce_nonce: false,
      embeds: undefined,
      components: [Array],
      username: undefined,
      avatar_url: undefined,
      allowed_mentions: undefined,
      flags: 32768,
      message_reference: undefined,
      attachments: [Array],
      sticker_ids: undefined,
      thread_name: undefined,
      applied_tags: undefined,
      poll: undefined
    }
  },
  rawError: {
    message: 'Invalid Form Body',
    code: 50035,
    errors: { components: [Object] }
  },
  code: 50035,
  status: 400,
  method: 'PATCH',
  url: 'https://discord.com/api/v10/webhooks/1304080954801000458/aW50ZXJhY3Rpb246MTQyMTc3MTY5MzcxMzc4ODk0ODpTVU1yOFhBaDR4UldSSGJEeWpLTmlOWmxHQ011YW42c2ZvSGJPbTM4TVFMSWFFNFVEOGRWWXUxOFQ3SzNXeUVjYVZBbWJvME5wQjhUNVVtS2pMTkpDSGlEbVRkMXVEYU1zMm0yNVVRZjlWNHdkY0V0c3RIZTAwMklKTzNQUGtoYg/messages/%40original'
}

Screenshots/Videos

No response

Client and System Information

Used Library: discord.js@14.23.2

Note

Using any libraries would result in the same behaviour as this issue stems directly from the Discord API.

Footnotes

  1. https://discord.com/developers/docs/resources/message#attachment-object 2

Pretty sure this is expected as it's documented at Uploading Files:

[...] Images can also be referenced [...] using the attachment://filename URL. The filename for these URLs must be ASCII alphanumeric with underscores, dashes, or dots. [...]

Also in the spec linked below that.