I’m trying to figure out why my bots slash commands aren’t showing up in my server. I have given it the applications.commands and bot scopes as well as the Administrator permission, so I don’t believe it’s a permissions issue.
Here is my current index.js,
require("dotenv").config();
const {REST} = require("@discordjs/rest");
const { Client, Events, GatewayIntentBits, Collection } = require('discord.js');
const { Routes } = require("discord-api-types/v10");
const { Player } = require("discord-player");
const fs = require("node:fs");
const path = require("node:path");
const client = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildVoiceStates]
});
client.once(Events.ClientReady, readyClient => {
console.log(`Ready! Logged in as ${readyClient.user.tag}`);
});
const commands = [];
client.commands = new Collection();
const commandsPath = path.join(__dirname, "commands");
const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith(".js"));
for (const file of commandFiles)
{
const filePath = path.join(commandsPath, file);
const command = require(filePath);
client.commands.set(command.data.name, command);
commands.push(command.data.toJSON());
}
client.player = new Player(client, {
ytdlOptions: {
quality: "highestaudio",
highWaterMark: 1 << 25
}
});
client.on("ready", () => {
const guild_ids = client.guilds.cache.map(guild => guild.id);
const rest = new REST({version: "10"}).setToken(process.env.TOKEN);
for (const guildId of guild_ids)
{
rest.put(Routes.applicationGuildCommands(process.env.CLIENT_ID, guildId), {
body: commands
})
.then(() => console.log(`Added commands to ${guildId}`))
.catch(console.error);
}
});
client.on("interactionCreate", async interaction => {
if(!interaction.isChatInputCommand()) return;
const command = client.commands.get(interaction.commandName);
if(!command) return;
try
{
await command.execute({client, interaction});
}
catch(err)
{
console.error(err);
await interaction.reply("An error occured executing this command. Try again.");
}
});
// Log in to Discord with your client's token
client.login(process.env.TOKEN);
along with one of my slash commands.
const { SlashCommandBuilder } = require("@discordjs/builders");
const { MessageEmbed } = require("discord.js");
const { QueryType } = require("discord-player");
module.exports = {
data: new SlashCommandBuilder()
.setName('play')
.setDescription('Play a song.')
.addSubcommand(subcommand => {
subcommand
.setName('search')
.setDescription('Search for a song.')
.addStringOption(option => {
option
.setName('searchterms')
.setDescription('Search keywords')
.setRequired(true);
})
})
.addSubcommand(subcommand => {
subcommand
.setName('playlist')
.setDescription('Plays a playlist from YT')
.addStringOption(option => {
option
.setName('url')
.setDescription('Playlist URL')
.setRequired(true);
})
})
.addSubcommand(subcommand => {
subcommand
.setName('playurl')
.setDescription('Plays a song from YT using URL')
.addStringOption(option => {
option
.setName('url')
.setDescription('URL for a song')
.setRequired(true);
})
}),
execute: async ({client, interactions}) => {
if (!interaction.member.voice.channel)
{
await interaction.reply(':warning: You must be in a voice channel to use this command!');
return;
}
const queue = await client.player.createQueue(interacton.guild);
if (!queue.connection) await queue.connect(interaction.member.voice.channel)
let embed = new MessageEmbed();
if(interaction.options.getSubcommand() === 'song')
{
let url = interaction.options.getString('url');
const result = await client.player.search(url, {
requestedBy: interaction.user,
searchEngine: QueryType.YOUTUBE_VIDEO,
});
if (result.tracks.length === 0)
{
await interaction.reply(':warning: No results found!')
return
}
const song = result.tracks[0];
await queue.addTrack(song);
embed
.setDescription(`Added **[${song.title}](${song.url})** to the queue.`)
.setThumbnail(song.thumbnail)
.setFooter({text: `Duration: ${song.duration}`});
}
else if(interaction.options.getSubcommand() === 'playlist')
{
let url = interaction.options.getString('url');
const result = await client.player.search(url, {
requestedBy: interaction.user,
searchEngine: QueryType.YOUTUBE_PLAYLIST,
});
if (result.tracks.length === 0)
{
await interaction.reply(':warning: No playlist found!')
return
}
const playlist = result.playlist;
await queue.addTracks(playlist);
embed
.setDescription(`Added **[${playlist.title}](${playlist.url})** to the queue.`)
.setThumbnail(playlist.thumbnail)
.setFooter({text: `Duration: ${playlist.duration}`});
}
else if(interaction.options.getSubcommand() === 'search')
{
let url = interaction.options.getString('searchterms');
const result = await client.player.search(url, {
requestedBy: interaction.user,
searchEngine: QueryType.YOUTUBE_PLAYLIST,
});
if (result.tracks.length === 0)
{
await interaction.reply(':warning: No results found!')
return
}
const song = result.tracks[0];
await queue.addTrack(song);
embed
.setDescription(`Added **[${song.title}](${song.url})** to the queue.`)
.setThumbnail(song.thumbnail)
.setFooter({text: `Duration: ${song.duration}`});
}
if(!queue.playing) await queue.play();
await interaction.reply({
embeds:
})
}
}
When running node index.js
in terminal, it does successfully run the .then(() => console.log(`Added commands to ${guildId}`))
code line, but for some reason I’m not seeing any slash commands for my bot, only other bots.
2
Answers
Modern slash commands requires use of the
deploy-commands.js
file to deploy commands to your server.Below is an example deployment script.
I’ve noticed while developing that it may take a while before your Discord client actually sees your slash commands. You could check whether the commands show up when using the Discord app on your phone. Another way is to open a private browser and log into your account. Both these methods have worked for me in the past.
Are you sure Discord actually acknowledges that the commands have been created/updated? I’m not sure how that could be done but I’d imagine
discord.js
will return an error when it failed.I digged a bit further into this and noticed an issue was filed on GitHub a couple of years ago. It states that the period to wait is up to 1 hour apparently.