discord.py多服务器欢迎消息功能代码运行异常问题求助
discord.py 多服务器入群欢迎功能修复方案
现存问题说明
- 事件参数定义错误:
on_member_join是discord.py内置事件,仅接收member这一个参数,你定义的ctx、message参数不符合规范,会导致事件触发失败 - 存储格式错误:
on_guild_join事件中直接将频道对象写入JSON,JSON不支持序列化Python对象,需要和welcomeMessage命令保持一致,存储频道ID - 频道调用错误:从JSON读取到的是频道ID数值,需要先通过
client.get_channel()方法转换为频道对象,才能调用send()方法发消息 - 成员事件意图未配置:新版本discord.py需要手动开启成员相关意图,否则
on_member_join事件不会被触发 - 边界逻辑缺失:缺少JSON文件初始化、服务器配置存在性校验,首次运行或未配置欢迎频道的服务器有新成员加入时会触发报错
前置操作
- 前往Discord开发者后台,在你的机器人应用页的「Privileged Gateway Intents」板块开启 Server Members Intent
- 初始化client时开启成员意图,示例:
import discord from discord.ext import commands import json import os # 开启意图 intents = discord.Intents.default() intents.members = True # 必须开启,否则成员事件不触发 client = commands.Bot(command_prefix='!', intents=intents) # 前缀可自行修改
修正后完整代码
# 初始化JSON配置文件,避免首次运行报错 if not os.path.exists("welcome-message.json"): with open("welcome-message.json", "w") as f: json.dump({}, f) @client.event async def on_guild_join(guild): with open("welcome-message.json", "r") as f: guildInfo = json.load(f) # 存储频道ID而非频道对象 if guild.text_channels: # 确保服务器有可用文字频道 guildInfo[str(guild.id)] = guild.text_channels[0].id with open("welcome-message.json", "w") as f: json.dump(guildInfo, f) # 设置欢迎频道命令,如需保留原命令名可自行修改函数名 @client.command() @commands.has_permissions(administrator=True) # 可选:限制仅管理员可以设置 async def welcomeMessage(ctx): with open("welcome-message.json", "r") as f: guildInfo = json.load(f) guildInfo[str(ctx.guild.id)] = ctx.channel.id with open("welcome-message.json", "w") as f: json.dump(guildInfo, f) await ctx.send(f"欢迎消息频道已设置为当前频道:{ctx.channel.mention}") # 入群欢迎事件 @client.event async def on_member_join(member): with open("welcome-message.json", "r") as f: guildInfo = json.load(f) # 校验当前服务器是否配置了欢迎频道 guild_id = str(member.guild.id) if guild_id not in guildInfo: return channel = client.get_channel(guildInfo[guild_id]) if not channel: return # 构建欢迎Embed embed = discord.Embed( title=f"欢迎 {member.name} 加入服务器!", description=f"👏 很高兴你来到这里,现在服务器共有 {member.guild.member_count} 名成员啦!", color=discord.Color.green() ) embed.set_thumbnail(url=member.avatar.url if member.avatar else member.default_avatar.url) await channel.send(content=member.mention, embed=embed)
内容的提问来源于stack exchange,提问作者TK12481
相关产品推荐
相关产品推荐

