Skip to content
GitHub

ResponseState

interface in meocord/common Since 4.1.0

interface ResponseState

How one interaction is answered: the single place its replies, edits and follow-ups go through.

Get it with respond(). Each call picks the right Discord method for where the answer stands. Calls made together run one after another, in the order they were made, so two send() calls at once reply, then edit.

Members

location

readonly location: InstallContext

Where the interaction happened, and whether the bot can reach the channel there.

state

readonly state: ResponsePhase

Where the answer stands, re-read from the interaction so answers made around this state count.

message

readonly message: Message | undefined

The message this state last replied with, updated or edited, never a follow-up, or the message a component is on. Read-only: edit through the state.

original

readonly original:
  | {
      readonly components: readonly unknown[]
      readonly embeds: readonly APIEmbed[]
    }
  | undefined

The components and embeds of the message before @Defer locked it; undefined until then.

acknowledge

acknowledge(options?: { ephemeral?: boolean }): Promise<void>

Acknowledges the interaction without answering it yet: a deferred reply for a command, and an invisible deferred update for a component or a modal from a message. Does nothing once answered, and concurrent calls share one acknowledgement. One that fails leaves the interaction unanswered, so the next answer replies.

Parameters

NameTypeDescription
options?{ ephemeral?: boolean }

ephemeral to make a command's deferred reply private.

options.ephemeral?boolean

Returns

Promise<void>

lock

lock(options?: ResponseLockOptions): Promise<void>

Locks the message a component is on, as @Defer's second step does: snapshots its components and embeds, disables its controls, shows the loading emoji on the clicked button, and adds the presenter's loading view. Commands have no message to lock. Does nothing once locked, or with disable: 'none'.

The loading view is left out when it would pass 10 embeds or the Components V2 component limit; the lock still applies. A loading view left behind by a crash or restart is dropped first.

Parameters

NameTypeDescription
options?ResponseLockOptions

Which controls to disable.

options.disable?'all' | 'clicked' | 'none'

Which controls to disable: every control on the message ('all', the default), only the one the user used ('clicked'), or none ('none'), which leaves the message as it is, with no loading view.

Returns

Promise<void>

send

send(
  payload: ResponsePayload,
  options?: ResponseSendOptions,
): Promise<Message | undefined>

Sends the answer: a reply to an unanswered command, an update of an unanswered component's message, and an edit once the interaction is deferred or replied. A second send() edits again. A reply Discord refuses as already acknowledged elsewhere still throws, and the next send() edits. After modal() it throws: a modal has no message, and the modal's submit is answered instead.

After @Defer locked a message, omitting components puts back its components as they were before the lock, and omitting embeds drops the loading view; components: [] clears them.

Parameters

NameTypeDescription
payloadResponsePayload

Text, or reply options.

options?ResponseSendOptions

fill: false leaves this message's embeds and containers uncoloured.

options.fill?boolean

Whether an embed with no colour and a Components V2 container with no accent take the theme's primary colour. Defaults to true; false sends this message's embeds and containers as written.

Returns

Promise<Message | undefined>

The message sent or edited, when Discord returns it.

edit

edit(
  payload: ResponseEditPayload,
  options?: ResponseSendOptions,
): Promise<Message | undefined>

Edits the answer, routed as send() is: an edit once the interaction is answered.

Parameters

NameTypeDescription
payloadResponseEditPayload

Text, or edit options.

options?ResponseSendOptions

fill: false leaves this edit's embeds and containers uncoloured.

options.fill?boolean

Whether an embed with no colour and a Components V2 container with no accent take the theme's primary colour. Defaults to true; false sends this message's embeds and containers as written.

Returns

Promise<Message | undefined>

The edited message, when Discord returns it.

followUp

followUp(
  payload: ResponsePayload,
  options?: ResponseSendOptions,
): Promise<Message | undefined>

Sends another message after the answer. Before any answer it is the first reply. While a command's reply is deferred and nothing is sent yet, Discord turns a follow-up into the deferred reply and ignores its flags, so it is sent as that edit; a private follow-up on a public deferral deletes the deferral first and is sent privately. After modal() it is sent as made, and Discord decides whether it accepts a follow-up there; the modal's submit is the interaction to answer.

Parameters

NameTypeDescription
payloadResponsePayload

Text, or reply options; Ephemeral makes the follow-up private.

options?ResponseSendOptions

fill: false leaves this follow-up's embeds and containers uncoloured.

options.fill?boolean

Whether an embed with no colour and a Components V2 container with no accent take the theme's primary colour. Defaults to true; false sends this message's embeds and containers as written.

Returns

Promise<Message | undefined>

The message sent, when Discord returns it.

delete

delete(): Promise<void>

Deletes the answer: the reply, or for a component deferred without a reply of its own, its message. Throws before any answer, and after modal(), which leaves no message.

Returns

Promise<void>
modal(
  modal:
    | JSONEncodable<APIModalInteractionResponseCallbackData>
    | ModalComponentData,
): Promise<void>

Shows a modal. A modal must be the interaction's first response, so this throws once the interaction is acknowledged, or while another answer is in flight, rather than failing at Discord. What the user enters arrives as a modal submit interaction, which is answered in its own right.

Parameters

NameTypeDescription
modal| JSONEncodable<APIModalInteractionResponseCallbackData> | ModalComponentData

The modal to show.

Returns

Promise<void>

error

error(error: unknown, options?: ResponseErrorOptions): Promise<void>

Presents an error, styled by the application's presenter, and never throws. A delivery Discord refuses for what it reports, such as a missing permission, is logged at debug level; one whose body Discord could not read, a presenter that fails, or any other failure, as an error.

  • Unanswered: a private reply.
  • A command whose reply is deferred: 'reply' edits that reply into the error; 'private' edits a private deferral into it, and deletes a public one, then follows up privately.
  • A component on a private (ephemeral) message: the error is added to that message, where it fits.
  • Otherwise: a private follow-up. The message the user clicked is never edited into the error, only put back as it was before a lock.

A UserError shows its own message, privately, unless options say otherwise.

Parameters

NameTypeDescription
errorunknown

The error, handed to the presenter so it can style it by kind.

options?ResponseErrorOptions

What the user is told, and who sees it.

options.message?string

What the user is told. Defaults to a UserError's own message, or a generic sentence.

options.visibility?'reply' | 'private'

'reply' (default) may turn a public deferred reply into the error; 'private' (the default for a UserError) never shows it to anyone but the user who made the call.

Returns

Promise<void>