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) )
原代码错误原因
- 校验函数混用:你传入了
commands.is_owner()(前缀命令的校验器)给app_commands的校验函数,二者不兼容,应使用app_commands.checks.is_owner()。 - 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é
相关产品推荐
相关产品推荐

