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
相关产品推荐
相关产品推荐

