使用Discord.js时能否获取邀请Discord机器人进服务器的用户身份?
Discord.js 实现获取机器人邀请者的方案
核心原理
Discord 官方没有在guildCreate事件中直接提供邀请者字段,市面上的同类机器人都是通过比对服务器邀请码的使用记录间接定位到邀请者的,无需采用给服务器所有者发私信的不精准方案。
前置要求
- 机器人需要开启
Guilds网关意图 - 机器人需要被授予
Manage Guild(管理服务器)权限,只有持有该权限才能拉取服务器的邀请码列表 - 需要在本地维护全局的邀请码缓存,存储所有已加入服务器的邀请码、对应使用次数、邀请者ID
具体实现逻辑
- 客户端
ready事件触发时,遍历所有机器人已加入的服务器,拉取每个服务器的全量邀请码,将code、uses(使用次数)、inviterId(邀请者ID)存入本地缓存 - 监听
guildCreate事件,机器人加入新服务器后立刻拉取当前服务器的所有邀请码,和本地缓存的该服务器邀请记录做对比 - 找到使用次数比缓存记录多1的邀请码,该邀请码就是用户添加机器人时使用的邀请码,对应的
inviterId就是邀请者ID - 调用
guild.members.fetch(inviterId)即可获取到邀请者的GuildMember对象,随后可直接发送私信 - 增加兜底逻辑:如果机器人无拉取邀请列表的权限、或用户通过应用发现等非邀请码渠道添加机器人,无法定位邀请者时,再给服务器所有者发送私信
代码示例
const { Client, GatewayIntentBits, PermissionsBitField } = require('discord.js'); const client = new Client({ intents: [GatewayIntentBits.Guilds] }); // 全局邀请缓存结构:key为服务器ID,value为Map<邀请码, { uses: 使用次数, inviterId: 邀请者ID }> const inviteCache = new Map(); // 启动时初始化已有服务器的邀请缓存 client.on('ready', async () => { for (const guild of client.guilds.cache.values()) { if (!guild.members.me.permissions.has(PermissionsBitField.Flags.ManageGuild)) continue; const invites = await guild.invites.fetch(); const guildInviteMap = new Map(); invites.forEach(invite => { guildInviteMap.set(invite.code, { uses: invite.uses, inviterId: invite.inviterId }); }); inviteCache.set(guild.id, guildInviteMap); } }); // 监听机器人加入新服务器事件 client.on('guildCreate', async (guild) => { // 无管理服务器权限时走兜底逻辑 if (!guild.members.me.permissions.has(PermissionsBitField.Flags.ManageGuild)) { const owner = await guild.fetchOwner(); owner.send('感谢邀请我加入服务器!').catch(() => {}); return; } const currentInvites = await guild.invites.fetch(); const cachedInvites = inviteCache.get(guild.id) || new Map(); // 匹配被使用的邀请码 const usedInvite = currentInvites.find(invite => cachedInvites.get(invite.code)?.uses === invite.uses - 1); if (usedInvite?.inviterId) { const inviter = await guild.members.fetch(usedInvite.inviterId).catch(() => null); if (inviter) { inviter.send(`感谢你邀请我加入${guild.name}!`).catch(() => {}); // 更新邀请缓存 const newGuildInviteMap = new Map(); currentInvites.forEach(invite => { newGuildInviteMap.set(invite.code, { uses: invite.uses, inviterId: invite.inviterId }); }); inviteCache.set(guild.id, newGuildInviteMap); return; } } // 未找到对应邀请码时走兜底逻辑 const owner = await guild.fetchOwner(); owner.send('感谢邀请我加入服务器!').catch(() => {}); // 更新邀请缓存 const newGuildInviteMap = new Map(); currentInvites.forEach(invite => { newGuildInviteMap.set(invite.code, { uses: invite.uses, inviterId: invite.inviterId }); }); inviteCache.set(guild.id, newGuildInviteMap); }); client.login('你的机器人Token');
内容的提问来源于stack exchange,提问作者Kryfulli
相关产品推荐
相关产品推荐

