如何为Discord.js机器人实现基于Top.gg投票的差异化命令冷却?
解决Discord.js命令冷却区分投票用户的问题
问题根源
你当前代码的核心问题是:CommandCooldown实例固定用10秒创建,且添加冷却时未根据用户投票状态调整时长,导致无论用户是否投票,冷却时间始终为10秒,无法实现差异化规则。
修复方案
以下提供两种可行的实现方式,均基于你使用的discord-command-cooldown包:
方式一:创建独立冷却实例区分用户
为普通用户和投票用户分别创建对应时长的冷却实例,根据投票状态切换使用:
client.on("message", async (message) => { if (message.content.substring(0, 2) !== "B!") return; const botId = client.user.id; const uId = message.author.id; const url = `https://top.gg/api/bots/${botId}/check?userId=${uId}`; // 初始化两个冷却实例,对应不同用户组的时长 const normalCooldown = new CommandCooldown('ask2_normal', ms('10s')); const votedCooldown = new CommandCooldown('ask2_voted', ms('5s')); try { // 获取用户投票状态 const res = await fetch(url, { method: "GET", headers: { Authorization: "top.gg bot token" } }); const data = await res.json(); const isVoted = data.voted === 1; // 根据投票状态选择对应的冷却实例 const targetCooldown = isVoted ? votedCooldown : normalCooldown; const isOnCooldown = await targetCooldown.getUser(uId); if (isOnCooldown) { const waitTime = isVoted ? '5秒' : '10秒'; return message.channel.send(`**你需要等待${waitTime}才能再次使用ask命令**`); } // 执行你的命令逻辑 // ... 这里写命令的具体代码 ... // 为用户添加对应时长的冷却 await targetCooldown.addUser(uId); } catch (err) { console.error('处理冷却或投票状态出错:', err); message.channel.send('请求处理失败,请稍后重试'); } });
方式二:动态指定冷却时长(需包支持)
如果discord-command-cooldown的addUser方法支持传入自定义时长参数(可查看包文档确认),可以用单个实例动态调整:
client.on("message", async (message) => { if (message.content.substring(0, 2) !== "B!") return; const botId = client.user.id; const uId = message.author.id; const url = `https://top.gg/api/bots/${botId}/check?userId=${uId}`; // 创建通用冷却实例 const askCooldown = new CommandCooldown('ask2', ms('10s')); try { const res = await fetch(url, { method: "GET", headers: { Authorization: "top.gg bot token" } }); const data = await res.json(); const isVoted = data.voted === 1; const cooldownDuration = isVoted ? ms('5s') : ms('10s'); const isOnCooldown = await askCooldown.getUser(uId); if (isOnCooldown) { const waitTime = isVoted ? '5秒' : '10秒'; return message.channel.send(`**你需要等待${waitTime}才能再次使用ask命令**`); } // 执行你的命令逻辑 // ... 这里写命令的具体代码 ... // 动态添加对应时长的冷却(需包支持该参数) await askCooldown.addUser(uId, cooldownDuration); } catch (err) { console.error('出错:', err); message.channel.send('请求处理失败'); } });
额外注意事项
- 用
async/await替代.then()链式调用,代码更易维护且便于错误捕获 - 确保
top.gg令牌有效,且机器人已在平台完成注册 - 建议添加错误处理逻辑,避免API请求失败导致机器人崩溃
内容的提问来源于stack exchange,提问作者GEYO 5
相关产品推荐
相关产品推荐

