setTitle
Parameters
setTitle(title: string)— The main headline of the embed.- Limit: Max 256 characters.
Visual Location
Appears at the very top of the embed in large, bold text.
const { MessageFlags, EmbedBuilder } = require("discord.js");
client.once(Events.ClientReady, async c => { console.log(`Logged in as ${c.user.username}`);
const help = new SlashCommandBuilder() .setName('help') .setDescription('Replies with an help embed.') .setContexts(InteractionContextType.Guild) .setIntegrationTypes(ApplicationIntegrationType.GuildInstall);
await client.application.commands.create(help, "GUILD_ID");});
client.on(Events.InteractionCreate, async interaction => { if(!interaction.isChatInputCommand()) return;
if(interaction.commandName === "ping"){ await interaction.reply("Pong!"); } else if(interaction.commandName === "help"){ const user = interaction.user; const avatarURL = user.displayAvatarURL();
const embed = new EmbedBuilder() .setColor("Green") .setTitle('Server Help & Command List') .setURL('https://development.goldendev.net') .setAuthor({ name: 'Tutorial Bot Support', iconURL: avatarURL, url: 'https://development.goldendev.net' }) .setDescription('Welcome to the help menu!') .addFields( { name: '/ping', value: 'Replies with "Pong!"' }, { name: '/message', value: 'Send a message addressed to someone in a specific channel.' }, { name: 'ℹ/help', value: 'Replies with an help embed.' }, { name: 'Support', value: '[Get Help](https://development.goldendev.net)', inline: true }, { name: 'Website', value: '[Visit Site](https://development.goldendev.net)', inline: true }, { name: 'Version', value: 'v1.0.0', inline: true }, ) .setThumbnail(avatarURL) .setImage(avatarURL) .setTimestamp() .setFooter({ text: 'Generated by Tutorial Bot', iconURL: avatarURL });
await interaction.reply({ embeds: [ embed ], flags: [ MessageFlags.Ephemeral ] }); }});{ "token": "YOUR_BOT_TOKEN"}setTitle
setTitle(title: string) — The main headline of the embed.Appears at the very top of the embed in large, bold text.
setDescription
setDescription(description: string) — The main body content.Appears just below the title. Supports Markdown (bold, italics, links, code blocks).
setURL
setURL(url: string) — A valid http/https link.Turns the Title into a clickable blue hyperlink.
setColor
setColor(color: ColorResolvable) — Hex code, integer, or string.0x0099FF, 'Red', '#FFFFFF'.The vertical colored strip on the left side of the embed.
setAuthor
Accepts an object: { name, iconURL, url }
name: string — The name of the author (max 256 chars).iconURL?: string — Small circular image to the left of the name.url?: string — Makes the author name clickable.Appears at the very top, above the Title, in smaller text.
setThumbnail
setThumbnail(url: string) — URL to an image file.A small, square image displayed in the top-right corner of the embed.
addFields
Accepts a comma-separated list or array of objects:
name: string — The field title (max 256 chars).value: string — The field text (max 1024 chars).inline?: boolean — If true, fields will stack side-by-side.Displayed in blocks below the Description but above the Image. Great for key-value data.
setImage
setImage(url: string) — URL to a large image file.A large image displayed at the bottom of the embed content (full width).
setFooter
Accepts an object: { text, iconURL }
text: string — Footer text (max 2048 chars).iconURL?: string — Small circular image to the left of the text.Very small text at the absolute bottom of the card.
setTimestamp
setTimestamp(date?: Date | number).setTimestamp() to use the current time.Appears to the right of the Footer text. Discord automatically converts this to the user’s local timezone.
If when running npm init -y you get an error something along the lines of:
npm : The term 'npm' is not recognized as the name of a cmdlet, function,script file, or operable program. Check the spelling of the name, or if apath was included, verify that the path is correct and try again.Open Windows PowerShell as Administrator.
Set the Execution Policy
In the PowerShell window, run:
Set-ExecutionPolicy RemoteSigned -Scope LocalMachinePowerShell will ask how you want to apply the change.
Choose [A] Yes to All
Type A and press Enter.
This updates a Windows security setting that can otherwise prevent tools like Node.js from running properly.
If you are trying to get the ID of a channel, user, or role but you don’t see the Copy User/Channel ID option when you right-click, it is because you do not have Developer Mode enabled.
Open User Settings
Navigate to Advanced Settings
Enable Developer Mode
Retrieve your ID
If your slash commands are appearing in Direct Messages or in servers where your bot hasn’t actually been added, it means your command configuration is missing specific context and integration limits. You need to explicitly restrict them to Guilds only.
const { SlashCommandBuilder, InteractionContextType, ApplicationIntegrationType } = require("discord.js")
new SlashCommandBuilder() .setName('ping') .setDescription('Replies with Pong!') .setContexts(InteractionContextType.Guild) .setIntegrationTypes(ApplicationIntegrationType.GuildInstall)Locate your Command Builder
Open the file where you define your SlashCommandBuilder. You need to chain two specific methods to your command definition.
Set the Contexts
Add .setContexts(InteractionContextType.Guild).
This ensures the command can only be executed inside a server (Guild) and disables it within Direct Messages (DMs).
Set the Integration Types
Add .setIntegrationTypes(ApplicationIntegrationType.GuildInstall).
This ensures the command is associated with the Guild installation of the bot, rather than being installed to the user’s personal profile.
Your Discord bot lives inside of your terminal, hence if you stop running it, close the application running it, or turn off your computer the bot will stop working.
To stop any running processing inside of your terminal click somewhere inside of the terminal, then press CTRL + C to stop the current process.
If you encounter the error Interaction has already been acknowledged or InteractionAlreadyReplied, and you are certain your code does not contain duplicate reply() or deferReply() calls, it almost always means your bot is running in two places at once.
Both instances receive the command. The “zombie” instance replies first, so when your local code tries to reply a millisecond later, Discord rejects it because the interaction is already “done.”
Option A: Hunt down the process Check your task manager, other terminal tabs, or your hosting dashboard. If you find the extra running instance, kill the process.
Option B: The “Nuclear” Option (Reset Token) If you cannot find where the other bot is running, you can force it to disconnect by invalidating its credentials.
.env or config.json file with the new token.This will immediately disconnect any “ghost” processes because their old token is no longer valid.
Spelling mistakes can be hard to catch and really annoying, it might be worth looking into a Code Spell Checker Extension. While I don’t formally recommend any particular extension this is the one I personally use at this time.
The error message “The application did not respond” usually means your bot crashed or failed to acknowledge the interaction within the required 3-second timeout.
| Question | Troubleshoot | Fix |
|---|---|---|
| Is the bot online? | Check the member list in your Discord server. If the bot appears offline, the host or runtime likely crashed. | Restart the bot process and review your logs for errors such as unhandled exceptions or failed imports. |
| Did your command handler crash? | Look at your terminal/hosting logs after running the command. If there is a thrown error, the bot may stop midway and never reply. | Wrap code in try/catch, validate all inputs, and avoid assuming properties like interaction.options always exist. |
| Did you reply within 3 seconds? | Discord requires interaction.reply() or interaction.deferReply() within 3 seconds, or the command will fail. | Use await interaction.deferReply() at the start of long-running commands. |
| Are you replying multiple times? | Sending more than one initial response (e.g., calling interaction.reply() twice) causes a crash or rejection. | Use reply() once, then use editReply() or followUp() for all future messages. |
| Are environment variables missing? | If token, clientId, guildId, or API keys are missing, startup may fail silently. | Create a config.json file and confirm variables load correctly. Log them during startup (but never commit them). |
| Are your commands registered properly? | If commands aren’t registered or contain invalid structures, Discord won’t execute them. | Run your deploy-commands script and check for validation errors in your console. |
| Are you using the correct intents and permissions? | Missing intents can cause interactionCreate to fail or not fire at all. | Add required intents to your Client initialization (e.g., Guilds, GuildMembers, GuildMessages). |
| Does your bot crash after sending a response? | Post-reply errors (e.g., accessing undefined variables) won’t prevent the initial reply but may block later logic. | Monitor logs in real time and fix downstream logic or failed fetches/DB operations. |
One of the most common causes of “duplicated” slash commands in Discord bots is a mismatch between where your commands were published:
Guild commands vs Global commands.
Discord treats these two types of commands as completely separate lists.
This means:
Because the lists are separate, you can accidentally end up with copies of the same command appearing if you switch your bot from guild-specific development to global deployment or vice-versa.
When building your bot for the first time, many developers start by registering their commands as guild commands because they update instantly (within seconds) and are easy to test.
Later on, when the bot is ready for production, they switch their deploy script to use global commands, expecting the guild commands to “automatically go away”.
But they don’t.
Discord keeps whatever you last published so the server ends up with:
→ Result: every slash command appears twice.
To fix this, you must “clear out” the registry you no longer want to use by publishing an empty array of commands to that specific endpoint.
You need to push an empty array to the guild commands endpoint:
const { REST } = require("@discordjs/rest");const rest = new REST({ version: '10' }).setToken("YOUR_BOT_TOKEN");
rest.put(Routes.applicationCommands(clientId), { body: commands.map(c => c.data) });We understand that sometimes, despite all the documentation, tutorials, and examples, you might still run into a tricky issue. Before reaching out for help, please make sure you have exhausted the following self help methods:
If you have genuinely tried all of the steps above and are still stuck, we are happy to help!