You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Bot为各Discord服务器单独启用/禁用discord.js斜杠命令

实现Discord Bot特定服务器的斜杠命令启用/禁用功能

核心思路

通过存储服务器级命令状态,或动态注册/移除服务器专属命令两种方式实现控制,以下是具体方案:

方案一:全局命令+服务器状态校验

适合不想重复注册命令的场景,全局注册命令后,在触发时校验当前服务器是否禁用该命令。

  1. 存储命令状态
    用JSON文件或数据库(如SQLite、MongoDB)保存各服务器的禁用命令列表,示例JSON结构:
{
  "guildId1": {
    "disabledCommands": ["ping", "ban"]
  },
  "guildId2": {
    "disabledCommands": []
  }
}
  1. 命令执行前校验
    在每个命令的execute函数开头添加校验逻辑:
const fs = require('fs');
const guildConfigs = JSON.parse(fs.readFileSync('./guildConfigs.json', 'utf8'));

module.exports = {
  data: new SlashCommandBuilder()
    .setName('ping')
    .setDescription('回复Pong!'),
  async execute(interaction) {
    const disabledCommands = guildConfigs[interaction.guildId]?.disabledCommands || [];
    if (disabledCommands.includes(this.data.name)) {
      return interaction.reply({ content: '此命令在当前服务器已被禁用', ephemeral: true });
    }
    // 正常执行命令逻辑
    await interaction.reply('Pong!');
  },
};
  1. 添加管理命令
    创建仅管理员可用的命令,用于切换指定命令的启用/禁用状态:
const { SlashCommandBuilder, PermissionFlagsBits } = require('discord.js');
const fs = require('fs');
const guildConfigs = JSON.parse(fs.readFileSync('./guildConfigs.json', 'utf8'));

module.exports = {
  data: new SlashCommandBuilder()
    .setName('toggle-command')
    .setDescription('启用或禁用服务器内的斜杠命令')
    .setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
    .addStringOption(option =>
      option.setName('command')
        .setDescription("要切换状态的命令名称")
        .setRequired(true))
    .addBooleanOption(option =>
      option.setName('enable')
        .setDescription('true为启用,false为禁用')
        .setRequired(true)),
  async execute(interaction) {
    const commandName = interaction.options.getString('command');
    const enable = interaction.options.getBoolean('enable');
    const guildId = interaction.guildId;

    // 初始化服务器配置(若不存在)
    if (!guildConfigs[guildId]) {
      guildConfigs[guildId] = { disabledCommands: [] };
    }

    if (enable) {
      guildConfigs[guildId].disabledCommands = guildConfigs[guildId].disabledCommands.filter(cmd => cmd !== commandName);
    } else {
      if (!guildConfigs[guildId].disabledCommands.includes(commandName)) {
        guildConfigs[guildId].disabledCommands.push(commandName);
      }
    }

    // 保存配置到文件
    fs.writeFileSync('./guildConfigs.json', JSON.stringify(guildConfigs, null, 2));
    await interaction.reply({ content: `已${enable ? '启用' : '禁用'}命令 \`${commandName}\``, ephemeral: true });
  },
};

方案二:动态注册/移除服务器级命令

适合需要让禁用命令完全从服务器命令列表中消失的场景,直接向目标服务器注册或删除命令。

  1. 注册服务器命令
    编写函数向指定服务器注册单个命令:
const { REST, Routes } = require('discord.js');
const rest = new REST({ version: '10' }).setToken(process.env.DISCORD_TOKEN);

async function registerGuildCommand(guildId, commandData) {
  try {
    await rest.post(
      Routes.applicationGuildCommands(process.env.CLIENT_ID, guildId),
      { body: commandData.toJSON() }
    );
    console.log(`已向服务器 ${guildId} 注册命令 ${commandData.name}`);
  } catch (error) {
    console.error(error);
  }
}
  1. 删除服务器命令
    编写函数删除指定服务器的某个命令:
async function deleteGuildCommand(guildId, commandName) {
  try {
    const commands = await rest.get(Routes.applicationGuildCommands(process.env.CLIENT_ID, guildId));
    const targetCommand = commands.find(cmd => cmd.name === commandName);
    if (targetCommand) {
      await rest.delete(Routes.applicationGuildCommand(process.env.CLIENT_ID, guildId, targetCommand.id));
      console.log(`已从服务器 ${guildId} 删除命令 ${commandName}`);
    }
  } catch (error) {
    console.error(error);
  }
}
  1. 管理命令调用
    修改toggle-command命令,调用上述注册/删除函数:
const fs = require('fs');
// 导入所有命令的配置(假设命令存于commands文件夹)
const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js'));
const allCommands = {};
for (const file of commandFiles) {
  const command = require(`./commands/${file}`);
  allCommands[command.data.name] = command.data;
}

// 在toggle-command的execute函数中替换状态更新逻辑:
if (enable) {
  await registerGuildCommand(guildId, allCommands[commandName]);
} else {
  await deleteGuildCommand(guildId, commandName);
}
await interaction.reply({ content: `已${enable ? '启用' : '禁用'}命令 \`${commandName}\``, ephemeral: true });

注意事项

  • 方案一无需频繁调用Discord API,适合命令较多的场景;方案二禁用后用户完全看不到命令,体验更直观。
  • 生产环境建议用数据库存储配置,避免JSON文件读写冲突。
  • 确保Bot拥有applications.commands权限,管理命令需限制仅服务器管理员可使用。

内容的提问来源于stack exchange,提问作者Bananoo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 00:20:16