Discord.js v14临时角色定时器无法延长及角色判断异常问题
问题解决方案
问题1:定时器无法跨命令延长/缩短
原因
每个命令模块单独定义了userTimeouts变量,导致不同命令的定时器存储在独立对象中,新命令无法清除旧命令设置的定时器。另外,直接用user对象作为键存在不稳定风险(对象转字符串可能出现不一致)。
解决方法
- 全局共享定时器存储:创建独立文件存放
userTimeouts,让所有命令模块引入同一个对象,确保跨命令能访问到同一定时器记录。 - 使用用户ID作为键:用
user.id代替user对象作为userTimeouts的键,避免对象转字符串的潜在问题,保证键的唯一性和稳定性。
问题2:角色判断始终错误(总是走if分支)
原因
member.roles.cache.has(role)传入的是Role对象,但Discord.js的Collection.has()方法是根据键(角色ID字符串)判断存在性,传入对象会导致判断失效,始终返回false。
解决方法
将判断条件改为!member.roles.cache.has(role.id),通过角色ID来检查成员是否拥有目标角色。
修改后的代码示例
第一步:创建全局定时器存储文件
新建utils/userTimeouts.js:
module.exports = {};
第二步:/pug1命令代码
const { SlashCommandBuilder, EmbedBuilder } = require('discord.js'); const userTimeouts = require('../utils/userTimeouts.js'); module.exports = { data: new SlashCommandBuilder() .setName("pug1") .setDescription("Adds the user to the PUG Queue for 1 hour."), async execute(interaction) { const userId = interaction.user.id; const role = interaction.guild.roles.cache.find(r => r.name === 'PUG Queue'); if (!role) return await interaction.reply({ content: "角色不存在!", ephemeral: true }); const member = await interaction.guild.members.fetch(userId); // 清除旧定时器 if (userTimeouts[userId]) { clearTimeout(userTimeouts[userId]); delete userTimeouts[userId]; } // 添加角色(如果用户还没有) if (!member.roles.cache.has(role.id)) { await member.roles.add(role); console.log(`给用户${userId}添加PUG Queue角色`); } else { console.log(`用户${userId}已拥有PUG Queue角色,重置定时器`); } // 设置新的1小时定时器 userTimeouts[userId] = setTimeout(async () => { if (member.roles.cache.has(role.id)) { await member.roles.remove(role); console.log(`移除用户${userId}的PUG Queue角色`); } delete userTimeouts[userId]; }, 3600000); const embed = new EmbedBuilder() .setDescription(`已将${interaction.user}加入PUG Queue,时长1小时`) .setColor(0x4169E1); await interaction.reply({ embeds: [embed], ephemeral: false }); } };
第三步:/pug30命令代码(同理修改)
const { SlashCommandBuilder, EmbedBuilder } = require('discord.js'); const userTimeouts = require('../utils/userTimeouts.js'); module.exports = { data: new SlashCommandBuilder() .setName("pug30") .setDescription("Adds the user to the PUG Queue for 30 minutes."), async execute(interaction) { const userId = interaction.user.id; const role = interaction.guild.roles.cache.find(r => r.name === 'PUG Queue'); if (!role) return await interaction.reply({ content: "角色不存在!", ephemeral: true }); const member = await interaction.guild.members.fetch(userId); // 清除旧定时器 if (userTimeouts[userId]) { clearTimeout(userTimeouts[userId]); delete userTimeouts[userId]; } // 添加角色(如果用户还没有) if (!member.roles.cache.has(role.id)) { await member.roles.add(role); console.log(`给用户${userId}添加PUG Queue角色`); } else { console.log(`用户${userId}已拥有PUG Queue角色,重置定时器`); } // 设置新的30分钟定时器 userTimeouts[userId] = setTimeout(async () => { if (member.roles.cache.has(role.id)) { await member.roles.remove(role); console.log(`移除用户${userId}的PUG Queue角色`); } delete userTimeouts[userId]; }, 1800000); const embed = new EmbedBuilder() .setDescription(`已将${interaction.user}加入PUG Queue,时长30分钟`) .setColor(0x4169E1); await interaction.reply({ embeds: [embed], ephemeral: false }); } };
内容的提问来源于stack exchange,提问作者Mythic-ctrl
相关产品推荐
相关产品推荐

