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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 08:10:08