Py-cord机器人未按权限移除指定角色问题排查
问题分析
你的代码核心错误是误将机器人自身的权限当成了操作人的权限。你用after.guild.get_member(after.guild.me.id)获取的是机器人自己,所以判断的是机器人有没有管理员权限,而非实际添加角色的用户。这就是为什么即使你没有管理员权限,机器人仍会打印"he has admin"——因为机器人本身可能被赋予了管理员权限。
另外,on_member_update事件本身不会直接提供操作人信息,需要通过服务器审计日志来获取执行角色添加操作的用户。
修正后的代码
@bot.event async def on_member_update(before, after): if len(after.roles) > len(before.roles): added_roles = [role for role in after.roles if role not in before.roles] target_role_id = 1093503503680405614 # 只处理目标角色 if any(role.id == target_role_id for role in added_roles): # 获取最近的角色添加审计日志 async for entry in after.guild.audit_logs(limit=1, action=discord.AuditLogAction.member_role_update): # 确认日志对应的是当前用户的角色更新 if entry.target.id == after.id: operator = entry.user # 判断操作人权限 if operator.guild_permissions.administrator: print(f"操作人 {operator.name} 拥有管理员权限,允许添加角色") elif operator.guild_permissions.manage_roles: print(f"操作人 {operator.name} 仅拥有manage_roles权限,移除角色") # 移除目标角色 await after.remove_roles(discord.Object(id=target_role_id)) break
关键修正点
- 获取操作人:通过
audit_logs获取最近的成员角色更新记录,从中提取执行操作的用户 - 权限判断对象:现在判断的是实际操作人的权限,而非机器人自身
- 逻辑优化:先检查是否添加了目标角色,再去查询审计日志,减少不必要的操作
注意事项
- 机器人需要拥有查看审计日志的权限,否则无法获取操作人信息
- 审计日志查询可能存在极小的延迟,如果操作频繁可能需要调整
limit参数或增加时间判断 - 确保机器人的角色位置高于目标角色,否则无法移除该角色
内容的提问来源于stack exchange,提问作者pydal1
相关产品推荐
相关产品推荐

