Discord机器人在线但无斜杠命令交互问题求助
Discord机器人在线但无Slash命令交互问题
我的Discord机器人已正常上线,终端执行node .后无报错,但输入/后完全没有命令交互。已确认token和机器人ID正确,以下是相关代码及配置:
主文件 index.js
require('dotenv').config(); const { Client, Collection } = require('discord.js'); const { GatewayIntentBits } = require('discord-api-types/v9'); const fs = require('fs'); const client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildVoiceStates, ], }); client.commands = new Collection(); const commandFiles = fs .readdirSync('./commands') .filter(file => file.endsWith('.js')); // Add the new command here for (const file of commandFiles) { const command = require(`./commands/${file}`); if (command.data) { client.commands.set(command.data.name, command); } } client.once('ready', () => { console.log('Bot is ready!'); }); client.on('interactionCreate', async interaction => { if (!interaction.isCommand()) return; const command = client.commands.get(interaction.commandName); if (!command) return; try { console.log(`Executing command: ${interaction.commandName}`); // Debug statement await command.execute({ client, interaction }); console.log(`Command executed successfully: ${interaction.commandName}`); // Debug statement } catch (error) { console.error(error); await interaction.reply({ content: 'An error occurred while executing the command.', ephemeral: true }); } }); client.login(process.env.TOKEN);
package.json 配置
{ "name": "musicbot", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "dependencies": { "@discordjs/builders": "^1.6.3", "@discordjs/opus": "^0.9.0", "@discordjs/rest": "^1.7.1", "@discordjs/voice": "^0.16.0", "discord-api-types": "^0.37.45", "discord-player": "^6.5.0", "discord.js": "^14.11.0", "dotenv": "^16.1.4", "prism-media": "^1.3.5" } }
命令模块 commands/play.js
const { SlashCommandBuilder } = require("@discordjs/builders"); const { MessageEmbed } = require("discord.js"); const { QueryType } = require("discord-player"); module.exports = { data: new SlashCommandBuilder() .setName("play") .setDescription("Plays a song.") .addSubcommand((subcommand) => subcommand .setName("search") .setDescription("Searches for a song") .addStringOption((option) => option .setName("searchterms") .setDescription("Search keywords") .setRequired(true) ) ) .addSubcommand((subcommand) => subcommand .setName("playlist") .setDescription("Plays a playlist from YouTube") .addStringOption((option) => option .setName("url") .setDescription("Playlist URL") .setRequired(true) ) ) .addSubcommand((subcommand) => subcommand .setName("song") .setDescription("Plays a song from YouTube") .addStringOption((option) => option .setName("url") .setDescription("Song URL") .setRequired(true) ) ), async execute({ client, interaction }) { if (!interaction.member.voice.channel) { await interaction.reply("You need to be in a voice channel."); return; } const queue = client.player.createQueue(interaction.guild); try { if (!queue.connection) await queue.connect(interaction.member.voice.channel); } catch (error) { queue.destroy(); await interaction.reply("Failed to join the voice channel."); return; } await interaction.deferReply(); const subcommand = interaction.options.getSubcommand(); if (subcommand === "song") { const url = interaction.options.getString("url"); const track = await client.player .search(url, { requestedBy: interaction.user, searchEngine: QueryType.YOUTUBE_VIDEO, }) .then((x) => x.tracks[0]); if (!track) { await interaction.editReply("No results found."); return; } queue.addTrack(track); await interaction.editReply(`Added **${track.title}** to the queue.`); } else if (subcommand === "playlist") { const url = interaction.options.getString("url"); const tracks = await client.player .search(url, { requestedBy: interaction.user, searchEngine: QueryType.YOUTUBE_PLAYLIST, }) .then((x) => x.tracks); if (!tracks.length) { await interaction.editReply("No tracks found in the playlist."); return; } queue.addTracks(tracks); await interaction.editReply(`Added ${tracks.length} tracks to the queue.`); } else if (subcommand === "search") { const searchTerms = interaction.options.getString("searchterms"); const tracks = await client.player .search(searchTerms, { requestedBy: interaction.user, searchEngine: QueryType.AUTO, }) .then((x) => x.tracks); if (!tracks.length) { await interaction.editReply("No results found."); return; } queue.addTrack(tracks[0]); await interaction.editReply(`Added **${tracks[0].title}** to the queue.`); } if (!queue.playing) await queue.play(); }, };
问题排查与解决
1. 缺失Slash命令注册代码
当前代码仅加载了命令文件,但未将命令注册到Discord API,这是核心问题。需添加命令注册逻辑:
- 创建
deploy-commands.js文件,内容如下:
require('dotenv').config(); const { REST, Routes } = require('discord.js'); const fs = require('fs'); const commands = []; const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js')); for (const file of commandFiles) { const command = require(`./commands/${file}`); commands.push(command.data.toJSON()); } const rest = new REST({ version: '10' }).setToken(process.env.TOKEN); (async () => { try { console.log(`Started refreshing ${commands.length} application (/) commands.`); const data = await rest.put( Routes.applicationGuildCommands(process.env.CLIENT_ID, process.env.GUILD_ID), { body: commands }, ); console.log(`Successfully reloaded ${data.length} application (/) commands.`); } catch (error) { console.error(error); } })();
- 在
.env文件中添加CLIENT_ID(机器人ID)和GUILD_ID(测试服务器ID) - 先执行
node deploy-commands.js完成命令注册,再启动机器人node .
2. 检查Discord开发者门户设置
- 确认机器人已启用
applications.commands权限 - 邀请机器人到服务器时,确保邀请链接包含
applications.commandsscope(格式示例:https://discord.com/api/oauth2/authorize?client_id=你的机器人ID&permissions=权限值&scope=bot%20applications.commands)
3. 其他检查点
- 确认
commands文件夹路径正确,play.js文件存在且无语法错误 - 检查
.env文件中TOKEN、CLIENT_ID、GUILD_ID是否正确无误
内容的提问来源于stack exchange,提问作者bloodysh
相关产品推荐
相关产品推荐

