You need to enable JavaScript to run this app. discord.js角色差异化命令冷却下humanize-duration时间显示异常问题
优惠活动
大模型
产品
解决方案
定价
更多

discord.js角色差异化命令冷却下humanize-duration时间显示异常问题

核心问题原因

  1. 存储结构选型错误:你使用Set存储处于冷却的用户ID,仅能记录「用户是否在冷却中」,无法存储用户触发命令的时间戳,导致剩余冷却时间计算逻辑完全错误。
  2. 计算逻辑错误:你在计算remaining时,直接拿返回布尔值的判断表达式cooldown.has(xxx) && xxx做减法运算,布尔值在数值运算中会被隐式转换为1(true)或0(false),最终得到的是负数时间戳,humanize-duration处理这类非法输入自然无法输出正确结果。
  3. 冷却时长配置写反:需求是普通用户冷却20秒、特权角色冷却10秒,你代码里普通用户的setTimeout设了10000ms(10秒)、特权角色设了2000ms(2秒),完全不符合需求。
  4. 冗余无效逻辑:setTimeout内的cooldown.delete(xxx) && 权限判断逻辑完全无效,Set.delete()返回布尔值,后续的表达式不会产生任何实际作用。

修正后的代码

const Discord = require("discord.js");
const humanizeDuration = require("humanize-duration");

// 改用Map存储,key为用户ID,value为用户触发命令的时间戳
const cooldown = new Map();
// 提前定义配置项,后续修改更方便
const BOOSTER_ROLE_ID = "830503345251680298";
const DEFAULT_COOLDOWN = 20 * 1000; // 普通用户20秒
const BOOSTER_COOLDOWN = 10 * 1000; // 特权用户10秒
const GUILD_ID = "828376495969402901";

module.exports = {
  name: "ping",
  description: "It shows the bot latency.",
  
  execute(client, message, args) {
    const guild = client.guilds.cache.get(GUILD_ID);
    const member = guild.members.cache.get(message.author.id);
    const isBooster = member.roles.cache.has(BOOSTER_ROLE_ID);
    const userCooldown = isBooster ? BOOSTER_COOLDOWN : DEFAULT_COOLDOWN;

    // 判断用户是否在冷却中
    if (cooldown.has(message.author.id)) {
      const useTime = cooldown.get(message.author.id);
      const remaining = useTime + userCooldown - Date.now();
      // 剩余时间大于0才返回冷却提示
      if (remaining > 0) {
        const remainingText = humanizeDuration(remaining, { units: ["s"], round: true, language: "en" });
        const cooldownEmbed = new Discord.MessageEmbed()
          .setTitle(isBooster ? `Too fast` : `Slow down, bud`)
          .setDescription(isBooster 
            ? `You can run this command again in **${remainingText}**. (booster perk)`
            : `You can run \`ping\` again in **${remainingText}**.\nThe default cooldown is \`20s\`, but boosters can only wait \`10s\`!`
          )
          .setColor(`RANDOM`);
        return message.channel.send(cooldownEmbed);
      }
    }

    // 记录用户当前触发命令的时间
    cooldown.set(message.author.id, Date.now());
    // 到时间后清除冷却记录
    setTimeout(() => {
      cooldown.delete(message.author.id);
    }, userCooldown);

    // 原有ping逻辑不变,修改变量名避免冲突
    message.channel.send('Pinging...').then(sentMsg => {
      const embed = new Discord.MessageEmbed()
        .setDescription(`Pong! :ping_pong: \`${Date.now() - sentMsg.createdTimestamp} ms\``)
        .setColor(`RANDOM`);
      sentMsg.edit(" ", embed);
    })
  }
}

额外优化点

  • 把固定配置项统一提取到代码顶部,后续修改不需要改动业务逻辑
  • 冗余的重复判断逻辑合并,代码可读性更高
  • 增加剩余时间合法性判断,避免输出异常数值
  • 修复了回调函数内变量名和外层变量冲突的潜在问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 21:06:05