Discord.js kick/ban指令优化:禁止权限用户封禁角色等级更高的成员
Discord.js 踢出/封禁指令角色权限等级校验修复方案
核心逻辑说明
Discord 服务器内角色的 position 属性对应角色等级,数值越大等级越高。我们只需要在执行操作前对比「指令执行者」「目标成员」「机器人自身」三者的最高角色等级即可规避越权操作。
需要额外注意:服务器所有者不受角色等级限制,任何非所有者用户都无法对所有者执行踢出/封禁操作。
原有代码问题
- 参数校验顺序错误:在未判断是否传入有效目标成员时就提前访问
member.user.tag生成Embed,参数为空时会直接抛出异常 - 缺少角色等级校验逻辑:仅校验了执行者是否有踢出权限,未限制操作更高等级角色的成员
- 未判断机器人自身权限:如果机器人角色等级低于目标成员,即使指令逻辑允许也无法执行操作,会抛出未知错误
修复后的完整kick指令代码
const Discord = require('discord.js'); module.exports = { name : 'kick', description : '踢出成员', async execute(message, args) { console.log("Works"); // 校验执行者是否有踢出权限 if (!message.member.hasPermission("KICK_MEMBERS")) return message.channel.send("你没有使用该指令的权限"); // 校验是否传入了目标用户参数 if (!args[0]) return message.channel.send(`你需要指定要踢出的用户`); const member = message.mentions.members.first(); // 校验目标用户是否在服务器内 if (!member) return message.channel.send(`你提到的用户不在该服务器中`); // 校验不能踢自己 if (member.id === message.author.id) return message.channel.send("你不能踢出自己"); // 校验不能操作服务器所有者 if (member.id === message.guild.ownerId) return message.channel.send("你无法对服务器所有者执行该操作"); // 校验执行者角色等级是否高于目标成员 if (member.roles.highest.position >= message.member.roles.highest.position) return message.channel.send("你无法操作角色等级高于或等于你的用户"); // 校验机器人自身角色等级是否高于目标成员 if (member.roles.highest.position >= message.guild.me.roles.highest.position) return message.channel.send("我的角色等级低于目标用户,无法执行踢出操作"); let reason = args.slice(1).join(" "); if (!reason) reason = "未指定原因"; const kickEmbed = new Discord.MessageEmbed() .setTitle(`${member.user.tag} 已被踢出 ${message.guild.name}`) .setDescription(`原因: ${reason}`) .setColor("#FF0000") .setTimestamp() .setFooter(message.author.tag, message.author.displayAvatarURL()) .setAuthor(member.user.tag, member.user.displayAvatarURL({dynamic : true})) .setThumbnail(member.guild.iconURL({ dynamic: true })) try { await member.send(kickEmbed); } catch(err){ console.log(`无法向目标用户发送私信通知`); } try { await member.kick(reason); await message.channel.send(kickEmbed); } catch(err){ console.log(err); message.channel.send("我无法踢出你提到的用户"); } } }
Ban指令适配方法
你只需要对上述代码做三处修改即可直接复用为ban指令:
- 将权限校验的
KICK_MEMBERS替换为BAN_MEMBERS - 将执行操作的
member.kick(reason)替换为member.ban({ reason: reason }) - 修改对应的提示文案和Embed内容即可
内容的提问来源于stack exchange,提问作者Ramer
相关产品推荐
相关产品推荐

