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

如何在Discord.js中为特定用户的所有命令设置冷却机制

如何为特定用户的所有命令设置统一冷却时间?

看起来你现在的冷却逻辑只绑定在单个命令里,所以只有那个命令会触发冷却,其他命令不受影响对吧?要实现全命令统一冷却,核心是把冷却状态改成全局共享的,让所有命令都共用同一个检查逻辑。我给你拆解一下具体怎么做:


第一步:全局维护冷却用户集合

首先,你需要把存储冷却用户ID的talkedRecently集合定义在所有命令代码之外(比如文件最顶部),这样所有命令都能访问到同一个集合,而不是每个命令各自维护自己的集合:

// 在文件最顶部全局定义,确保所有命令都能访问
const talkedRecently = new Set();

第二步:封装公共冷却检查函数

为了避免每个命令都写重复的冷却代码,我们把检查逻辑封装成一个公共函数,这样每个命令只需要调用这个函数就行:

/**
 * 检查用户是否处于全局冷却中
 * @param {object} msgOrInteraction - 消息或交互对象(适配普通消息和slash命令)
 * @param {number} cooldownTime - 冷却时长,默认6000毫秒(6秒)
 * @returns {boolean} - true表示处于冷却中,false表示可以执行命令
 */
function checkGlobalCooldown(msgOrInteraction, cooldownTime = 6000) {
  const userId = msgOrInteraction.author?.id || msgOrInteraction.user?.id;
  if (!userId) return false; // 非用户消息直接跳过

  if (talkedRecently.has(userId)) {
    const replyText = `Wait before using any commands again. - ${msgOrInteraction.author || msgOrInteraction.user}`;
    // 适配普通消息和slash命令的回复方式
    if (msgOrInteraction.channel) {
      msgOrInteraction.channel.send(replyText);
    } else if (msgOrInteraction.reply) {
      msgOrInteraction.reply(replyText);
    }
    return true;
  }

  // 不在冷却中,添加到集合并设置超时移除
  talkedRecently.add(userId);
  setTimeout(() => {
    talkedRecently.delete(userId);
  }, cooldownTime);
  return false;
}

第三步:在所有命令中应用检查

不管是普通前缀命令还是slash命令,都在命令逻辑的最开头调用这个检查函数,如果返回true就直接终止命令执行,否则继续:

示例1:普通前缀命令

client.on('messageCreate', (msg) => {
  // 忽略机器人自己的消息
  if (msg.author.bot) return;

  if (msg.content === '!hello') {
    // 先检查全局冷却
    if (checkGlobalCooldown(msg)) return;
    // 这里写!hello命令的逻辑
    msg.channel.send(`Hello ${msg.author}!`);
  }

  if (msg.content === '!help') {
    if (checkGlobalCooldown(msg)) return;
    // !help命令的逻辑
    msg.channel.send('Here are my commands: !hello, !help');
  }
});

示例2:Slash命令(Discord.js v14+)

// 假设你有一个hello的slash命令
module.exports = {
  data: new SlashCommandBuilder()
    .setName('hello')
    .setDescription('Say hello to me'),
  async execute(interaction) {
    // 检查全局冷却
    if (checkGlobalCooldown(interaction)) return;
    // 命令逻辑
    await interaction.reply(`Hello ${interaction.user}!`);
  },
};

这样修改后,用户只要触发了任意一个命令,接下来的所有命令都会进入冷却状态,直到设定的时长结束后才能再次使用任何命令,完美实现你想要的全局冷却效果。

内容的提问来源于stack exchange,提问作者Wide

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:34:11