Skip to content

Sending Files

Sending files in Discord requires two things to be present in your request: the binary file data (sent as multipart form fields) and the attachment metadata (sent as JSON). The AttachmentBuilder class handles both for you.

Use AttachmentBuilder to describe a file you want to send. It accepts any Buffer, Uint8Array, string, or Stream as the file data.

import { AttachmentBuilder } from "honocord";
const attachment = new AttachmentBuilder(Buffer.from("Hello, world!"), {
name: "hello.txt",
description: "A simple text file",
});

Use the fluent builder methods to configure the attachment:

MethodDescription
.setName(name)Sets the filename shown in Discord
.setDescription(desc)Sets the alt-text / description
.setContentType(type)Overrides the MIME type (e.g. "application/json")
.setSpoiler(true)Prefixes the filename with SPOILER_

Pass your AttachmentBuilder instance(s) directly into the files field of any response method. reply, editReply, followUp, and update all accept it.

await ctx.reply({
content: "Here is your file!",
files: [
new AttachmentBuilder(Buffer.from(data), { name: "output.txt" }),
],
});

Once a file is attached, you can reference it inside an embed using the attachment://filename URI scheme. This is useful for embed thumbnails or images.

await ctx.reply({
embeds: [
{
title: "Preview",
image: { url: "attachment://chart.png" },
},
],
files: [new AttachmentBuilder(imageBuffer, { name: "chart.png" })],
});

Call .setSpoiler() to hide the file behind a spoiler warning in Discord. This prefixes the filename with SPOILER_ automatically.

const attachment = new AttachmentBuilder(imageBuffer, { name: "surprise.png" }).setSpoiler();
// attachment name is now "SPOILER_surprise.png"

Since v2.0.0 you can use the re-exported REST class (from @discordjs/rest) to send messages with attachments. If you need to post a message directly via the REST client rather than through an interaction method, use AttachmentBuilder.resolve() to split your builders into the files and attachments arrays that the REST client expects.

  1. Build your attachments as normal.

    const builders = [
    new AttachmentBuilder(Buffer.from(data), { name: "report.txt" }),
    ];
  2. Resolve them into the two separate arrays.

    const { files, attachments } = AttachmentBuilder.resolve(builders);
  3. Pass files as a top-level REST option and attachments inside body.

    await rest.post(`/channels/${channelId}/messages`, {
    body: {
    content: "Here is your report!",
    attachments,
    },
    files,
    });

Since v2.0.0 you can also use the API class to send messages with attachments. This class is re-exported from @discordjs/core/http-only and provides a higher-level interface over the REST client.

import { REST, API, AttachmentBuilder } from "honocord";
const rest = new REST().setToken("your-bot-token");
const api = new API(rest);
await api.channels.createMessage(channelId, {
content: "Here is your file!",
...new AttachmentBuilder(Buffer.from(data), { name: "report.txt" }).resolve(),
});