Discord.js如何让机器人显示数秒输入状态并设置命令响应冷却?
Discord.js 实现命令冷却+正在输入状态方案
核心实现逻辑
- 命令触发后先调用
sendTyping()接口让机器人显示正在输入状态 - 用
Map存储用户冷却状态避免重复触发 - 通过
setTimeout控制冷却时长,冷却结束后执行实际命令逻辑
完整示例代码(适用于Discord.js v14版本)
斜杠交互命令版本
// 存储用户冷却状态,key为用户ID,value为冷却到期时间戳 const userCooldowns = new Map(); const DEFAULT_COOLDOWN = 3000; // 默认冷却时长3秒,可自行修改 client.on('interactionCreate', async interaction => { if (!interaction.isChatInputCommand()) return; const userId = interaction.user.id; // 冷却校验 if (userCooldowns.has(userId)) { return interaction.reply({ content: '操作过于频繁,请稍后再试', ephemeral: true // 仅触发用户可见 }); } try { // 触发正在输入状态 await interaction.channel.sendTyping(); // 标记用户进入冷却 userCooldowns.set(userId, Date.now() + DEFAULT_COOLDOWN); // 冷却到期后自动移除标记 setTimeout(() => userCooldowns.delete(userId), DEFAULT_COOLDOWN); // 冷却结束后执行实际命令逻辑 setTimeout(async () => { // 这里替换为你的实际命令响应代码 await interaction.reply(`命令 \`${interaction.commandName}\` 执行完成`); }, DEFAULT_COOLDOWN); } catch (error) { console.error('命令执行出错', error); // 出错时清除用户冷却状态避免卡冷却 userCooldowns.delete(userId); } });
前缀消息命令版本
const PREFIX = '!'; // 你的命令前缀 const userCooldowns = new Map(); const DEFAULT_COOLDOWN = 2000; // 默认冷却2秒 client.on('messageCreate', async message => { if (!message.content.startsWith(PREFIX) || message.author.bot) return; const userId = message.author.id; if (userCooldowns.has(userId)) { return message.reply('操作过于频繁,请稍后再试'); } try { await message.channel.sendTyping(); userCooldowns.set(userId, Date.now() + DEFAULT_COOLDOWN); setTimeout(() => userCooldowns.delete(userId), DEFAULT_COOLDOWN); setTimeout(async () => { // 替换为你的实际命令响应代码 await message.reply('命令执行完成'); }, DEFAULT_COOLDOWN); } catch (error) { console.error('命令执行出错', error); userCooldowns.delete(userId); } });
注意事项
- 单次调用
sendTyping()触发的正在输入状态仅持续5秒,如果你的冷却时长超过5秒,需要在冷却期间每隔4秒重新调用一次该接口维持状态 sendTyping()需要机器人拥有对应频道的发送消息、读取消息历史权限,否则会调用失败- 可以为不同命令单独配置冷却时长,无需统一使用全局冷却值
内容的提问来源于stack exchange,提问作者BGamerManu
相关产品推荐
相关产品推荐

