如何在Discord机器人的on_guild_join事件中设置权限覆盖?
解决Discord机器人on_guild_join事件的权限覆盖与工单命令报错问题
一、修复Muted角色的权限覆盖代码
你原代码的问题在于overwrites字典的键使用了空字符串,而该字典的键必须是角色、成员或频道对象,空字符串无法被识别,导致权限覆盖不生效。正确的做法是先创建角色,再遍历服务器所有文本频道,为该角色设置禁止发送消息的权限:
@bot.event async def on_guild_join(guild): # 创建Muted角色 muted_role = await guild.create_role( name="Muted", color=discord.Color.dark_grey(), reason="创建禁止发送消息的角色" ) # 遍历所有文本频道,设置角色权限覆盖 for channel in guild.text_channels: await channel.set_permissions( muted_role, send_messages=False, send_messages_in_threads=False, reason="配置Muted角色的禁言权限" )
如果只需要给特定频道设置权限,可直接在set_permissions中指定目标频道,无需遍历。
二、排查工单命令的"NoneType has no attribute 'id'"错误
这个报错大概率是机器人在on_guild_join事件中遍历所有频道发送自我介绍时,部分频道无发送权限,导致await channel.send()返回None,而工单命令代码中引用了这个返回的消息对象的id字段,从而触发错误。
解决办法:发送自我介绍时加入异常捕获,仅向有权限的频道发送,且只发送一次(避免骚扰):
@bot.event async def on_guild_join(guild): # 先创建Muted角色(代码同上) # ... # 发送自我介绍嵌入消息 intro_embed = discord.Embed( title="机器人已上线", description="我是你的工单机器人,输入/ticket即可创建工单~", color=discord.Color.blue() ) for channel in guild.text_channels: try: await channel.send(embed=intro_embed) # 发送成功后跳出循环,不再向其他频道发送 break except discord.Forbidden: # 无发送权限,跳过当前频道 continue
这样能避免产生None类型的消息对象,从根源解决工单命令的报错。
内容的提问来源于stack exchange,提问作者user22676652
相关产品推荐
相关产品推荐

