IntegrationsIntermediate

How to Add an /ask Slash Command That Calls AI in Discord

Register a global /ask slash command and deferred reply so AI answers feel native in Discord.

9 minIntermediate

Mentioning a bot works, but slash commands feel cleaner: members type /ask, get an autocompleted prompt field, and the answer appears as a proper bot reply. This guide registers a global /ask command and uses a deferred reply so the model has time to respond without Discord timing out.

What you need

  • A working Discord bot token and application ID
  • Node 18+ and the discord.js library installed
  • An AI API key
  • The applications.commands scope checked when you invited the bot
Three second deadline
Discord expects a reply within three seconds. Any AI call is slower than that, so you must call interaction.deferReply() first, then edit the reply when the model returns.

Step 1: Register the command

Slash commands are registered with Discord's REST API once, not on every startup. Create a deploy script that pushes the command definition. Global commands can take up to an hour to appear, so use a guild-scoped registration while testing.

deploy-commands.js
import "dotenv/config";
import { REST, Routes, SlashCommandBuilder } from "discord.js";

const commands = [
  new SlashCommandBuilder()
    .setName("ask")
    .setDescription("Ask the AI anything")
    .addStringOption((o) =>
      o.setName("prompt").setDescription("Your question").setRequired(true),
    )
    .toJSON(),
];

const rest = new REST().setToken(process.env.DISCORD_TOKEN);

await rest.put(
  Routes.applicationGuildCommands(
    process.env.APP_ID,
    process.env.GUILD_ID,
  ),
  { body: commands },
);
console.log("Registered /ask");
zsh - discord-ask
$node deploy-commands.js
Registered /ask
$

Step 2: Handle the interaction

In your main bot file, listen for InteractionCreate. Defer the reply immediately, run the AI call, then edit the original reply with the answer.

index.js
client.on(Events.InteractionCreate, async (i) => {
  if (!i.isChatInputCommand() || i.commandName !== "ask") return;

  await i.deferReply();
  const prompt = i.options.getString("prompt");

  const res = await ai.chat.completions.create({
    model: "gpt-5-mini",
    messages: [{ role: "user", content: prompt }],
  });

  await i.editReply(res.choices[0].message.content.slice(0, 1900));
});
Discord - typing a command
/ask prompt: explain DNS like I am five
------------------------------------------
/ask Ask the AI anything
prompt (required)
The command picker shows the description and the required prompt option.

Step 3: Test in your server

Restart the bot, type /ask in any channel, and fill in the prompt. You should see MyHelper is thinking... for a moment, then the answer replaces it.

#bot-playground
You
/ask explain DNS like I am five
Agent
DNS is the internet's phone book. You type a name, it finds the number (IP) so your computer knows where to go.
A deferred reply turns into the final answer.
Go global when ready
Swap applicationGuildCommands for applicationCommands to publish to every server your bot is in. Run the deploy script again after the change.

Result

Members now have a native /ask command with an autocompleted prompt field. Because it uses a deferred reply, longer model responses never trigger the dreaded This interaction failed error.

Watch related tutorials

Tags
#discord#slash-commands#bot#ai#node