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

discord.py自定义欢迎频道功能失效KeyError报错排查

问题根因

一共3个直接导致功能失效的问题:

  • 配置文件读写路径不统一:set_welcome_channel命令读写的是项目根目录下的guilds.json,但on_member_join事件读取的是data/guilds.json,两个文件完全独立,新成员加入时读取的配置文件里根本没有对应服务器的频道配置,直接抛出KeyError。
  • 频道对象类型错误:JSON存储的频道ID是字符串格式,直接把ID字符串当成频道实例调用.send()方法,就算KeyError解决了这里也会报属性错误,发不出消息。
  • 日志编码问题:on_message事件里写日志文件时没有指定编码,Windows系统默认用cp1252编码打开文件,遇到消息里的零宽空格(\u200b)就会抛出编码错误,打断事件执行流程。
修复步骤
  1. 统一配置文件路径,建议抽成全局常量避免写错,提前创建好data目录避免文件找不到报错。
  2. 从配置读取到频道ID后,转成整数类型,通过公会对象查询到实际的频道实例再发送消息。
  3. 增加容错判断:如果服务器没有配置过欢迎频道、或者配置的频道已被删除,直接跳过逻辑不要抛错。
  4. 打开所有读写文本/JSON的文件时统一指定encoding='utf-8',避免编码报错;头像地址改用member.display_avatar.url兼容无自定义头像的成员场景。
修复后可直接运行的代码
import json
import random
import discord
from discord.ext import commands
from easy_pil import Editor, load_image_async, Font, File

# 替换成你自己的机器人前缀,Intents必须开启成员权限
client = commands.Bot(command_prefix="!", intents=discord.Intents.all())
# 统一配置路径,避免读写不一致
WELCOME_CONFIG_PATH = "data/guilds.json"

@client.event
async def on_member_join(member):
    # 读取配置,兼容文件不存在/格式损坏场景
    try:
        with open(WELCOME_CONFIG_PATH, 'r', encoding='utf-8') as f:
            guilds_dict = json.load(f)
    except (FileNotFoundError, json.JSONDecodeError):
        guilds_dict = {}

    guild_id_str = str(member.guild.id)
    # 未配置欢迎频道直接退出,不抛错
    if guild_id_str not in guilds_dict:
        return

    # 转换ID类型,获取真实频道实例
    channel_id = int(guilds_dict[guild_id_str])
    welcome_channel = member.guild.get_channel(channel_id)
    # 频道已删除/无权限访问直接退出
    if not welcome_channel or not isinstance(welcome_channel, discord.TextChannel):
        return

    # 生成欢迎图片
    background = Editor("pic.png")
    # 兼容未设置自定义头像的成员
    profile_image = await load_image_async(str(member.display_avatar.url))
    profile = Editor(profile_image).resize((150, 150)).circle_image()
    poppins = Font.poppins(size=50, variant="bold")
    poppins_small = Font.poppins(size=20, variant="light")
    random_color = ["black", "white", "blue", "red", "green", "cyan", "brown", "orange", "yellow", "gray", "purple"]

    background.paste(profile, (325, 90))
    background.ellipse((325, 90), 150, 150, outline=random.choice(random_color), stroke_width=5)
    # 文字描边逻辑
    for offset in [(-2,-2),(2,-2),(-2,2),(2,2)]:
        background.text((400+offset[0], 260+offset[1]), f"WELCOME TO {member.guild.name}", font=poppins, color="black", align="center")
    background.text((400, 260), f"WELCOME TO {member.guild.name}", color="white", font=poppins, align="center")
    for offset in [(-1,-1),(1,-1),(-1,1),(1,1)]:
        background.text((400+offset[0], 325+offset[1]), f"{member.name}#{member.discriminator}", font=poppins_small, color="black", align="center")
    background.text((400, 325), f"{member.name}#{member.discriminator}", color="white", font=poppins_small, align="center")

    file = File(fp=background.image_bytes, filename="welcome.png")
    await welcome_channel.send(f"Hello {member.mention}")
    await welcome_channel.send(file=file)

@client.command(name='welcome')
@commands.has_permissions(administrator=True) # 仅管理员可修改配置
async def set_welcome_channel(ctx, channel: discord.TextChannel):
    try:
        with open(WELCOME_CONFIG_PATH, 'r', encoding='utf-8') as f:
            guilds_dict = json.load(f)
    except (FileNotFoundError, json.JSONDecodeError):
        guilds_dict = {}

    guilds_dict[str(ctx.guild.id)] = str(channel.id)
    with open(WELCOME_CONFIG_PATH, 'w', encoding='utf-8') as f:
        json.dump(guilds_dict, f, indent=4, ensure_ascii=False)

    await ctx.send(f'已将本服欢迎消息发送频道设置为:{channel.mention}')

# 修复日志编码问题示例
@client.event
async def on_message(message):
    # 写日志必须指定utf-8编码
    with open("message_log.txt", "a", encoding="utf-8") as text_file:
        print(f"{message.guild} {message.author} {message.id} {message.content}", file=text_file)
    # 必须加这行,否则前缀命令不会触发
    await client.process_commands(message)
额外注意点
  • 必须在Discord开发者后台开启机器人的「服务器成员意图」(Server Members Intent),否则on_member_join事件根本不会触发。
  • 确保机器人拥有欢迎频道的发送消息、嵌入文件权限,否则消息会发送失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 14:39:18