discord.js v12 switch case+push方法实现申请功能的逻辑错误排查
问题定位与修复方案
运行环境
- Discord.js@v12.5.3
- Node v14.17.3
核心错误点
- 当前生效的
collector.on("collect")逻辑完全没有调用答案校验函数geraFunkcija,无论用户输入内容是什么都会直接跳转到下一题,你之前写了带校验逻辑的collect事件被注释废弃了。 geraFunkcija没有返回校验状态标识,上层逻辑无法判断用户答案是否正确,无法控制是否需要停在当前题让用户重试。collector.on('end')事件里错误调用了geraFunkcija(collected[index-1]),index变量在初始化问题列表时已经自增到3,collected[index-1]永远取不到有效值,必然触发switch的default分支,所以才会不管用户答案对错都弹出错误提示。- 每次执行
apply命令都会重复注册messageReactionAdd事件监听,会导致内存泄漏、同一次申请多次触发回调的问题。 - 生成申请结果Embed时,直接将整个answers数组拼入每一行问题,会导致答案展示混乱。
修复后核心代码
const { Client, Message, MessageEmbed, ReactionCollector } = require('discord.js'); const button = require('./button'); const APPS_CHANNEL_ID = '904003816876285973'; module.exports = { name: 'apply', /** * @param {Client} client * @param {Message} message * @param {String[]} args */ run: async (client, message, args) => { const Moduliai = [ `1) lt?`, `2) it?` ]; let collectCounter = 0; const filter = (m) => m.author.id === message.author.id; const appsChannel = client.channels.cache.get(APPS_CHANNEL_ID); const appStart = await message.channel.send(Moduliai[collectCounter++]); const channel = appStart.channel; const collector = channel.createMessageCollector(filter); const answers = []; // 校验函数新增返回值,true为答案正确,false为错误 const geraFunkcija = (expr) => { const content = expr.trim().toLowerCase(); switch (content) { case "lt": case "lietuvių": case "lietuviu": message.channel.send('lt'); return true; case "it": case "info": case "informacinės": case "informacinių": case "informaciniu tech": case "informaciniu technologiju": case "informacinių technologijų": message.channel.send('it'); return true; default: console.log('Try again') message.channel.send('wrong answer, try again'); channel.send(Moduliai[collectCounter-1]); return false; } } collector.on("collect", async (m) => { const isRight = geraFunkcija(m.content); // 答案错误不跳题,直接返回 if(!isRight) return; answers.push(m.content); if(collectCounter < Moduliai.length) { await channel.send(Moduliai[collectCounter++]) console.log(`${m.content}`) } else { message.reply('application was sent.') collector.stop("fulfilled"); } }); collector.on('end', async (collected, reason) => { console.log(`${collected.size}`) if(reason === "fulfilled") { const answersStep = collected.map((msg, idx) => { return `${Moduliai[idx]}\n-> ${answers[idx]}`; }) const embed = new MessageEmbed() .setAuthor(message.author.tag, message.author.displayAvatarURL({dynamic: true}) ) .setTitle('New Application') .setDescription(answersStep.join('\n\n')) .setTimestamp(); const sent = await appsChannel.send(embed); await sent.react("✅") await sent.react("❌") } }); } }; // 反应监听放到全局,只注册一次,避免内存泄漏 client.on('messageReactionAdd', async (reaction, user) => { if(reaction.message.channel.id !== APPS_CHANNEL_ID || user.bot) return; const applyEmbed = reaction.message.embeds[0]; if(!applyEmbed || applyEmbed.title !== 'New Application') return; const guild = reaction.message.guild; if(user.id !== guild.ownerID) return; // 从embed.author提取申请人信息,补充通过/拒绝后的逻辑即可 if (reaction.emoji.name === '✅') { // 申请通过逻辑 } else if (reaction.emoji.name === '❌') { // 申请拒绝通知逻辑 } });
补充优化说明
- 校验函数统一将用户输入转小写,避免大小写不一致导致的误判。
- 调整了答案拼接逻辑,每个问题对应自己的答案,展示更清晰。
内容的提问来源于stack exchange,提问作者Term
相关产品推荐
相关产品推荐

