discord.py私信DM场景使用has_role校验功能失效问题求助
问题根因
commands.has_role()校验器仅支持服务器(公会)上下文,私信场景下不存在服务器信息,ctx.guild返回None,无法读取用户角色,所以必然触发校验失败。- 装饰器默认从下往上执行,
@commands.dm_only()先校验触发场景为私信,之后执行的has_role已经没有服务器上下文,必然失败。
解决方法
你需要自定义支持私信场景的角色校验逻辑,具体实现如下:
1. 编写自定义校验函数
def check_guild_role(role_id: int, target_guild_id: int): async def role_check(ctx): # 从机器人实例中获取目标服务器对象 target_guild = ctx.bot.get_guild(target_guild_id) if not target_guild: return False # 获取触发用户在目标服务器的成员身份 user_member = target_guild.get_member(ctx.author.id) if not user_member: return False # 校验是否持有目标角色 return any(role.id == role_id for role in user_member.roles) return commands.check(role_check)
2. 替换原有装饰器
将你原有的校验装饰器替换为自定义校验:
@commands.check_any(check_guild_role(role_id=你要校验的角色ID, target_guild_id=目标服务器ID)) @commands.dm_only()
3. 前置配置检查
- 确认机器人已经加入你要校验的目标服务器
- 前往Discord开发者后台的机器人设置页,开启Server Members Intent权限,否则无法获取服务器成员信息
- 如果需要支持多个服务器的角色校验,可以扩展自定义函数的参数,传入多个服务器ID做遍历校验即可
内容的提问来源于stack exchange,提问作者d4t44
相关产品推荐
相关产品推荐

