You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 00:35:17