You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord bot添加search命令后频繁触发垃圾消息发送问题如何修复?

问题根因

你的代码存在3个核心逻辑错误导致异常响应:

  1. 消息收集器的过滤器用户匹配逻辑错误:直接使用message.author == author进行对象引用对比,在Discord.js运行时中同一个用户的消息实例可能存在差异,会导致用户身份校验完全失效,收集器会捕获所有内容匹配搜索位置的频道消息。
  2. 没有过滤bot自身发送的消息:bot输出的可选位置提示本身就包含了完整的位置文本,过滤器失效后bot自己发的提示消息会被收集器误捕获,直接触发奖励发放逻辑。
  3. 收集器未手动终止:单次收集完成后没有主动销毁收集器,超时前频道内所有符合内容的消息都会持续触发响应。

修复方案

直接替换你的过滤器逻辑和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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 22:45:02