Discord.js v11临时禁言命令报错:Cannot read property 'roles'/'members' of undefined
解决Discord.js v11 TempMute命令的TypeError问题
看起来你遇到的两个错误都是因为对象未定义导致的,结合你使用的Discord.js v11.6.1版本,我们一步步来排查修复:
第一个错误:TypeError: Cannot read property 'roles' of undefined
这个错误大概率出现在两个地方:
- 权限检查的
message.member.roles.has(...):如果命令在DM中触发,message.member会是undefined - 后续
toMute.roles操作:你写的message.mentions.member.first()是错误的,Discord.js v11中提及成员的属性是复数的members,写错后toMute会变成undefined,访问其roles自然报错
第二个错误:TypeError: Cannot read property 'members' of undefined
这个错误来自message.guild.members.get(args[0]),说明message.guild是undefined——本质还是命令在非服务器环境(比如DM)中执行,你的guildOnly配置可能没被bot加载器正确识别生效。
完整修复方案及代码
1. 核心问题修正
- 把
message.mentions.member.first()改成message.mentions.members.first(),确保正确获取提及成员 - 在命令开头主动检查
message.guild,提前拦截DM中的命令调用 - 初始化
bot.mutes对象,避免直接赋值时报错 - 修正时间计算逻辑:你要的是分钟单位,原来的
*10000是10秒,改成*60*1000转换成分钟对应的毫秒数
2. 添加过期检查定时任务
你需要每3秒检查过期禁言,把这段代码放在bot的主文件(比如index.js)的ready事件中:
const fs = require('fs'); bot.on('ready', () => { // 初始化mutes数据 try { bot.mutes = require('./mutes.json'); } catch (err) { bot.mutes = {}; } setInterval(() => { const now = Date.now(); for (const userId in bot.mutes) { const mute = bot.mutes[userId]; if (now >= mute.time) { const guild = bot.guilds.get(mute.guild); if (!guild) continue; const member = guild.members.get(userId); const role = guild.roles.find(x => x.name === '「」Muted'); if (member && role) member.removeRole(role); delete bot.mutes[userId]; fs.writeFile('./mutes.json', JSON.stringify(bot.mutes, null, 4), err => { if (err) console.error('禁言数据更新失败:', err); }); } } }, 3000); // 每3秒检查一次 });
3. 修正后的完整命令代码
const { RichEmbed } = require('discord.js'); const fs = require('fs'); module.exports.run = async (message, args, bot) => { // 强制限制命令只能在服务器中运行 if (!message.guild) return message.channel.send('Bu komut sadece sunucularda kullanılabilir!'); // 权限检查 if(!message.member.roles.has("675376537272582154")) { return message.channel.send(`Bu komutu kullanabilmek için \`「」Mute Premission\` rolüne sahip olmalısınız.`); } // 获取要禁言的成员(修正为复数members) let toMute = message.mentions.members.first() || message.guild.members.get(args[0]); if(!toMute) return message.channel.send(`:x: Susturulacak kullanıcıyı etiketlemelisin!`); // 处理禁言时间 let timeMute = args[1]; if(!timeMute) return message.channel.send(':x: Susturma süresini dakika cinsinden yazmalısın!'); if(isNaN(timeMute)) return message.channel.send(':x: Senin de bildiğin gibi süre sadece sayı olabilir!'); const muteExpireTime = Date.now() + parseInt(timeMute) * 60 * 1000; // 转换为分钟对应的毫秒 // 处理禁言理由 let reason = args.slice(2).join(" "); if(!reason) return message.channel.send(':x: Susturma sebebini yazmalısın!'); // 自我禁言检查 if(toMute.id === message.author.id) return message.channel.send(`:x: Kendini susturamazsın bea!`); // 权限角色检查 if(toMute.roles.has('675376537272582154')) return message.channel.send(`:x: \`「」Mute Premission\` rolüne sahip olan birini susturamazsın!`); // 获取Muted角色 let role = message.guild.roles.find(x => x.name === '「」Muted'); if(!role) return message.channel.send(':x: \`「」Muted\` adlı rolü bulamıyorum!'); // 检查是否已被禁言 if(toMute.roles.has(role.id)) return message.channel.send(':x: Bu kullanıcı zaten susturulmuş!'); // 获取ModLog频道 let modlog = message.guild.channels.find(c => c.name === '『』punishment'); if(!modlog) return message.channel.send(':x: Mod-Log kanalını bulamıyorum!'); // 创建嵌入消息 const embed = new RichEmbed() .setTitle('Susturma') .setDescription(`**Susturlan Kişi: \`${toMute.user.tag}\`** \n **ID Numarası: \`${toMute.id}\`**\n **Susturan Yetkili: \`${message.author.tag}\`**\n **Süre: \`${timeMute} dakika\`**\n **Sebep: \`${reason}\`** `) .setColor("#ff0000") .setFooter('Kurallara Uymayanın Sonu') .setTimestamp(); // 保存禁言数据 bot.mutes[toMute.id] = { guild: message.guild.id, time: muteExpireTime }; // 添加禁言角色 await toMute.addRole(role); // 写入JSON文件并发送日志 fs.writeFile("./mutes.json", JSON.stringify(bot.mutes, null, 4), err => { if(err) { console.error(err); return message.channel.send(':x: Veri kaydedilirken bir hata oluştu!'); } modlog.send(embed); message.channel.send(`✅ ${toMute.user.tag} başarıyla ${timeMute} dakika boyunca susturuldu!`); }); }; module.exports.conf = { enabled: true, guildOnly: true, aliases: ['sustur'], permLevel: 0 }; module.exports.help = { name: 'mute', description: 'Sustur gitsin', usage: '!sustur @kullanıcı süre sebep' };
额外注意事项
- 确保
mutes.json文件存在于命令同级目录,首次运行时如果文件不存在,代码会自动创建空对象 - 定时任务必须放在bot主文件的
ready事件中,确保bot启动后立即开始检查过期逻辑
内容的提问来源于stack exchange,提问作者BloodStains
相关产品推荐
相关产品推荐

