Discord.js消息收集器过滤器失效问题排查
问题:音乐问答机器人无法捕获正确歌名输入,超时才提示无人答对
我开发的音乐问答机器人逻辑是:播放歌曲后询问用户歌名,用户需30秒内输入答案,超时则提示无人答对。但实际运行时,即便输入完全匹配的歌名,机器人毫无响应,必须等30秒超时后才触发提示。
相关代码
const filter = m => m.content.toLowerCase() === item.title.toLowerCase(); // 消息过滤器 interaction.reply({ content: "What is the name of this song?"}) const collector = interaction.channel.createMessageCollector({ filter, time: 30000 }); // 创建消息收集器,超时30秒 collector.on('collect', m => { // 收集到匹配消息时触发 console.log(`Collected ${m.content}`); interaction.followUp(`${m.author} got the correct answer!`) queue.skip() }); collector.on('end', collected => { // 收集器结束时触发 console.log(`Collected ${collected.size} items`); interaction.followUp(`${collected.size} people got the right answer!`) queue.skip() });
歌曲信息对象示例
{ "title": "Uptown Funk", "url": "https://www.youtube.com/watch?v=OPf0YbXqDm0", "singers": ["Mark Ronson", "Bruno Mars"] }
即便输入uptown funk,消息也无法被收集器捕获。
排查与解决方案
1. 确认歌曲标题的正确性
在创建过滤器前打印item.title的值,确保它确实指向当前播放歌曲的标题,避免因对象属性名错误(比如误写为item.name)或item未正确赋值导致匹配失败:
console.log("当前歌曲标题:", item.title); // 检查输出是否为预期的歌名 const filter = m => m.content.toLowerCase() === item.title.toLowerCase();
2. 优化过滤器逻辑
- 排除机器人自身的消息,避免干扰匹配
- 去除用户输入内容的首尾空格,防止因输入时的多余空格导致匹配失败
修改后的过滤器:
const filter = m => !m.author.bot && m.content.trim().toLowerCase() === item.title.toLowerCase();
3. 确保回复发送完成后再创建收集器
interaction.reply是异步操作,使用await确保回复发送完毕后再启动收集,避免潜在的时序问题:
await interaction.reply({ content: "What is the name of this song?" }); const collector = interaction.channel.createMessageCollector({ filter, time: 30000 });
4. 完善收集器事件逻辑
- 收集到正确答案后立即停止收集器,避免重复触发
- 在
end事件中根据收集结果区分提示语,0条时显示“无人答对”:
collector.on('collect', m => { console.log(`Collected ${m.content}`); interaction.followUp(`${m.author} 答对了!`); collector.stop(); // 停止收集器,避免后续消息触发 queue.skip(); }); collector.on('end', collected => { console.log(`共收集到 ${collected.size} 条有效答案`); if (collected.size > 0) { interaction.followUp(`有 ${collected.size} 人答对了!`); } else { interaction.followUp("无人答对,跳过歌曲!"); } queue.skip(); });
5. 检查Discord.js版本兼容性
如果使用v14及以上版本,当前代码的参数格式是符合规范的;如果是旧版本,可添加max: 1参数表示只收集一条正确答案,避免多余匹配:
const collector = interaction.channel.createMessageCollector({ filter, time: 30000, max: 1 });
内容的提问来源于stack exchange,提问作者vixitu
相关产品推荐
相关产品推荐

