> ## 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.

# Interaction

> Someone used something of the bot and waits for an answer: reply, defer, edit, follow up

An `Interaction` is what you answer with: the `interaction` of a [command](https://www.chapterjs.org/commands.md) is a `CommandInteraction`, the one of a [button or a menu](https://www.chapterjs.org/components.md) a `ComponentInteraction`, the one of a [form](https://www.chapterjs.org/components/modals.md) a `ModalInteraction`. Discord wants a first answer within 3 seconds, and accepts edits and other messages for 15 minutes.

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

export async function deny(interaction: CommandInteraction, why: string) {
  // Only the person sees it, whatever the command says.
  await interaction.reply({ content: `Sorry: ${why}`, ephemeral: true });
}
```

> [!NOTE]
>
> You never create an interaction: your `run` function receives one. This page lists everything it has; how to answer well (when to defer, ephemeral answers, what happens when `run` throws) is in [Answering](https://www.chapterjs.org/commands/answering.md).

## Properties

**id** `Snowflake`

The unique id Discord gave it.

**createdAt** `Date`

When it was created: a Discord id contains its creation date.

**user** `User`

Who did it.

**guildId** `Snowflake | null`

The id of the server; `null` in a private message.

**channelId** `Snowflake`

The id of the channel it happened in.

**guild** `Guild | null`

The server it happened in; `null` in a private message.

**channel** `TextBasedChannel`

The channel it happened in: Discord sends it with the interaction.

**member** `GuildMember | null`

Who did it, as a member of the server; `null` in a private message.

**locale** `Locale`

The language of the person: use it to answer in their language.

**answered** `boolean`

Whether an answer was sent, or promised with `defer()`.

**deferred** `boolean`

Whether `defer()` was called and the answer is still to come. Also `true` after `deferUpdate()`, until `update()` or `reply()` completes it.

### CommandInteraction

Someone used a slash command. It has everything above, plus:

**commandName** `string`

The command as the person typed it: `/mod ban`.

And one more action, [`showModal()`](#showmodal).

### ComponentInteraction

Someone clicked a button or picked something in a select menu of a message of the bot. It can answer like a command, or change the message the component is on. It has everything of `Interaction`, plus:

**message** `Message`

The message the component is on.

And three more actions: [`update()`](#update), [`deferUpdate()`](#deferupdate) and [`showModal()`](#showmodal).

[Discord documentation](https://docs.discord.com/developers/interactions/receiving-and-responding#interaction-object-message-component-data-structure)

### ModalInteraction

Someone sent a form of the bot. It can answer like a command; when a button or a menu opened the form, it can also change their message. It has everything of `Interaction`, plus:

**message** `Message | null`

The message whose button or menu opened the form; `null` when a command did.

And two more actions: [`update()`](#update) and [`deferUpdate()`](#deferupdate), which throw when `message` is `null`: "This form was opened by a command, not by a button or a menu: there is no message to change. Use interaction.reply()."

[Discord documentation](https://docs.discord.com/developers/interactions/receiving-and-responding#interaction-object-modal-submit-data-structure)

### In a server, in private

What a command receives is more precise than `CommandInteraction`, and follows the `where` of the command. The same holds for components, with the [`InGuild`, `InPrivate` and `InDm`](https://www.chapterjs.org/reference/button#inguild-inprivate-indm) types.

| Type | For | What changes |
| - | - | - |
| `GuildCommandInteraction` | A slash command used in a server: what a command receives by default (`where: 'guild'`). Discord sends the server, the member and the channel with it. | `guildId` is a `Snowflake`, `guild` is a `Guild`, `member` is a `GuildMember`, `channel` is a `GuildTextBasedChannel` |
| `DmCommandInteraction` | A slash command that is only used in private messages with the bot (`where: 'dm'`): nothing about a server exists on it. | `guildId`, `guild` and `member` do not exist; `channel` is a `DMChannel` |
| `PrivateCommandInteraction` | A slash command used in a private message with the bot, for a command that works in both places (`where: 'both'`): there is no server, which is how it is told apart from `GuildCommandInteraction`. | `guildId`, `guild` and `member` are `null`; `channel` is a `DMChannel` |

With `where: 'both'`, `run` receives `GuildCommandInteraction | PrivateCommandInteraction`: one `if (interaction.guild)` narrows everything.

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

## Helpers

### toJSON()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
toJSON(): object
```

The data of the interaction, without its token: a token is a secret. `console.log(interaction)` never shows it either.

## Actions

Answers are sent one after the other, in the order they were asked: you can call `reply()` and `followUp()` without waiting for the first to finish.

### reply()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
reply(message: InteractionReply): Promise<Message>
```

Answers. If `defer()` was called (by you, or by the framework because the answer was taking long), this completes the pending answer.

Throws when the interaction was already answered: "This interaction was already answered. Use interaction.followUp() to send another message, or interaction.edit() to change the answer."

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

### defer()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
defer(options?: { ephemeral?: boolean }): Promise<void>
```

Tells Discord the answer is coming: the person sees "thinking…" and `reply()` can then take up to 15 minutes. The framework does it by itself when an answer takes long; call it yourself to choose when.

Does nothing when the interaction was already answered or deferred. Whether the answer is ephemeral is decided here: without `ephemeral`, it is what the command says.

### update()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
update(message: string | MessageEditOptions): Promise<Message>
```

On a `ComponentInteraction` and a `ModalInteraction`. Changes the message the component is on, as the answer: its text, its embeds, its components, its files. Only what you pass changes; `components: []` removes the buttons and menus.

Throws when the interaction was already answered with a message or deferred with `defer()`: "This interaction was already answered: the message can no longer be changed through it. Use interaction.message.edit() to change the message, or interaction.followUp() to send another one."

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

### deferUpdate()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
deferUpdate(): Promise<void>
```

On a `ComponentInteraction` and a `ModalInteraction`. Tells Discord the message will change later: the person sees nothing meanwhile, and `update()` can then take up to 15 minutes. The framework does it by itself when an answer to a component takes long.

After `deferUpdate()`, `reply()` sends its message as a follow-up, which looks the same to the person, and `edit()` changes the message of the component.

### showModal()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
showModal(form: ModalComponent): Promise<void>
```

On a `CommandInteraction` and a `ComponentInteraction`. Opens a form, as the answer: `showModal(report({ userId }))`, with a form declared with `modal()`. It must be the first answer, and the person has as long as they want to fill it in.

Throws when something was already answered: "A form can only be the first answer to an interaction: call interaction.showModal() before reply() or defer(), and the framework waits for it."

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

### edit()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
edit(message: string | MessageEditOptions): Promise<Message>
```

Changes the answer. It takes a text, or [MessageEditOptions](https://www.chapterjs.org/reference/message-options.md#messageeditoptions).

Throws when there is no answer yet: "There is no answer to edit yet: call interaction.reply() first."

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

### followUp()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
followUp(message: InteractionReply): Promise<Message>
```

Sends another message, after the answer.

Throws when there is no answer yet: "A follow-up comes after an answer: call interaction.reply() first."

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

### delete()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
delete(): Promise<void>
```

Deletes the answer.

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

## Types

### InteractionReply

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
InteractionReply = string | InteractionReplyOptions
```

An answer to an interaction: its text, or its options. What `reply()` and `followUp()` take.

### InteractionReplyOptions

The options of an answer: everything a message takes, except `replyTo` and `stickers`, plus `ephemeral`. It is listed in [InteractionReplyOptions](https://www.chapterjs.org/reference/message-options.md#interactionreplyoptions).

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

export async function report(interaction: CommandInteraction, lines: string[]) {
  await interaction.reply({
    embeds: [{ title: 'Report', description: lines.join('\n') }],
    files: [{ name: 'report.txt', data: lines.join('\n') }],
    ephemeral: true,
  });
}
```


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