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

Discord.js消息收集器计时器重置及结束阶段回复问题求助

Discord.js消息收集器计时器重置及结束阶段回复问题求助

嘿,我看你碰到了两个关于Discord.js消息收集器的小问题:一是想让收集器在用户5分钟未输入时自动结束,且用户输入后能重置计时器;二是收集器结束时没法发送新回复的困扰。咱们一步一步来解决~

问题1:实现「用户5分钟未输入自动结束,输入后重置计时器」

你当前代码里的time: 300000确实设置了5分钟超时,但这个计时器是从收集器创建时开始计算的——哪怕用户中途输入了消息,到点还是会自动结束,这显然不是你想要的效果。另外代码里的max: 1会让收集器只收一条消息就停止,得先把这个去掉,才能实现无限收集直到超时或用户主动停止。

解决办法很简单:每次收集到用户消息时,调用收集器的resetTimer()方法,把计时器从当前时间重新开始计算。同时可以保留你想要的「输入stop手动结束」的逻辑,具体代码修改如下:

const collector = interaction.channel.createMessageCollector({
  filter: (msg) => msg.author.id === interaction.user.id,
  time: 300000, // 5分钟超时,单位毫秒
});

collector.on("collect", (msg) => {
  // 先判断用户是否输入stop,手动终止收集器
  if (msg.content.toLowerCase() === "stop") {
    collector.stop("user-initiated");
    return;
  }
  textToSpeech(msg.content);
  collector.resetTimer(); // 关键:每次收到消息就重置计时器
});

这样一来,只要用户一直在输入,计时器就会不断重置;一旦用户超过5分钟没说话,收集器就会自动触发end事件。

问题2:收集器结束时发送回复的限制

你遇到的「一个交互只能回复一次」是Discord的规则——interaction.reply()只能调用一次,但我们可以用interaction.followUp()来发送后续消息,它会和最初的回复显示在同一个对话串里,完美解决这个问题。

修改end事件的代码,把原来的interaction.reply()换成interaction.followUp(),还可以根据收集器结束的原因(用户主动停止/超时)发送不同提示,体验更好:

collector.on("end", (collected, reason) => {
  let endMessage;
  switch (reason) {
    case "user-initiated":
      endMessage = "已根据你的指令停止echo功能,我不会再重复你的输入啦~";
      break;
    case "time":
      endMessage = "5分钟没收到你的输入,echo功能已自动停止。";
      break;
    default:
      endMessage = "echo功能已结束。";
  }
  interaction.followUp(endMessage);
});

完整修改后的代码

这里给你整合了所有优化点的完整代码,还把判断频道类型的数字换成了更易读的ChannelType枚举:

import { SlashCommandBuilder, ChannelType } from "discord.js";
import { command, textToSpeech } from "../../utils";

const meta = new SlashCommandBuilder()
  .setName("echo")
  .setDescription("I'll say in voice whatever you type.");

export default command(meta, ({ interaction }) => {
  if (!interaction.channel) {
    return interaction.reply(`You can't use this command here.`);
  }

  // 用ChannelType枚举替代数字0,代码更易维护
  if (interaction.channel.type !== ChannelType.GuildText) {
    return interaction.reply(`I can't read your messages here.`);
  }

  // 初始回复里加上stop提示,让用户知道怎么主动终止
  interaction.reply(`Now I'll say everything you type. Type "stop" to end early.`);

  const collector = interaction.channel.createMessageCollector({
    filter: (msg) => msg.author.id === interaction.user.id,
    time: 300000, // 5分钟超时
  });

  collector.on("collect", (msg) => {
    if (msg.content.toLowerCase() === "stop") {
      collector.stop("user-initiated");
      return;
    }
    textToSpeech(msg.content);
    collector.resetTimer(); // 重置计时器
  });

  collector.on("end", (collected, reason) => {
    let endMsg;
    switch (reason) {
      case "user-initiated":
        endMsg = "You've stopped the echo command. I won't repeat your messages anymore.";
        break;
      case "time":
        endMsg = "5 minutes have passed without any input. The echo command has ended automatically.";
        break;
      default:
        endMsg = "The echo command has ended.";
    }
    interaction.followUp(endMsg);
  });
});

备注:内容来源于stack exchange,提问作者Ckemill

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 14:23:03