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.
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
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.
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");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.
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));
});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.
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
5:42
24:16
33:42
41:18
28:05
3:12