Discord.js V14权限检查报错:TypeError读取'has'时未定义
Discord.js V14 权限检查报错:TypeError: Cannot read properties of undefined (reading 'has')
问题场景
开发Discord.js V14机器人时,需要实现以下逻辑:
- 拦截用户发送的链接
- 若发送者是管理员,不做处理
- 若发送者是普通用户,删除消息并提示「No links allowed」
但权限检查部分触发报错:
TypeError: Cannot read properties of undefined (reading 'has') at Client.<anonymous> (/home/runner/sancturopolis-city-assistant/index.js:65:34)
初始代码:
client.on("messageCreate", (message) => { let regexp = /^(?:(?:https?|ftp):\/\/)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/\S*)?$/; if (regexp.test(message.content)) { if ( message.author.permissions.has(PermissionFlagsBits.Administrator) ) { return; } else { message.delete().then(() => { message.channel.send(`**<@${message.author.id}> No links allowed!**`); }); } } });
尝试将message.author.permissions改为message.author.id.permissions后,报错仍未解决。
错误原因
message.author返回的是User对象,仅存储用户的全局基础信息(如ID、用户名),不包含用户在当前服务器的权限数据。权限检查必须使用message.member,它返回的是GuildMember对象,包含用户在当前服务器的角色、权限等专属信息。
修正后的代码
// 确保已正确导入所需模块 const { Client, GatewayIntentBits, PermissionFlagsBits } = require('discord.js'); client.on("messageCreate", async (message) => { // 跳过机器人自身消息和DM频道消息(按需保留) if (message.author.bot || !message.guild) return; const linkRegex = /^(?:(?:https?|ftp):\/\/)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/\S*)?$/; if (linkRegex.test(message.content)) { // 检查用户是否拥有服务器管理员权限 if (message.member.permissions.has(PermissionFlagsBits.Administrator)) { return; } // 异步处理消息删除与提示发送,增加错误捕获 try { await message.delete(); await message.channel.send(`**<@${message.author.id}> No links allowed!**`); } catch (err) { console.error("处理消息时出错:", err); } } });
额外优化说明
- 添加
message.author.bot判断,避免机器人自身消息触发拦截逻辑 - 添加
!message.guild判断,跳过DM频道的消息(若无需处理DM可保留) - 改用
async/await处理异步操作,比.then()更易读且便于错误排查 - 确保机器人账号拥有管理消息权限,否则无法执行删除用户消息的操作
内容的提问来源于stack exchange,提问作者Mohtasim Alam Sohom
相关产品推荐
相关产品推荐

