Discord机器人on_member_join事件报错:NoneType无id属性,无法获取邀请人ID
报错原因
你遇到的AttributeError: 'NoneType' object has no attribute 'id'报错,核心原因是await tracker.fetch_inviter(member)返回了None值,后续调用.id属性时触发异常。fetch_inviter返回None的常见场景:
- 新成员通过Discord服务器发现页、管理员直接邀请、临时链接入群,无对应邀请人记录
- 邀请人已经退出当前服务器
- 邀请追踪器未成功捕获到对应的邀请记录
- 机器人未开启对应网关意图,无法读取邀请、成员相关数据
解决方法
1. 检查基础权限配置
首先确认Discord开发者后台的机器人设置页,已经开启Server Members Intent网关意图,同时代码初始化bot时开启对应权限:
import discord from discord.ext import commands intents = discord.Intents.default() intents.members = True intents.invites = True bot = commands.Bot(command_prefix='你的前缀', intents=intents)
2. 增加空值兜底逻辑
修改代码,先判断inv_user是否为空,同时不要强制依赖服务器内的member对象获取邀请人ID,避免邀请人退服后无法获取数据,修改后的核心代码如下:
@bot.event async def on_member_join(member): global count_df global inviters_df global leavers_df inv_user = await tracker.fetch_inviter(member) # 空值判断,无邀请人时直接跳过或记录为未知来源 if not inv_user: channel = bot.get_channel(821556573386047518) await channel.send(f'{member.mention} 以未知途径加入服务器') return # 直接取inv_user的id,不依赖服务器内member对象 inviter_id = inv_user.id inviter = member.guild.get_member(inviter_id) #Update invite counts try: #Check to see if the user had an invite count saved already count_df.loc[inviter_id] except KeyError: #If not, make a new entry for the member new_entry = pd.DataFrame([[1,0,0]], index=[inviter_id], columns=count_df.columns) count_df = pd.concat([count_df, new_entry]) # 替换已废弃的append方法 else: #If yes, then add to it count_df.loc[inviter_id,"Real"] += 1 #Update inviter/leaver record inviters_df = pd.concat([inviters_df, pd.DataFrame([[inviter_id]], index=[member.id], columns=inviters_df.columns)]) inviters_df.to_csv('csv/member_invite_record.csv', index_label='Member') try: entries = leavers_df.loc[member.id] except KeyError: pass #Member has not left the guild before, no need to update anything else: for entry in pd.DataFrame([entries]).itertuples(): if entry.Inviter == inviter_id: count_df.loc[inviter_id,"Left"] -= 1 count_df.to_csv('csv/invite_count.csv', index_label='User_ID') leavers_df.drop(labels=member.id, inplace=True) leavers_df.to_csv('csv/member_leaver_record.csv', index_label='Leaver') if inviter: await give_roles(inviter) channel = bot.get_channel(821556573386047518) await channel.send(f'{inviter.mention} 邀请了 {member.mention} 加入服务器!') else: channel = bot.get_channel(821556573386047518) await channel.send(f'ID为{inviter_id}的用户邀请了 {member.mention} 加入服务器,该用户已离开服务器')
额外说明
如果不需要统计无邀请人/邀请人已退服的加入记录,直接在if not inv_user分支return即可,不会影响正常邀请的统计逻辑。
内容的提问来源于stack exchange,提问作者ColeTMK
相关产品推荐
相关产品推荐

