discord.js机器人启动时命令无法自动刷新的问题求助
Discord机器人命令不刷新问题的解决方案
核心问题
你的代码仅在本地将命令加载到了client.commands集合中,但没有通过Discord REST API将命令数据同步到Discord服务器。Discord的Slash命令必须经过API注册才会在客户端显示,本地加载不影响Discord端的命令列表。
问题代码分析
- 缺失命令注册逻辑:现有代码初始化了
REST实例,但从未调用rest.put()向Discord提交命令数据,导致新命令无法被识别,旧命令也不会被移除。 - reload函数局限:
reload_command仅刷新了本地Node.js缓存和client.commands集合,未同步更新Discord端的命令。 - 路径错误:
reload.js中command.category未在命令文件中定义,会导致require.resolve路径错误,无法正确重载命令。
修复方案
1. 添加命令部署函数
在index.js中添加同步命令到Discord的函数:
async function deployCommands() { const commands = []; const foldersPath = path.join(__dirname, 'commands'); const commandFolders = fs.readdirSync(foldersPath); // 遍历所有命令文件,收集命令的data结构 for (const folder of commandFolders) { const commandsPath = path.join(foldersPath, folder); 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); if ('data' in command && 'execute' in command) { commands.push(command.data.toJSON()); } else { console.log(`[WARNING] 命令文件 ${filePath} 缺少必填的"data"或"execute"属性。`); } } } try { console.log(`正在刷新 ${commands.length} 个应用命令...`); // 全局注册命令(生效需约1小时),测试阶段可替换为服务器专属路由 const data = await rest.put( Routes.applicationCommands(clientId), { body: commands }, ); console.log(`成功刷新 ${data.length} 个应用命令!`); } catch (error) { console.error(error); } }
测试推荐用服务器专属命令(即时生效),将
Routes.applicationCommands(clientId)替换为Routes.applicationGuildCommands(clientId, '你的服务器ID')
2. 修改ClientReady事件
在机器人就绪时调用部署函数,替换原有的reload_command调用:
client.once(Events.ClientReady, async readyClient => { await deployCommands(); // 同步命令到Discord console.log(`已就绪!登录账号:${readyClient.user.tag}`); });
3. 修复reload函数的路径与同步逻辑
首先在每个命令文件中添加category属性,比如addkey.js:
module.exports = { category: 'utility', // 添加分类标记 data: new SlashCommandBuilder() .setName('addkey') .setDescription('Add a key.'), async execute(interaction) { await interaction.reply("Running add key"); }, };
然后修改index.js中的reload_command函数:
async function reload_command(command_name) { const command = client.commands.get(command_name); if (!command) { return console.log(`不存在名为 \`${command_name}\` 的命令!`); } const filePath = path.join(__dirname, 'commands', command.category, `${command.data.name}.js`); delete require.cache[require.resolve(filePath)]; try { client.commands.delete(command.data.name); const newCommand = require(filePath); client.commands.set(newCommand.data.name, newCommand); console.log(`命令 \`${newCommand.data.name}\` 已重载本地缓存!`); await deployCommands(); // 重载后同步到Discord } catch (error) { console.error(error); console.log(`重载命令 \`${command.data.name}\` 时出错:\n\`${error.message}\``); } }
4. 修复reload.js的路径问题
修改reload.js中的路径处理与同步逻辑:
const { SlashCommandBuilder, REST, Routes } = require('discord.js'); const path = require('node:path'); const { token } = require('../../config.json'); const clientId = '1184598822593253477'; module.exports = { category: 'utility', data: new SlashCommandBuilder() .setName('reload') .setDescription('Reloads a command.') .addStringOption(option => option.setName('command') .setDescription('要重载的命令名称') .setRequired(true)), async execute(interaction) { const commandName = interaction.options.getString('command', true).toLowerCase(); const command = interaction.client.commands.get(commandName); if (!command) { return interaction.reply(`不存在名为 \`${commandName}\` 的命令!`); } const filePath = path.join(__dirname, '..', command.category, `${command.data.name}.js`); delete require.cache[require.resolve(filePath)]; try { interaction.client.commands.delete(command.data.name); const newCommand = require(filePath); interaction.client.commands.set(newCommand.data.name, newCommand); // 同步更新到Discord const rest = new REST().setToken(token); const commands = interaction.client.commands.map(cmd => cmd.data.toJSON()); await rest.put(Routes.applicationCommands(clientId), { body: commands }); await interaction.reply(`命令 \`${newCommand.data.name}\` 已重载并同步到Discord!`); } catch (error) { console.error(error); await interaction.reply(`重载命令 \`${command.data.name}\` 时出错:\n\`${error.message}\``); } }, };
注意事项
- 全局命令刷新后需等待约1小时生效,测试阶段优先使用服务器专属命令。
- 修改命令的名称、描述或选项后,必须调用
deployCommands()同步到Discord。 rest.put()会用新命令数组完全覆盖Discord端的命令列表,旧命令会被自动移除。
内容的提问来源于stack exchange,提问作者Jacob Cooper
相关产品推荐
相关产品推荐

