Discord bot添加search命令后频繁触发垃圾消息发送问题如何修复?
问题根因
你的代码存在3个核心逻辑错误导致异常响应:
- 消息收集器的过滤器用户匹配逻辑错误:直接使用
message.author == author进行对象引用对比,在Discord.js运行时中同一个用户的消息实例可能存在差异,会导致用户身份校验完全失效,收集器会捕获所有内容匹配搜索位置的频道消息。 - 没有过滤bot自身发送的消息:bot输出的可选位置提示本身就包含了完整的位置文本,过滤器失效后bot自己发的提示消息会被收集器误捕获,直接触发奖励发放逻辑。
- 收集器未手动终止:单次收集完成后没有主动销毁收集器,超时前频道内所有符合内容的消息都会持续触发响应。
修复方案
直接替换你的过滤器逻辑和collect事件逻辑即可,修改后的完整代码如下:
const profileModel = require("../models/profileSchema"); module.exports = { name: "search", aliases: [], permissions: [], cooldowns: 30, description: "Search for some coin!", async execute(message, args, cmd, client, Discord, profileData) { const locations = [ "Dragonspine", "Windrise", "Qingyun Peak", "Mt. Hulao", "Mondstadt City", "Springvale", "Kamisato Estate", "Guyun Stone Forest", "Fort Mumei", "Watatsumi Island", ]; const chosenLocations = locations .sort(() => Math.random() - Math.random()) .slice(0, 3); // 修复过滤器:对比用户ID、排除bot消息 const filter = (m) => !m.author.bot && m.author.id === message.author.id && chosenLocations.some( (location) => location.toLowerCase() === m.content.toLowerCase() ); const collector = message.channel.createMessageCollector(filter, { max: 1, time: 30000, }); const earnings = Math.floor(Math.random() * (1000 - 100 + 1)) + 100; collector.on("collect", async (m) => { // 触发后手动停止收集器,避免残留 collector.stop('completed'); message.channel.send(`You found ${earnings} primogems !`); await profileModel.findOneAndUpdate( { userID: message.author.id, }, { $inc: { primogems: earnings, }, } ); }); collector.on("end", (collected, reason) => { if (reason == "time") { message.channel.send("You ran out of time!"); } }); message.channel.send( `<@${ message.author.id }> **Which location would you like to search?\n** Type the location in this channel\n \`${chosenLocations.join( "` `" )}\`` ); }, };
另外建议你在全局的消息监听事件最开头加一段判断,忽略所有bot发送的消息,避免后续其他命令也出现同类问题:
client.on('messageCreate', message => { // 全局忽略bot消息,放在逻辑最开头 if(message.author.bot) return; // 后续命令处理逻辑 })
内容的提问来源于stack exchange,提问作者mango
相关产品推荐
相关产品推荐

