> ## Documentation Index
> Fetch the complete documentation index at: https://www.chapterjs.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Message options

> Everything a message can contain when you send, reply, edit, answer a command or post with a webhook

`channel.send()`, `message.reply()`, `user.send()`, `member.send()` and the first message of `forum.createPost()` take a `MessageInput`: a text, or a `MessageOptions` object. `interaction.reply()` and `webhook.send()` take the same options with a few changes, listed at the end.

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
import type { TextChannel } from 'chapterjs';

async function example(channel: TextChannel) {
  await channel.send('Hello!');
  await channel.send({
    content: 'Here is the report',
    embeds: [{ title: 'Weekly report', description: 'Everything went well.' }],
    files: [{ name: 'report.txt', data: 'The full report' }],
    silent: true,
  });
}
```

> [!NOTE]
>
> How to use all of this is in [Sending messages](https://www.chapterjs.org/messages.md). The messages you receive are described in [Message](https://www.chapterjs.org/reference/message.md).

## MessageInput

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
type MessageInput = string | MessageOptions
```

A message to send: its text, or its options.

## MessageOptions

What a message can contain, and how it is sent. A message needs at least a content, an embed, a file, a component, a sticker or a poll.

**content** `string`

The text of the message (up to 2000 characters).

**embeds** `(Embed | EmbedDeclaration\<[]\>)[]`

Up to 10 embeds: written here, or declared with `embed()`. See [Embed](#embed) and [embed()](https://www.chapterjs.org/reference/embed.md).

**components** `MessageComponent[]`

Buttons, select menus and layout components, made by ChapterJS: components declared with `button()`, `select()`... and `row()`, `text()`, `container()`... See [Components](#components).

**files** `(FileInput | AssetFile)[]`

Up to 10 files to attach: their content, or `asset()` for a file of `public/`. See [FileInput](#fileinput) and [asset()](#asset).

**allowedMentions** `AllowedMentions`

Who the message is allowed to notify. See [AllowedMentions](#allowedmentions).

**stickers** `Snowflake[]`

The ids of up to 3 stickers of the server.

**poll** `PollInput`

A poll to attach to the message. See [PollInput](#pollinput).

**tts** `boolean`

Reads the message aloud.

**silent** `boolean`

Sends the message without a notification sound.

**suppressEmbeds** `boolean`

Does not show the previews of the links of the message.

**replyTo** `Snowflake | \{ id: Snowflake \}`

The message to reply to.

[Discord documentation](https://docs.discord.com/developers/resources/message#create-message)

## MessageEditOptions

What can be changed in a message that was already sent: `message.edit()` takes a text, or these fields of `MessageOptions`. Only what you pass changes: an empty list removes the embeds or the components, and the files you pass replace the ones of the message.

**content** `string`

The text of the message (up to 2000 characters).

**embeds** `(Embed | EmbedDeclaration\<[]\>)[]`

Up to 10 embeds: written here, or declared with `embed()`.

**components** `MessageComponent[]`

Buttons, select menus and layout components, made by ChapterJS: components declared with `button()`, `select()`... and `row()`, `text()`, `container()`...

**files** `(FileInput | AssetFile)[]`

Up to 10 files to attach: their content, or `asset()` for a file of `public/`.

**allowedMentions** `AllowedMentions`

Who the message is allowed to notify.

**suppressEmbeds** `boolean`

Does not show the previews of the links of the message. `false` shows them again.

[Discord documentation](https://docs.discord.com/developers/resources/message#edit-message)

## FileInput

A file to attach to a message. Each file is sent with the message, and an embed can show it with `attachment://<name>` as the `url` of its `image` or `thumbnail`.

**name** `string` *required*

The name of the file, with its extension: `chart.png`.

**data** `Blob | Uint8Array | ArrayBuffer | string` *required*

The content of the file.

**description** `string`

What the file shows, for people who can't see it.

**spoiler** `boolean`

Hides the file until it is clicked.

**contentType** `string`

The media type of the file (`image/png`); guessed from the name when missing.

[Discord documentation](https://docs.discord.com/developers/reference#uploading-files)

## asset()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
asset(path: PublicFile, options?: AssetOptions): AssetFile
```

A file of the `public/` folder of the project, to send with a message: `files: [asset('photos/monday.png')]`. The file is read when the message is sent, so a missing file is an error there.

`asset` is imported from `'chapterjs'` like everything else, and typed for your project by the `.chapterjs/` folder: `PublicFile` is the union of the paths of every file of `public/`, so the editor lists them and underlines one that does not exist. The folder is read again by `chapterjs dev` every time a file is added or removed, and by `chapterjs sync` and `chapterjs build`. How to use it is in [Files](https://www.chapterjs.org/messages.md#files).

### PublicFile

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
type PublicFile = 'logo.png' | 'photos/monday.png' | ...
```

A file of the `public/` folder of your project, as a path from it: `'photos/monday.png'`. `never` while the folder is empty or missing.

### AssetOptions

What can change about a file of `public/` when it is sent.

**name** `string`

The name the file is sent under; by default its own name.

**description** `string`

What the file shows, for people who can't see it.

**spoiler** `boolean`

Hides the file until it is clicked.

**contentType** `string`

The media type of the file (`image/png`); guessed from the name when missing.

### AssetFile

A file of the `public/` folder of the project, made by `asset()`, to put in the `files` of a message. It is read when the message is sent.

**name** `string` *required*

The name the file is sent under, with its extension.

**path** `string` *required*

The path of the file inside `public/`.

**description** `string`

What the file shows, for people who can't see it.

**spoiler** `boolean`

Hides the file until it is clicked.

**contentType** `string`

The media type of the file; guessed from the name when missing.

## Embed

A rich box in a message: title, description, fields, image... The same type describes the `embeds` of a message you receive: the fields marked "Set by Discord" are filled in the messages Discord sends back, and ignored when you send one.

**title** `string`

The title of the embed (256 characters at most).

**description** `string`

The text of the embed (4096 characters at most).

**url** `string`

The link the title opens.

**timestamp** `string`

A date shown in the footer, as an ISO 8601 text: `new Date().toISOString()`.

**color** `number`

The color of the left border, as a number: `0x5865f2`.

**footer** `EmbedFooter`

The footer of the embed.

**EmbedFooter**

**text** `string` *required*

The text of the footer (2048 characters at most).

**iconUrl** `string`

The URL of the icon of the footer (only `http(s)` and `attachment://` links).

**proxyIconUrl** `string`

Set by Discord: a proxied URL of the icon.

**image** `EmbedImage`

The large image of the embed.

**EmbedImage**

**url** `string` *required*

The URL of the image (only `http(s)` and `attachment://` links).

**description** `string`

What the image shows, for people who can't see it.

**proxyUrl** `string`

Set by Discord: a proxied URL of the image.

**height** `number`

Set by Discord: the height of the image.

**width** `number`

Set by Discord: the width of the image.

**contentType** `string`

Set by Discord: the media type of the image.

**placeholder** `string`

Set by Discord: a thumbhash placeholder of the image.

**placeholderVersion** `number`

Set by Discord: the version of the placeholder.

**flags** `number`

Set by Discord: the media flags of the image, as a bitfield.

**thumbnail** `EmbedImage`

The small image in the top right corner. Same fields as `image`.

**author** `EmbedAuthor`

The author line, above the title.

**EmbedAuthor**

**name** `string` *required*

The name of the author (256 characters at most).

**url** `string`

The link the name opens (only `http(s)` links).

**iconUrl** `string`

The URL of the icon of the author (only `http(s)` and `attachment://` links).

**proxyIconUrl** `string`

Set by Discord: a proxied URL of the icon.

**fields** `EmbedField[]`

Up to 25 fields, shown under the description.

**EmbedField**

**name** `string` *required*

The name of the field (256 characters at most).

**value** `string` *required*

The value of the field (1024 characters at most).

**inline** `boolean`

Whether the field is shown next to the previous one instead of under it.

**type** `'rich' | 'image' | 'video' | 'gifv' | 'article' | 'link' | 'poll_result'`

Set by Discord: the kind of embed (always `'rich'` for the embeds a bot sends).

**video** `EmbedVideo`

Set by Discord: the video of an embed made from a link.

**EmbedVideo**

**url** `string`

The URL of the video.

**proxyUrl** `string`

A proxied URL of the video.

**height** `number`

The height of the video.

**width** `number`

The width of the video.

**contentType** `string`

The media type of the video.

**placeholder** `string`

A thumbhash placeholder of the video.

**placeholderVersion** `number`

The version of the placeholder.

**description** `string`

What the video shows, for people who can't see it.

**flags** `number`

The media flags of the video, as a bitfield.

**provider** `EmbedProvider`

Set by Discord: the site an embed made from a link comes from.

**EmbedProvider**

**name** `string`

The name of the site.

**url** `string`

The URL of the site.

**flags** `number`

Set by Discord: the flags of the embed, as a bitfield.

[Discord documentation](https://docs.discord.com/developers/resources/message#embed-object)

### Embed limits

| Limit | Maximum |
| - | - |
| Embeds per message | 10 |
| `title` | 256 characters |
| `description` | 4096 characters |
| `fields` | 25 |
| `fields[].name` | 256 characters |
| `fields[].value` | 1024 characters |
| `footer.text` | 2048 characters |
| `author.name` | 256 characters |
| All of the above, for every embed of a message | 6000 characters |

Going over one throws an error that names the field, before anything is sent: see [Limits and errors](#limits-and-errors).

## AllowedMentions

Who a message is allowed to notify. Without it, a message notifies everyone it mentions.

**parse** `('roles' | 'users' | 'everyone')[]`

The kinds of mentions of the text that notify: `[]` notifies nobody.

**roles** `Snowflake[]`

The ids of the roles to notify (100 at most).

**users** `Snowflake[]`

The ids of the users to notify (100 at most).

**repliedUser** `boolean`

For a reply, whether to notify the author of the message replied to. By default `false`.

[Discord documentation](https://docs.discord.com/developers/resources/message#allowed-mentions-object)

## PollInput

A poll to attach to a message.

**question** `PollMedia` *required*

The question of the poll. Only `text` is supported.

**PollMedia**

**text** `string`

The text.

**emoji** `\{ id?: Snowflake | null; name?: string | null \}`

The emoji: `{ name: '🍕' }` for a standard one, `{ id }` for a custom one.

**answers** `PollAnswer[]` *required*

Each of the answers available in the poll, up to 10.

**PollAnswer**

**pollMedia** `PollMedia` *required*

The text and the emoji of the answer: same fields as `question`.

**duration** `number`

How many hours the poll stays open, up to 32 days. By default 24.

**allowMultiselect** `boolean`

Whether a person can pick several answers. By default `false`.

**layoutType** `1`

The layout of the poll. There is only one: `1`, the default.

[Discord documentation](https://docs.discord.com/developers/resources/poll#poll-create-request-object)

## Components

`components` only takes what ChapterJS made: the buttons, menus and forms declared with `button()`, `select()` and `modal()`, and the layout helpers (`row()`, `linkButton()`, `text()`, `section()`, `container()`...). A plain object is refused before anything is sent, so no id is ever written by hand. Buttons that follow each other are put in rows of 5; a menu gets a row of its own.

A message with a text, a section, a gallery, a file, a separator or a container is built with components only: Discord shows no `content` and no `embeds`, and the message says so before leaving if you pass one. The pieces and their types are listed in [Layout](https://www.chapterjs.org/reference/layout.md); how to use them is in [Buttons](https://www.chapterjs.org/components.md) and [Embeds and layout](https://www.chapterjs.org/components/embeds.md).

[Discord documentation](https://docs.discord.com/developers/components/reference)

## InteractionReplyOptions

The options of an answer: everything a message takes, except `replyTo` and `stickers`. It is what `interaction.reply()` and `interaction.followUp()` take, as a text or as an object (`InteractionReply`); `interaction.edit()` takes a [`MessageEditOptions`](#messageeditoptions). See [Interaction](https://www.chapterjs.org/reference/interaction.md).

**ephemeral** `boolean`

Only show the answer to who used the command. By default: what the command says with its own `ephemeral`, else visible to everyone.

[Discord documentation](https://docs.discord.com/developers/interactions/receiving-and-responding#create-interaction-response)

## WebhookMessageOptions

What a message posted with a webhook can contain: everything a message takes, except `replyTo`, and these. It is what [`webhook.send()`](https://www.chapterjs.org/reference/webhook) takes, as a text or as an object.

**username** `string`

Shows this name instead of the name of the webhook.

**avatarURL** `string`

Shows this avatar instead of the avatar of the webhook.

**threadId** `Snowflake`

Sends the message in this thread of the channel of the webhook.

[Discord documentation](https://docs.discord.com/developers/resources/webhook#execute-webhook)

## Limits and errors

Every message is checked before it is sent, so a mistake is an error in your code with a plain message, not a refusal of Discord. The numbers are the ones of your message.

| What was wrong | The error |
| - | - |
| Not a text nor an object | `A message is a text or an object like { content: "Hello" }, got number.` |
| `content` is not a text | `The content of a message is a text, got number.` |
| `content` over 2000 characters | `The message is 2345 characters long: Discord accepts 2000 at most. Split it in several messages or put the text in a file.` |
| More than 10 embeds | `A message has 10 embeds at most, got 11.` |
| A text of an embed too long | `The title of embed 1 is 300 characters long: Discord accepts 256 at most.` (also `description`, `footer text`, `author name`, `name of field 3`, `value of field 3`) |
| More than 25 fields in an embed | `Embed 1 has 26 fields: Discord accepts 25 at most.` |
| The embeds over 6000 characters together | `The embeds of the message contain 6100 characters in total: Discord accepts 6000 at most.` |
| More than 3 stickers | `A message has 3 stickers at most, got 4.` |
| More than 10 files | `A message has 10 files at most, got 11.` |
| Nothing to send (when sending, not editing) | `The message is empty: give it a content, an embed, a file, a component, a sticker or a poll.` |
| A file without a name | `Every file needs a name with its extension, like "chart.png".` |

The text of an embed is counted without the spaces around it. What these checks don't cover (a wrong `customId`, an unknown sticker...) is refused by Discord with a [`DiscordApiError`](https://www.chapterjs.org/reference/errors#discordapierror) that says which field.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.