使用Discord.js创建Discord机器人时,如何获取消息作者的角色?
在Discord.js中获取消息作者的角色
嘿,我太懂这种查了一堆资料却找不到可行方法的烦躁了——毕竟Discord.js不同版本的API变化真的不小,很容易看了旧文档白忙活。我帮你分版本理清楚,保证能直接用上:
先确认你的Discord.js版本
目前主流是v14及以上,如果你还在用v12这类旧版本,写法会有差异,先在终端跑npm list discord.js确认自己的版本。
情况1:Discord.js v14+(推荐)
v14里,message.author是User对象(代表全局用户),它没有角色信息——角色是服务器(Guild)专属的,所以得用message.member(GuildMember对象,用户在当前服务器的身份)来获取角色。
举个完整的监听消息并获取角色的示例:
// 导入必要模块(v14需要显式声明Intent权限) const { Client, GatewayIntentBits } = require('discord.js'); const client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent // 必须开启这个才能读取消息内容 ] }); client.on('messageCreate', (message) => { // 跳过DM消息(DM里没有member对象) if (!message.inGuild()) return; // 获取该成员的所有角色缓存(是一个Collection集合) const userRoles = message.member.roles.cache; // 1. 打印所有角色名称(想排除@everyone看下面) const roleNames = userRoles.map(role => role.name); console.log(`${message.author.tag} 的角色:`, roleNames); // 2. 检查用户是否拥有某个特定角色(用ID比名称更可靠,避免重名) const targetRoleId = '你的目标角色ID'; if (userRoles.has(targetRoleId)) { message.reply('你拥有我要找的角色!'); // 这里可以执行你的特定功能逻辑 } // 3. 排除@everyone角色(@everyone的ID等于当前服务器ID) const rolesWithoutEveryone = userRoles.filter(role => role.id !== message.guild.id); const cleanRoleNames = rolesWithoutEveryone.map(role => role.name); console.log(`${message.author.tag} 的自定义角色:`, cleanRoleNames); }); client.login('你的机器人Token');
情况2:Discord.js v12(旧版本)
v12的核心逻辑和v14一致,主要是事件名称和权限设置不同:
- 监听消息用
message事件而非messageCreate - 不需要显式声明GatewayIntentBits,但要确保机器人后台开启了相应权限
示例代码:
const Discord = require('discord.js'); const client = new Discord.Client(); client.on('message', (message) => { // 跳过DM消息 if (!message.guild) return; const userRoles = message.member.roles.cache; // 同样的操作逻辑 const roleNames = userRoles.map(role => role.name); console.log(`${message.author.tag} 的角色:`, roleNames); // 检查特定角色 if (userRoles.has('目标角色ID')) { message.reply('权限验证通过!'); } }); client.login('你的机器人Token');
关键注意事项
- 必须确保机器人开启了服务器成员权限和消息读取权限,否则无法获取
member对象或消息内容 - 永远优先用角色ID判断权限,而不是角色名称——名称可以被修改,ID是唯一不变的
- DM消息里没有
member对象,一定要先判断消息是否来自服务器
内容的提问来源于stack exchange,提问作者Smir




