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

如何在discord.js中为/roles部分子命令设置setDefaultMemberPermissions

解决discord.js中/roles子命令权限差异化的问题

不需要创建新命令,有两种可靠的实现方式:

方法1:给单个子命令单独配置默认权限(推荐)

Discord.js的SubcommandBuilder支持为每个子命令单独设置默认成员权限,你可以直接移除全局的权限配置,只给需要权限的子命令加上ManageRoles限制:

  1. 删掉全局的.setDefaultMemberPermissions(PermissionFlagsBits.ManageRoles)
  2. 给create、delete、add、remove这四个子命令分别添加.setDefaultMemberPermissions(PermissionFlagsBits.ManageRoles)
  3. 新增的list子命令不添加任何权限设置,默认所有成员都能调用

修改后的核心代码片段:

const {
  SlashCommandBuilder,
  EmbedBuilder,
  PermissionFlagsBits,
} = require("discord.js");
module.exports = {
  data: new SlashCommandBuilder()
    .setName("roles")
    .setDescription("Manage roles for your guild!")
    // 移除全局的权限设置
    .addSubcommand((subcommand) =>
      subcommand
        .setName("create")
        .setDescription("Create a role")
        .setDefaultMemberPermissions(PermissionFlagsBits.ManageRoles) // 给该子命令加权限
        .addStringOption((option) =>
          option
            .setName("name")
            .setDescription("Name of the role you want to add")
            .setRequired(true)
        )
        // 其他选项保持不变...
    )
    .addSubcommand((subcommand) =>
      subcommand
        .setName("delete")
        .setDescription("Delete a role")
        .setDefaultMemberPermissions(PermissionFlagsBits.ManageRoles) // 给该子命令加权限
        .addRoleOption((option) =>
          option
            .setName("role")
            .setDescription("Enter the name of the role you want to delete")
            .setRequired(true)
        )
    )
    .addSubcommand((subcommand) =>
      subcommand
        .setName("add")
        .setDescription("Add a role to a user")
        .setDefaultMemberPermissions(PermissionFlagsBits.ManageRoles) // 给该子命令加权限
        .addRoleOption((option) =>
          option
            .setName("role")
            .setDescription("Enter the name of the role you want to add")
            .setRequired(true)
        )
        .addUserOption((option) =>
          option
            .setName("user")
            .setDescription("Enter the user you want to add")
            .setRequired(true)
        )
    )
    .addSubcommand((subcommand) =>
      subcommand
        .setName("remove")
        .setDescription("Remove a role from a user")
        .setDefaultMemberPermissions(PermissionFlagsBits.ManageRoles) // 给该子命令加权限
        .addRoleOption((option) =>
          option
            .setName("role")
            .setDescription("Role to remove from user")
            .setRequired(true)
        )
        .addUserOption((option) =>
          option
            .setName("user")
            .setDescription("Enter the user you want to remove")
            .setRequired(true)
        )
    )
    .addSubcommand((subcommand) =>
      subcommand
        .setName("list")
        .setDescription("List all roles in the guild")
        // 不添加权限设置,所有成员可调用
    ),
  // execute逻辑...
};

这种方法是Discord原生支持的,没有权限的用户甚至看不到需要权限的子命令,交互体验更顺畅。

方法2:在命令执行逻辑中手动校验权限

如果需要更灵活的权限判断逻辑(比如结合自定义角色或特殊规则),可以在命令的执行代码里手动检查:

  1. 先移除全局的.setDefaultMemberPermissions(PermissionFlagsBits.ManageRoles)
  2. 在execute函数中,根据子命令名称判断是否需要校验权限:

示例执行逻辑代码:

module.exports = {
  // data部分...
  async execute(interaction) {
    const subcommand = interaction.options.getSubcommand();
    const restrictedSubcommands = ['create', 'delete', 'add', 'remove'];

    // 对需要权限的子命令进行校验
    if (restrictedSubcommands.includes(subcommand)) {
      if (!interaction.member.permissions.has(PermissionFlagsBits.ManageRoles)) {
        return interaction.reply({ 
          content: '你需要拥有「管理角色」权限才能执行此操作!', 
          ephemeral: true 
        });
      }
    }

    // 按子命令执行对应逻辑
    switch(subcommand) {
      case 'create':
        // 处理创建角色逻辑
        break;
      case 'list':
        // 处理列出角色逻辑
        break;
      // 其他子命令的逻辑...
    }
  }
};

这种方法适合需要自定义权限规则的场景,但没有权限的用户依然能看到所有子命令,只是执行时会被拦截。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 16:25:20