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

Discord机器人app_commands装饰器未触发:权限校验失效问题

解决Discord斜杠命令的权限校验问题

你的问题出在对app_commands校验机制的误用上,以下是纠正后的两种实现方案:

方案一:手动实现权限判断逻辑

直接在断言函数里检查用户是否是服务器所有者,或拥有指定角色:

import discord
from discord import app_commands

MODERATOR_ROLE_NAME = "Mods"
ADMIN_ROLE_NAME = "Admins"

def mods_or_owner():
    async def predicate(interaction: discord.Interaction):
        # 校验服务器所有者
        if interaction.user.id == interaction.guild.owner_id:
            return True
        # 校验是否拥有指定角色
        target_roles = {MODERATOR_ROLE_NAME, ADMIN_ROLE_NAME}
        return any(role.name in target_roles for role in interaction.user.roles)
    return app_commands.check(predicate)

方案二:使用内置校验函数组合

利用app_commands.check_any组合官方提供的校验器,更简洁规范:

import discord
from discord import app_commands

MODERATOR_ROLE_NAME = "Mods"
ADMIN_ROLE_NAME = "Admins"

def mods_or_owner():
    return app_commands.check_any(
        app_commands.checks.is_owner(),  # 注意用app_commands的is_owner,不是commands的
        app_commands.checks.has_role(MODERATOR_ROLE_NAME),
        app_commands.checks.has_role(ADMIN_ROLE_NAME)
    )

原代码错误原因

  1. 校验函数混用:你传入了commands.is_owner()(前缀命令的校验器)给app_commands的校验函数,二者不兼容,应使用app_commands.checks.is_owner()。
  2. has_any_role用法错误:app_commands.checks.has_any_role()的参数是角色名称/ID,不能传入其他校验器;且它本身是生成校验器的工厂函数,不是直接返回布尔值的方法,你的断言函数返回了一个校验器对象(被视为True),导致所有用户都能通过校验。

使用示例

和你原来的命令调用方式一致:

@app_commands.command(name='foo', description="")
@mods_or_owner()
async def status(self, interaction: discord.Interaction, member: discord.Member = None):
    await interaction.response.send_message("bar")

内容的提问来源于stack exchange,提问作者Pedro Caribé

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 07:52:38