开发Discord机器人时,一个高频需求就是:机器人收到某条命令后,在回复中点名这条消息的发送者。无论是做欢迎提示、管理员警告,还是简单的命令回执,提及(mention)用户都是提升交互体验的基本功。本文基于Node.js环境下的discord.js库,从消息对象的内部结构入手,讲清楚获取发送者信息的几种方式,并给出能直接运行的代码。

一、从message对象中读取发送者信息
discord.js中,每当有用户发送消息且机器人具有读取权限时,都会触发messageCreate事件,回调函数会传入一个Message对象。这个对象上与发送者相关的属性主要有三个:message.author表示发送这个消息的User对象,包含用户名、ID、头像等;message.member表示该用户在当前服务器中的GuildMember对象,额外带有昵称、角色、加入时间等信息;如果消息来自私信或Webhook,message.member可能为null,这一点要格外注意。
用户ID是提及的关键。Discord的提及机制本质是一个特殊格式的字符串:小于号、艾特符号、用户ID、大于号拼接在一起。客户端渲染时会把这段文本变成可点击的用户标签,同时触发对方的通知。所以只要拿到message.author.id,就能拼出提及文本。
const { Client, GatewayIntentBits } = require('discord.js');
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
GatewayIntentBits.GuildMembers
]
});
client.on('messageCreate', async (message) => {
// 忽略机器人自己的消息,防止死循环
if (message.author.bot) return;
const content = message.content.toLowerCase();
if (content === '!ping') {
// 直接拼接提及格式:<@用户ID>
const mention = `<@${message.author.id}>`;
message.channel.send(`${mention} Pong!延迟正常。`);
}
});
client.login('你的BotToken');二、用reply方法自动提及发送者
除了手动拼接,discord.js提供了更优雅的方式:message.reply()。这个方法会以引用回复的形式发送消息,并且在默认设置下自动在消息开头提及被回复者。它的好处是语义更明确,客户端会显示一条引用线,用户一眼就能看出机器人是在回应哪条命令。
两种方式的区别值得了解。手动拼接<@ID>适合需要灵活控制提及位置的场景,比如在一段长文本中间点名某人,或者同时提及多个用户;而reply()适合一问一答式的命令响应,代码更简洁。如果你希望reply不自动提及,可以传入allowedMentions参数来关闭,这在批量回复时能避免频繁打扰用户。
client.on('messageCreate', async (message) => {
if (message.author.bot) return;
if (message.content === '!info') {
// reply默认会提及发送者
await message.reply('这是你的信息查询结果。');
}
if (message.content === '!quiet') {
// 关闭自动提及,同时不解析用户输入中的提及
await message.reply({
content: '静默回复,不会艾特你。',
allowedMentions: { repliedUser: false }
});
}
});三、提取消息中被提及的用户列表
另一个常见方向是:用户在命令中艾特了某个人,机器人如何识别并操作这个被艾特的用户?Message对象提供了message.mentions属性,其中users是一个Collection,包含消息中所有被提及的用户。注意这里要排除机器人自己,因为很多客户端在回复时会顺带提及机器人,导致机器人误判。
此外还可以结合正则或message.mentions.members获取带服务器信息的成员对象,进而查询其角色、权限。下面的示例实现了一个简单的点名命令:用户输入命令并艾特目标,机器人向目标打招呼。
client.on('messageCreate', async (message) => {
if (message.author.bot) return;
if (message.content.startsWith('!greet')) {
// 过滤掉机器人自身
const target = message.mentions.users.first();
if (!target) {
message.reply('请先艾特一个用户,例如:!greet @某人');
return;
}
message.channel.send(`你好,${target}!${message.author.username} 向你打了个招呼。`);
}
});四、提及无效的常见原因排查
实际开发中,提及不生效通常有以下几种情况。第一,ID拼接出错,比如把用户名当成ID用了,Discord的提及必须使用数字形式的雪花ID,可以通过右键用户头像选择复制用户ID获取(需开启开发者模式)。第二,消息内容被机器人原样转发,客户端把提及文本当普通文字显示,这往往是把消息放进了代码块导致的,代码块内的提及不会被解析。
第三,权限问题。如果机器人缺少发送消息的权限,提及自然无从谈起,建议在发送前用channel.permissionsFor(client.user)做检查。第四,allowedMentions配置过于严格。如果你在ClientOptions里全局设置了allowedMentions: { parse: [] },那么所有提及都会被剥离,需要显式允许users类型的解析。掌握这几个排查点,提及相关的坑基本都能避开。
总结一下:获取发送者靠message.author,点名用户靠<@ID>格式或reply()方法,识别被艾特对象靠message.mentions。三者组合起来,就能覆盖绝大多数交互场景,再配合文中提到的排查思路,你的机器人回复功能会稳定得多。
Discord机器人Node.jsmessage.mentions修改时间:2026-09-07 06:04:30