Discord.js开发mute命令报ReferenceError: time is not defined错误求解
问题排查与修复方案
核心错误原因
你的time变量定义在setTimeout的回调函数内部,而setTimeout的第二个延迟参数需要在调用定时器时就传入,此时回调函数还未执行,外层作用域无法访问到内部定义的time变量,直接触发ReferenceError。
同时你的逻辑存在倒置:setTimeout应该用来实现到期自动解除禁言,而不是延迟执行禁言逻辑,你当前把全部禁言逻辑都塞进了定时器回调里,完全不符合预期功能。
其他已知问题
- 参数取值错误:常规
mute命令格式为/mute @用户 时长 原因,时长应该从args[1]取,你当前取args[2]会把原因的第一个内容误认为时长 - 异步操作未加
await:创建禁言角色、修改频道权限、给用户加角色都是异步操作,不加await会出现逻辑时序错误 - 语法版本不兼容:你使用的
createRole、addRole、roles.find都是Discord.js v11的废弃语法,v12+版本需要调整为roles.create、roles.add、roles.cache.find - 废弃API调用:
RichEmbed在v12+版本已经被MessageEmbed替代,直接调用会报错 - 权限名拼写错误:发送消息权限是
SEND_MESSAGES(复数),你写成了单数 - 方法名拼写错误:
toLocaleAString多打了一个A,正确为toLocaleString - 缺少自动解除禁言逻辑:你定义了
time变量但没有实现到期移除禁言角色的逻辑
修复后完整代码(适配Discord.js v12+)
const { MessageEmbed } = require('discord.js'); module.exports = { name: "mute", aliases: ["mutes", "muted"], category: "moderation", description: "禁言指定用户", run: async(client, message, args) => { // 权限校验先执行,不要放到定时器里 if(!message.member.permissions.has("MANAGE_ROLES")) return message.channel.send("你没有执行该命令的权限"); if(!message.guild.me.permissions.has("MANAGE_ROLES")) return message.channel.send("我没有管理角色的权限,无法执行禁言操作"); // 取被禁言用户 let muteMember = message.mentions.members.first() || message.guild.members.cache.get(args[0]); if(!muteMember) return message.channel.send("请指定要禁言的用户"); // 取时长和原因 let time = parseInt(args[1]) * 60000; if(isNaN(time)) return message.channel.send("请输入有效的禁言时长(单位:分钟)"); let reason = args.slice(2).join(" ") || "未提供禁言原因"; // 找或创建禁言角色 let muteRole = message.guild.roles.cache.find(role => role.name === "Muted"); if(!muteRole) { try { muteRole = await message.guild.roles.create({ name: "Muted", permissions: [] }); // 批量设置频道权限 for (const channel of message.guild.channels.cache.values()) { await channel.permissionOverwrites.edit(muteRole, { SEND_MESSAGES: false, ADD_REACTIONS: false, SEND_TTS_MESSAGES: false, ATTACH_FILES: false, SPEAK: false }); } } catch (e) { console.log(e.stack); return message.channel.send("创建禁言角色失败,请检查我的权限"); } } // 执行禁言 try { await muteMember.roles.add(muteRole.id); message.delete(); muteMember.send(`你在${message.guild.name}被禁言,原因:${reason},时长:${args[1]}分钟`).catch(err => console.log(err)); message.channel.send(`${muteMember.user.username}已被成功禁言`); // 发送日志 let muteEmbed = new MessageEmbed() .setColor("#FF0000") .addField(" moderation action", "mute") .addField("被禁言用户", muteMember.user.username) .addField("操作人", message.author.username) .addField("原因", reason) .addField("时间", message.createdAt.toLocaleString()); let modChannel = message.guild.channels.cache.find(channel => channel.name === "mod-log"); if(modChannel) modChannel.send(muteEmbed); // 定时解除禁言 setTimeout(async () => { await muteMember.roles.remove(muteRole.id); muteMember.send(`你在${message.guild.name}的禁言已到期`).catch(err => console.log(err)); }, time); } catch (e) { console.log(e.stack); return message.channel.send("禁言操作失败,请检查我的权限等级是否高于被禁言用户"); } }, };
命令使用说明
使用格式:!mute @被禁言用户 禁言时长(分钟) 禁言原因
示例:!mute @张三 10 刷屏
内容的提问来源于stack exchange,提问作者Crazy Gladiator
相关产品推荐
相关产品推荐

