如何在discord.js中比较用户角色?实现封禁命令的角色层级校验
解决Discord.js中Ban命令的角色权限层级检查问题
嘿,我正好之前做过类似的功能,给你梳理一下怎么实现!在Discord里,角色是有层级优先级的——层级越高的角色权限越大,discord.js已经给我们提供了现成的方法来对比角色层级,不用自己从头造轮子~
核心思路
要实现“只有发起命令的用户角色层级高于目标用户时才能执行封禁”,核心就是对比两者的最高层级角色:
- 获取命令发起者和目标用户的
GuildMember对象 - 分别拿到他们的最高层级角色(
roles.highest) - 用
comparePositionTo()方法对比两个角色的层级 - 还要额外处理一些边界情况(比如目标是管理员、服务器所有者,或者机器人自身没权限)
示例代码(以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
相关产品推荐
相关产品推荐

