如何用Python的discord.py仅记录通过机器人邀请链接加入的成员?
问题排查:仅记录通过机器人永久邀请链接加入的Discord成员
当前代码的核心问题是:没有验证成员是否真的通过机器人生成的永久邀请链接加入,只是检查服务器中存在机器人的永久邀请,就直接记录所有成员的加入行为,导致所有新成员都会被记录。
问题根源
原代码逻辑是:只要服务器里有机器人创建的永久邀请,就触发日志。但完全没有关联成员和邀请的对应关系,不管成员是通过哪个链接(甚至是服务器自带的快速邀请)进来的,都会被记录。
解决方案
要实现目标,必须追踪服务器所有邀请的使用次数变化,在成员加入时对比邀请的使用次数,找出该成员实际使用的邀请链接,再判断是否是机器人的永久邀请。
完整修正代码
# 全局变量存储各服务器的邀请状态(邀请码: 使用次数) guild_invites = {} @bot.event async def on_ready(): # 机器人启动时,初始化所有服务器的邀请状态 for guild in bot.guilds: invites = await guild.invites() guild_invites[guild.id] = {invite.code: invite.uses for invite in invites} @bot.event async def on_member_join(member): guild = member.guild log_channel_id = 1103749918079852676 log_channel = bot.get_channel(log_channel_id) if not log_channel: return # 获取当前服务器的最新邀请状态 current_invites = await guild.invites() old_invites = guild_invites.get(guild.id, {}) # 对比新旧邀请,找到使用次数增加的那个(即成员使用的邀请) used_invite = None for invite in current_invites: old_uses = old_invites.get(invite.code, 0) if invite.uses > old_uses: used_invite = invite # 更新全局存储的邀请状态 guild_invites[guild.id][invite.code] = invite.uses break # 判断是否是机器人创建的永久邀请 if used_invite and used_invite.max_age == 0 and used_invite.max_uses == 0 and used_invite.inviter == guild.me: embed = discord.Embed( description = f"<:3199blurplejoin:1109799576375918722> **{member.display_name}** just joined **{member.guild.name}**", color=discord.Color(int("313338", 16)) ) await log_channel.send(embed=embed) async def get_existing_never_ending_invite(guild): invites = await guild.invites() for invite in invites: if invite.max_age == 0 and invite.max_uses == 0 and invite.inviter == guild.me: return invite return None
关键逻辑说明
- 邀请状态追踪:
on_ready事件启动时,记录所有服务器的邀请及其当前使用次数,存储在guild_invites字典中。 - 成员加入时对比邀请:当成员加入,获取最新的邀请列表,和之前存储的使用次数对比,找到使用次数增加的邀请,这就是该成员使用的链接。
- 验证邀请属性:确认找到的邀请是机器人创建的永久邀请(
max_age=0永久有效、max_uses=0无使用次数限制、inviter为机器人自身),才触发日志记录。
额外注意事项
- 确保机器人拥有
Manage Server权限,否则无法获取服务器的邀请列表。 - 如果服务器有新创建的邀请链接,下次机器人重启后会自动纳入追踪,无需额外操作。
内容的提问来源于stack exchange,提问作者7hepeter
相关产品推荐
相关产品推荐

