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

如何让Discord.py斜杠命令仅允许指定角色使用?

Discord.py 斜杠命令角色权限校验失效问题解决

问题现象

使用@discord.app_commands.checks.has_role(1073244171541942283)为/test2斜杠命令添加角色权限校验后,出现权限控制失效:移除指定角色的普通用户仍能执行该命令。测试流程:

  • 启动Bot程序
  • 给用户添加指定角色,命令可正常执行
  • 移除用户的指定角色,命令依然能被执行

当前代码示例

import discord
from discord import app_commands

class MyClient(discord.Client):
    def __init__(self, *, intents: discord.Intents):
        super().__init__(intents=intents)
        self.tree = app_commands.CommandTree(self)

    async def setup_hook(self):
        await self.tree.sync()

intents = discord.Intents.default()
client = MyClient(intents=intents)

@client.tree.command(name="test2")
@app_commands.checks.has_role(1073244171541942283)
async def test2(interaction: discord.Interaction):
    await interaction.response.send_message("命令执行成功", ephemeral=True)

client.run("你的Bot令牌")

可能的失效原因

  • Discord缓存延迟:Bot本地缓存的用户角色信息未及时更新,移除角色后仍保留旧数据
  • 内置校验函数局限性:has_role在部分场景下(如用户角色层级、多角色叠加)可能出现判断偏差
  • 命令同步不及时:修改校验逻辑后未重新同步命令,Discord端未应用新的权限规则

彻底解决方法

方法1:自定义精准校验函数

替代内置has_role,直接遍历用户角色ID做判断,避免内置函数的潜在问题:

import discord
from discord import app_commands

class MyClient(discord.Client):
    def __init__(self, *, intents: discord.Intents):
        super().__init__(intents=intents)
        self.tree = app_commands.CommandTree(self)

    async def setup_hook(self):
        await self.tree.sync()

intents = discord.Intents.default()
client = MyClient(intents=intents)

# 自定义角色校验装饰器
def has_required_role(role_id: int):
    async def predicate(interaction: discord.Interaction):
        return any(role.id == role_id for role in interaction.user.roles)
    return app_commands.check(predicate)

@client.tree.command(name="test2")
@has_required_role(1073244171541942283)
async def test2(interaction: discord.Interaction):
    await interaction.response.send_message("命令执行成功", ephemeral=True)

client.run("你的Bot令牌")

方法2:强制刷新用户角色缓存

在命令执行前主动拉取用户最新角色数据,确保校验基于最新信息:

@client.tree.command(name="test2")
async def test2(interaction: discord.Interaction):
    # 主动获取用户最新数据,刷新本地缓存
    await interaction.user.fetch()
    # 手动校验角色
    if not any(role.id == 1073244171541942283 for role in interaction.user.roles):
        await interaction.response.send_message("你没有权限执行此命令", ephemeral=True)
        return
    await interaction.response.send_message("命令执行成功", ephemeral=True)

方法3:结合Discord原生权限控制

除代码校验外,通过Discord服务器设置加固权限:

  1. 进入服务器设置 → 集成 → 选择你的Bot
  2. 找到/test2命令,点击编辑权限
  3. 设置仅指定角色(ID:1073244171541942283)可使用该命令

验证步骤

  1. 修改代码后重启Bot
  2. 确认命令已同步(重启时setup_hook会自动执行tree.sync())
  3. 给测试用户添加指定角色,执行/test2确认可正常运行
  4. 移除测试用户的指定角色,执行命令确认被拦截

内容的提问来源于stack exchange,提问作者Dark

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 14:02:39