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

如何在discord.js中比较用户角色?实现封禁命令的角色层级校验

解决Discord.js中Ban命令的角色权限层级检查问题

嘿,我正好之前做过类似的功能,给你梳理一下怎么实现!在Discord里,角色是有层级优先级的——层级越高的角色权限越大,discord.js已经给我们提供了现成的方法来对比角色层级,不用自己从头造轮子~

核心思路

要实现“只有发起命令的用户角色层级高于目标用户时才能执行封禁”,核心就是对比两者的最高层级角色:

  1. 获取命令发起者和目标用户的GuildMember对象
  2. 分别拿到他们的最高层级角色(roles.highest)
  3. 用comparePositionTo()方法对比两个角色的层级
  4. 还要额外处理一些边界情况(比如目标是管理员、服务器所有者,或者机器人自身没权限)

示例代码(以discord.js v14为例)

普通消息命令版本

module.exports = {
  name: 'ban',
  description: '封禁指定用户',
  async execute(message, args) {
    // 先拿到目标用户
    const target = message.mentions.members.first() || message.guild.members.cache.get(args[0]);
    if (!target) return message.reply('麻烦指定要封禁的用户哦!');

    // 一些基础判断:不能封自己,不能封管理员
    if (target.id === message.member.id) return message.reply('你总不能封禁自己吧😂');
    if (target.permissions.has('Administrator')) return message.reply('服务器管理员你可动不了!');
    // 额外:不能封服务器所有者
    if (target.id === message.guild.ownerId) return message.reply('服务器主人你也敢碰?');

    // 核心:对比角色层级
    const authorHighestRole = message.member.roles.highest;
    const targetHighestRole = target.roles.highest;
    if (authorHighestRole.comparePositionTo(targetHighestRole) <= 0) {
      return message.reply('你的角色层级不够哦,比目标用户低或者平级都没法封禁人家!');
    }

    // 检查机器人自己有没有ban权限
    if (!message.guild.members.me.permissions.has('BanMembers')) {
      return message.reply('我没有封禁用户的权限呀,麻烦管理员给我开一下权限!');
    }

    // 执行封禁操作
    try {
      await target.ban({ reason: `由${message.author.tag}发起封禁` });
      message.reply(`搞定啦!已经封禁用户 ${target.user.tag}`);
    } catch (err) {
      console.error(err);
      message.reply('哎呀,封禁的时候出错了,再试一次看看?');
    }
  },
};

斜杠命令版本(更符合现在的Discord生态)

const { SlashCommandBuilder, PermissionFlagsBits } = require('discord.js');

module.exports = {
  data: new SlashCommandBuilder()
    .setName('ban')
    .setDescription('封禁指定用户')
    .addUserOption(option =>
      option.setName('target')
        .setDescription('要封禁的用户')
        .setRequired(true))
    .addStringOption(option =>
      option.setName('reason')
        .setDescription('封禁理由')),
  async execute(interaction) {
    const target = interaction.options.getMember('target');
    const reason = interaction.options.getString('reason') || '无理由';

    if (!target) return interaction.reply('找不到这个用户哦!');
    if (target.id === interaction.user.id) return interaction.reply('不能封禁自己啦!');
    if (target.permissions.has(PermissionFlagsBits.Administrator)) return interaction.reply('服务器管理员无法被你封禁哦!');
    if (target.id === interaction.guild.ownerId) return interaction.reply('服务器主人你可不能动哦!');

    // 角色层级对比
    if (interaction.member.roles.highest.comparePositionTo(target.roles.highest) <= 0) {
      return interaction.reply('你的角色层级不够,没法封禁这个用户!');
    }

    // 检查机器人权限
    if (!interaction.guild.members.me.permissions.has(PermissionFlagsBits.BanMembers)) {
      return interaction.reply('我没有封禁权限,请管理员给我分配一下!');
    }

    try {
      await target.ban({ reason: `${interaction.user.tag}: ${reason}` });
      await interaction.reply(`已成功封禁用户 ${target.user.tag},理由:${reason}`);
    } catch (err) {
      console.error(err);
      await interaction.reply('封禁失败了,检查一下权限或者稍后再试吧!');
    }
  },
};

关键方法解释

  • roles.highest:这个属性会直接返回用户拥有的最高层级角色,层级数值越大,角色权限越高
  • comparePositionTo(role):用来对比当前角色和传入角色的层级:
    • 返回正数:当前角色层级更高
    • 返回0:两个角色层级相同
    • 返回负数:当前角色层级更低

这样处理下来,就能完美实现你想要的功能啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:55:21