interaction.reply() answered with a text. This page is about everything else an answer can be: private, delayed, changed, followed by another. And about the one case you will meet sooner or later: your code throws, and someone is waiting on the other side.
One answer, then follow-ups
A use of a command gets one answer, withreply(). After that, followUp() sends another message, edit() changes the answer, and delete() removes it. Here is the whole set:
Calling
reply() twice is a mistake, and the framework says so with the line and what to do instead:
content, embeds, files, components… A later page goes through all of it.
Private answers
Sometimes only the person should see the answer: a confirmation, an error, a secret. Passephemeral: true, and Discord shows the message to them alone, with a “Only you can see this” note and a way to dismiss it.
src/commands/secret-number.ts
ephemeral: true on the command itself instead of on each call. It also tells the framework, before run even starts, that whatever it sends for this command is for the person alone, which matters for the language of the answer in a later chapter.
src/commands/mynumber.ts
When the answer takes time
Discord wants an answer within 3 seconds, or it tells the person “The application did not respond”. A request to another website, a big computation, or a few requests to Discord in a row can take longer than that. You don’t have to care. After 2 seconds without an answer, the framework tells Discord the answer is coming: the person sees “thinking…”, and yourreply() completes it when it arrives, up to 15 minutes later.
src/commands/slow.ts
/slow: after two seconds, “thinking…”, then the answer. If you would rather show “thinking…” right away, call interaction.defer() yourself at the start of run.
Whether a delayed answer is private is decided when it is deferred. For a slow command whose answer must be private, put
ephemeral: true on the command, or call interaction.defer({ ephemeral: true }) yourself: by the time the framework defers for you, it only knows what the command declares.Changing the answer
edit() changes the answer that was sent. Only what you pass changes:
src/commands/countdown3.ts
edit() and delete() work for 15 minutes after the command was used; after that, Discord forgets the interaction.
When your code fails
Your code will throw one day: a bug, or Discord refusing something. What happens then is worth knowing, because someone is waiting in Discord.- The person gets a short, private answer: “Something went wrong while running this command.” If the bot lacked a permission, the phrase says so instead: “I don’t have the permission to do that here.” Never a stack trace, never a technical word.
- You get the error in your terminal, with the file and the line:
- The bot keeps running. One failing command never stops anything else.
throw new Error('oops') at the top of run in /dice, save, and use the command. Then remove it.
To handle a failure yourself, wrap the risky part in try / catch. Errors from Discord are DiscordApiError, with a code that says what happened; the page What you receive shows one.
Recap
reply()once, thenfollowUp(),edit(),delete().ephemeral: truemakes a message private; on the command, it makes every answer private.- After 2 seconds, the framework defers for you;
defer()does it at once. - When
runthrows, the person gets a plain answer, you get the file and the line, the bot goes on.
What you receive
Users, members, servers, channels: what they tell you and what they can do.
Guide: Answering
The same, in short.