使用discord.js如何获取频道内所有被提及的用户
Discord.js 获取指定频道内所有提及用户的实现方案
前置准备
- 初始化客户端时需要开启
Guilds、GuildMessages两个必填意图,否则无法正常拉取频道消息 - 机器人需要拥有目标频道的读取消息历史(ReadMessageHistory)权限,否则会因为权限不足拉取不到消息数据
- 提前获取目标频道的ID,用于定位要查询的频道
核心实现逻辑
Discord接口拉取历史消息时单次最多返回100条,因此需要通过分页标记循环拉取频道的全部历史消息,遍历每条消息自带的提及用户字段,最终通过Map结构对重复提及的用户做去重处理。
参考代码(适配discord.js v14版本)
const { Client, GatewayIntentBits } = require('discord.js'); const client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages ] }); client.once('ready', async () => { console.log(`机器人已启动,登录身份:${client.user.tag}`); // 替换为你要查询的目标频道ID const TARGET_CHANNEL_ID = '你的目标频道ID'; const targetChannel = await client.channels.fetch(TARGET_CHANNEL_ID); // 用Map存储提及的用户,自动按用户ID去重 const mentionedUserMap = new Map(); // 分页标记:记录上次拉取的最早一条消息ID,用于拉取更早的历史消息 let lastFetchedMessageId = undefined; // 循环分页拉取消息直到频道消息全部拉完 while (true) { // 单次最多拉取100条消息,before参数指定拉取该ID之前的消息 const messageBatch = await targetChannel.messages.fetch({ limit: 100, before: lastFetchedMessageId }); // 没有更多可拉取的消息时跳出循环 if (messageBatch.size === 0) break; // 遍历当前批次的消息,提取提及的用户 messageBatch.forEach(message => { // message.mentions.users 仅包含消息中提及的用户对象,自动过滤@everyone、@角色等非用户提及 message.mentions.users.forEach(user => { // 如果需要排除机器人账号,可以在此处加判断:if (!user.bot) { ... } mentionedUserMap.set(user.id, user); }); }); // 更新分页标记为当前批次最早的消息ID lastFetchedMessageId = messageBatch.last().id; } // 输出最终结果 const allMentionedUsers = [...mentionedUserMap.values()]; console.log(`目标频道累计提及过的不同用户总数:${allMentionedUsers.length}`); console.log('用户列表:', allMentionedUsers); }); client.login('你的机器人登录Token');
常见问题说明
- 如果频道消息量过大:比如单频道消息超过1万条,频繁分页拉取可能触发Discord接口的速率限制,建议在每次拉取批次后增加1-2秒的延迟,避免被临时限制访问接口
- 如果不需要拉取全部历史消息,仅需要实时监听新消息中的提及用户:无需实现分页拉取逻辑,直接通过
client.on('messageCreate', message => { ... })监听消息创建事件,从返回的message.mentions.users字段即可拿到该条新消息的提及用户 - 如果需要保留消息关联信息:比如某用户在哪条消息被提及、被提及的次数,可以在Map结构中增加计数器字段,遍历消息时累加对应用户的被提及次数
内容的提问来源于stack exchange,提问作者Arthur_Ms
相关产品推荐
相关产品推荐

