如何创建会随被邀请成员留存状态自动更新的invites命令
可同步退群用户的邀请统计invites命令实现方案
实现该功能的核心逻辑是不要直接依赖Discord原生的邀请使用数统计,原生统计不会因为被邀请人退群而扣减,必须自己存储用户邀请关联关系才能实现动态同步。以下基于Discord.js v14给出具体实现步骤:
1. 准备数据存储
你可以选择轻量JSON文件、SQLite或其他数据库,需要存储两类核心数据:
invite_codes:存储邀请码基础信息,包含字段:code(邀请码内容)、guild_id(所属服务器ID)、creator_id(邀请码创建者ID)、uses(当前累计使用数)invited_users:存储用户邀请关联信息,包含字段:user_id(被邀请人ID)、guild_id(所属服务器ID)、inviter_id(邀请人ID)
2. 启动时预加载全量邀请码
机器人启动时拉取所有已加入服务器的现有邀请码,存入缓存或数据库,避免后续新用户入群时匹配不到邀请人:
const { Client, GatewayIntentBits } = require('discord.js'); const client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildInvites ] }); const db = require('better-sqlite3')('./invite.db'); // 此处用SQLite做示例 client.on('ready', async () => { // 初始化数据库表 db.exec(` CREATE TABLE IF NOT EXISTS invite_codes ( code TEXT PRIMARY KEY, guild_id TEXT, creator_id TEXT, uses INTEGER ); CREATE TABLE IF NOT EXISTS invited_users ( user_id TEXT, guild_id TEXT, inviter_id TEXT, PRIMARY KEY(user_id, guild_id) ); `); // 预加载所有服务器邀请码 for (const guild of client.guilds.cache.values()) { const invites = await guild.invites.fetch(); invites.forEach(invite => { db.prepare(`INSERT OR REPLACE INTO invite_codes (code, guild_id, creator_id, uses) VALUES (?, ?, ?, ?)`).run( invite.code, guild.id, invite.inviterId, invite.uses ); }); } console.log(`已登录为 ${client.user.tag}`); });
3. 监听新用户入群事件,记录邀请关联
新用户入群时拉取当前服务器全量邀请码,和存储的旧邀请码比对,找到使用数+1的邀请码即为该用户的入群邀请,存储关联关系:
client.on('guildMemberAdd', async (member) => { if (member.user.bot) return; // 跳过机器人用户 const oldInvites = db.prepare(`SELECT code, uses FROM invite_codes WHERE guild_id = ?`).all(member.guild.id); const newInvites = await member.guild.invites.fetch(); // 匹配使用数发生变化的邀请码 const usedInvite = newInvites.find(inv => { const oldUse = oldInvites.find(o => o.code === inv.code)?.uses || 0; return inv.uses > oldUse; }); if (!usedInvite || !usedInvite.inviterId) return; // 更新邀请码使用数 db.prepare(`UPDATE invite_codes SET uses = ? WHERE code = ? AND guild_id = ?`).run(usedInvite.uses, usedInvite.code, member.guild.id); // 存储被邀请人和邀请人的关联关系 db.prepare(`INSERT OR REPLACE INTO invited_users (user_id, guild_id, inviter_id) VALUES (?, ?, ?)`).run(member.id, member.guild.id, usedInvite.inviterId); });
4. 监听用户退群事件,同步扣减邀请数
用户退群时直接查询关联表,找到对应的邀请人,删除该条邀请记录即可自动同步后续统计结果:
client.on('guildMemberRemove', async (member) => { // 查询该用户的邀请记录 const record = db.prepare(`SELECT inviter_id FROM invited_users WHERE user_id = ? AND guild_id = ?`).get(member.id, member.guild.id); if (!record) return; // 删除该条邀请记录,避免重复扣减 db.prepare(`DELETE FROM invited_users WHERE user_id = ? AND guild_id = ?`).run(member.id, member.guild.id); });
5. 实现invites查询命令
直接统计指定用户在当前服务器的有效邀请关联记录数,即可得到实时邀请数:
// 斜杠命令示例,需提前注册对应invites命令 client.on('interactionCreate', async (interaction) => { if (!interaction.isChatInputCommand() || interaction.commandName !== 'invites') return; const targetUser = interaction.options.getUser('用户') || interaction.user; // 统计有效邀请数 const count = db.prepare(`SELECT COUNT(*) as total FROM invited_users WHERE inviter_id = ? AND guild_id = ?`).get(targetUser.id, interaction.guild.id); await interaction.reply(`${targetUser.tag} 当前有效邀请人数为:${count.total}`); }); client.login('你的机器人Token');
注意事项
- 机器人刚加入服务器时没有历史邀请数据,加入前的邀请记录不会被统计,属于正常情况
- 遇到特殊邀请(如服务器vanity url、临时一次性邀请码)匹配不到邀请人时,可以标记该用户的邀请人为
null,避免统计错误
内容的提问来源于stack exchange,提问作者Ylan
相关产品推荐
相关产品推荐

