如何在disnake/discord.py中正确检查用户权限并发送无权限提示
解决Disnake命令权限检查提示问题
问题原因
你加的if-else判断根本不会生效——因为@commands.has_permissions(view_audit_log=True)装饰器会在命令执行前就完成权限校验。如果调用者没权限,装饰器直接抛出MissingPermissions异常,根本不会进入addrole函数内部,所以你写的else分支永远跑不到。
方法一:全局错误处理(推荐)
给机器人加一个全局错误监听,统一处理权限不足的情况:
@bot.event async def on_command_error(ctx, error): if isinstance(error, commands.MissingPermissions): await ctx.send("你没有执行该命令的权限!需要「查看审核日志」权限。") # 其他错误保持默认处理 else: raise error
这样所有用@commands.has_permissions装饰的命令,权限不足时都会自动弹出提示,不用每个命令重复写判断。
方法二:移除装饰器,自行在函数内判断
如果只想给这个命令单独处理,直接去掉装饰器,在函数开头做权限检查:
@commands.slash_command(name="addrole", description="Додати користувачу роль") async def addrole(self, ctx, member: disnake.Member, role: disnake.Role): if not ctx.author.guild_permissions.view_audit_log: await ctx.send("你没有执行该命令的权限!需要「查看审核日志」权限。") return # 有权限时执行的逻辑 await member.add_roles(role) emb = disnake.Embed( title=f"Видача ролі", description=f"Користувачу {member.mention} було видано роль {role.mention} на сервері {ctx.guild.name}\n Видав модератор - **{ctx.author.mention}**", colour=disnake.Color.blue(), timestamp=ctx.created_at ) await ctx.send(embed=emb)
方法三:自定义Check函数(灵活扩展)
如果需要更灵活的权限逻辑,可以自己写check函数:
def has_view_audit_log(): def predicate(ctx): if not ctx.author.guild_permissions.view_audit_log: raise commands.MissingPermissions(["view_audit_log"]) return True return commands.check(predicate) # 用自定义check装饰命令 @commands.slash_command(name="addrole", description="Додати користувачу роль") @has_view_audit_log() async def addrole(self, ctx, member: disnake.Member, role: disnake.Role): await member.add_roles(role) emb = disnake.Embed( title=f"Видача ролі", description=f"Користувачу {member.mention} було видано роль {role.mention} на сервері {ctx.guild.name}\n Видав модератор - **{ctx.author.mention}**", colour=disnake.Color.blue(), timestamp=ctx.created_at ) await ctx.send(embed=emb)
再配合上面的全局错误处理,既能保留装饰器的前置校验,又能自定义提示内容。
内容的提问来源于stack exchange,提问作者Vitalii_Kucher
相关产品推荐
相关产品推荐

