Discord机器人Mute命令未校验成员权限问题排查
问题分析与修复方案
核心错误点
你的代码导致“应用未响应”的直接原因是权限判断的语法错误:if member.guild_permissions(manage_roles = True) == True: 这行写法错误,guild_permissions是discord.Permissions对象,不是可调用方法,不能用括号传参调用,正确写法是直接访问属性member.guild_permissions.manage_roles。
除此之外,命令还存在两个权限逻辑漏洞:
- 未检查机器人自身是否有权限操作目标成员(比如目标成员角色层级高于机器人时,机器人无法添加Muted角色)
- 未限制命令使用者的权限范围(比如普通用户不能禁言角色层级比自己高的成员)
修正后的代码
@bot.slash_command(name="mute", description="Mute a member in your server (REQUIRES MANAGE ROLES)") @default_permissions(manage_roles=True) @commands.guild_only() async def mute(ctx, member: discord.Member, *, reason=None): bot_member = ctx.guild.me muted_role = discord.utils.get(ctx.guild.roles, name="Muted") # 检查Muted角色是否存在 if not muted_role: embed = discord.Embed(description="服务器中未找到名为`Muted`的角色!", color=discord.Color.red()) await ctx.respond(embed=embed, ephemeral=True) return # 检查目标成员是否已被禁言 if muted_role in member.roles: embed = discord.Embed(description="该用户已经处于禁言状态!", color=discord.Color.red()) await ctx.respond(embed=embed, ephemeral=True) return # 检查是否要禁言机器人自身 if member == bot_member: embed = discord.Embed(description="我不能禁言我自己!", color=discord.Color.red()) await ctx.respond(embed=embed, ephemeral=True) return # 检查目标成员是否拥有管理员或管理角色权限 if member.guild_permissions.administrator or member.guild_permissions.manage_roles: embed = discord.Embed(description="无法禁言拥有`管理角色`或`管理员`权限的成员!", color=discord.Color.red()) await ctx.respond(embed=embed, ephemeral=True) return # 检查命令使用者的角色层级是否高于目标成员 if ctx.author.top_role <= member.top_role: embed = discord.Embed(description="你无法禁言角色层级高于或等于你的成员!", color=discord.Color.red()) await ctx.respond(embed=embed, ephemeral=True) return # 检查机器人的角色层级是否高于目标成员 if bot_member.top_role <= member.top_role: embed = discord.Embed(description="我的角色层级低于该成员,无法执行禁言操作!", color=discord.Color.red()) await ctx.respond(embed=embed, ephemeral=True) return # 执行禁言操作 await member.add_roles(muted_role) reason_text = reason if reason else "无理由" embed = discord.Embed(title="禁言成功!", description=f"已成功禁言 {member.mention},原因:{reason_text}", color=discord.Color.green()) await ctx.respond(embed=embed) # 给所有频道设置Muted角色的权限(如果还没设置过的话) for channel in ctx.guild.channels: await channel.set_permissions(muted_role, speak=False, send_messages=False) print(f"{ctx.author} 在 {ctx.guild} 成功禁言 {member},原因:{reason_text}")
关键优化说明
- 修复权限判断语法:把错误的方法调用改为属性访问,避免运行时错误导致机器人无响应。
- 增加角色存在检查:提前判断Muted角色是否存在,避免后续操作报错。
- 完善权限逻辑:
- 禁止禁言拥有管理员/管理角色权限的成员
- 禁止用户禁言角色层级高于自己的成员
- 确保机器人角色层级足够,能对目标成员执行操作
- 优化代码结构:使用提前
return的方式减少嵌套,提升代码可读性。
内容的提问来源于stack exchange,提问作者zoomingspeed
相关产品推荐
相关产品推荐

