Discord机器人邀请奖励Bug求助:未完成邀请却提前发命令次数
Discord机器人额度规则实现与Bug修复
规则可行性确认
你的需求完全可以实现:用户初始拥有5次命令额度,每成功邀请1人加入服务器可额外获得5次额度,且每个用户、每个邀请独立生效——核心是通过事件监听+持久化存储来追踪用户额度和邀请关联关系。
Bug修复方案
1. 用户初始无法使用命令
问题原因:新用户加入后未初始化额度记录,导致额度判断时默认视为0。
解决方法:
- 监听
guildMemberAdd事件,新用户加入时自动在存储(数据库/JSON)中创建该用户的额度记录,初始值设为5。 - 增加兜底逻辑:用户第一次触发命令时,若未找到额度记录则立即初始化。
示例代码(Discord.js + SQLite):
// 新用户加入时初始化额度 client.on('guildMemberAdd', async (member) => { const existingQuota = await db.get( 'SELECT * FROM user_quota WHERE user_id = ? AND guild_id = ?', [member.user.id, member.guild.id] ); if (!existingQuota) { await db.run( 'INSERT INTO user_quota (user_id, guild_id, quota) VALUES (?, ?, ?)', [member.user.id, member.guild.id, 5] ); } }); // 命令触发时兜底初始化 client.on('interactionCreate', async (interaction) => { if (!interaction.isCommand()) return; let userQuota = await db.get( 'SELECT * FROM user_quota WHERE user_id = ? AND guild_id = ?', [interaction.user.id, interaction.guild.id] ); if (!userQuota) { await db.run( 'INSERT INTO user_quota (user_id, guild_id, quota) VALUES (?, ?, ?)', [interaction.user.id, interaction.guild.id, 5] ); userQuota = { quota: 5 }; } // 后续额度检查逻辑... });
2. 邀请后提前获得额度
问题原因:当前逻辑在用户创建邀请时就增加额度,而非被邀请人成功加入后触发。
解决方法:调整奖励触发时机,仅当被邀请人通过目标邀请链接成功加入时,才给邀请人增加额度:
- 用户使用
/convidar命令时,创建单次使用的邀请链接,并存储邀请码与邀请者ID的关联。 - 监听
guildMemberAdd事件,识别新用户的邀请来源,找到对应的邀请者,为其增加5次额度,并标记该邀请已使用(避免重复奖励)。
示例代码:
// /convidar命令处理 client.commands.get('convidar').execute = async (interaction) => { // 创建仅可使用1次的邀请链接 const invite = await interaction.channel.createInvite({ maxUses: 1, reason: '邀请获取命令额度' }); // 存储邀请与邀请者的关联 await db.run( 'INSERT INTO invites (invite_code, inviter_id, guild_id) VALUES (?, ?, ?)', [invite.code, interaction.user.id, interaction.guild.id] ); await interaction.reply(`你的邀请链接:${invite.url}\n有人通过此链接加入后,你将获得5次额外命令额度!`); }; // 新用户加入时处理邀请奖励 client.on('guildMemberAdd', async (member) => { // 获取服务器所有邀请记录 const guildInvites = await member.guild.invites.fetch(); // 找到被使用的邀请(此处简化逻辑,实际需提前存储邀请初始使用次数做对比) const usedInvite = guildInvites.find(inv => inv.uses === 1); if (!usedInvite) return; // 从存储中获取邀请者信息 const inviteRecord = await db.get( 'SELECT * FROM invites WHERE invite_code = ? AND guild_id = ?', [usedInvite.code, member.guild.id] ); if (!inviteRecord) return; // 为邀请者增加额度 await db.run( 'UPDATE user_quota SET quota = quota + 5 WHERE user_id = ? AND guild_id = ?', [inviteRecord.inviter_id, member.guild.id] ); // 通知邀请者 const inviter = await member.guild.members.fetch(inviteRecord.inviter_id); inviter.send(`恭喜!有人通过你的邀请加入服务器,你的命令额度已增加5次。`); // 删除已使用的邀请记录,避免重复奖励 await db.run('DELETE FROM invites WHERE invite_code = ?', [usedInvite.code]); });
核心逻辑补充:命令额度检查与扣除
client.on('interactionCreate', async (interaction) => { if (!interaction.isCommand()) return; let userQuota = await db.get( 'SELECT * FROM user_quota WHERE user_id = ? AND guild_id = ?', [interaction.user.id, interaction.guild.id] ); // 兜底初始化 if (!userQuota) { await db.run( 'INSERT INTO user_quota (user_id, guild_id, quota) VALUES (?, ?, ?)', [interaction.user.id, interaction.guild.id, 5] ); userQuota = { quota: 5 }; } // 检查额度是否足够 if (userQuota.quota <= 0) { return interaction.reply('你的命令额度已用完,请邀请他人加入服务器获取额外额度!'); } // 扣除额度 await db.run( 'UPDATE user_quota SET quota = quota - 1 WHERE user_id = ? AND guild_id = ?', [interaction.user.id, interaction.guild.id] ); // 执行命令逻辑 await client.commands.get(interaction.commandName).execute(interaction); });
内容的提问来源于stack exchange,提问作者João
相关产品推荐
相关产品推荐

