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

discord.py中Bot无法正确设置用户send_messages权限问题

问题解决:Discord Bot按钮点击后无法正确限制用户发消息权限

问题原因

创建游戏频道时,你给所有队员都添加了单独的成员权限覆盖(send_messages=True)。当点击按钮后,仅修改了服务器默认角色和选中用户的权限,但其他队员的单独权限覆盖仍然有效。由于Discord权限系统中,成员级别的权限优先级高于角色级别,所以这些队员依然保留发消息权限。

修复方案

在按钮的处理逻辑中,需要先重置所有游戏队员的发消息权限为禁用状态,再给随机选中的用户开放权限。具体修改如下:

修改后的caller方法核心代码

@discord.ui.button(label="Click me!", style=discord.ButtonStyle.primary)
async def caller(self, interaction: discord.Interaction, button: discord.ui.Button['Viewer']):
    # 布局相关代码保持不变
    arrangement1 = [":yellow_square:"] * 10
    arrangement2 = [":yellow_square:"] * 10
    arrangement3 = [
        ":wastebasket:",
        ":blue_square:",
        ":yellow_square:",
        ":yellow_square:",
        ":yellow_square:",
        ":yellow_square:",
        ":yellow_square:",
        ":yellow_square:",
        ":red_square:",
        ":yellow_square:",
    ]
    arrangement4 = [":yellow_square:"] * 10
    arrangement5 = [":yellow_square:"] * 10

    # 随机选中队员
    random_member = random.choice(self.all_members)

    # 将原频道权限转换为可修改的字典
    overwrites = dict(self.channel.overwrites)
    
    # 1. 锁定服务器默认角色的频道访问和发消息权限
    overwrites[self.channel.guild.default_role] = discord.PermissionOverwrite(
        view_channel=False,
        send_messages=False
    )
    
    # 2. 重置所有队员的发消息权限为禁用(保留频道查看权限)
    for member in self.all_members:
        overwrites[member] = discord.PermissionOverwrite(
            view_channel=True,
            send_messages=False
        )
    
    # 3. 给选中的队员开放发消息权限
    overwrites[random_member] = discord.PermissionOverwrite(
        view_channel=True,
        send_messages=True
    )

    await self.channel.edit(overwrites=overwrites)
    await self.channel.send(f"{random_member.mention}, you have the ball!")

    # 后续队伍判断、布局发送代码保持不变
    if random_member in self.team_one:
        await self.channel.send(f"{random_member.mention} is in Team 1!")
    elif random_member in self.team_two:
        await self.channel.send(f"{random_member.mention} is in Team 2!")

    joined_arrangements: typing.List[str] = [
        " ".join(arrangement) for arrangement in (arrangement1, arrangement2, arrangement3, arrangement4, arrangement5)
    ]
    messenger: str = '\n'.join(joined_arrangements)
    await interaction.response.send_message(messenger)

关键说明

  • 先统一重置所有队员的发消息权限为False,确保默认状态下无法发消息
  • 单独给选中用户设置send_messages=True,利用成员权限优先级覆盖全局设置
  • 使用dict(self.channel.overwrites)将原权限映射转换为可修改字典,避免直接操作原对象可能出现的异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 10:23:15