Discord.js Serverinfo命令统计服务器机器人、成员数量错误
问题根因
统计结果偏差的核心原因是interaction.guild.members.cache未存储全量服务器成员数据。
Discord.js v13及以上版本受Discord网关隐私规则限制,默认不会主动拉取所在服务器的完整成员列表,缓存中仅会保留机器人自身、触发过交互/发送过消息的成员、以及部分在线成员数据。即便机器人拥有服务器管理员权限,只要未开启对应网关意图,缓存数据就是残缺的,直接基于缓存过滤统计机器人数量、计算普通成员数必然会小于实际值,和你测试中出现的「总成员数准确、bot和普通成员数都偏少」的现象完全匹配。
修复方案
1. 开启特权网关意图
- 进入Discord开发者平台,打开对应机器人的应用设置页
- 切换到「Bot」标签页,下滑找到Privileged Gateway Intents板块
- 开启
Server Members Intent选项,保存配置
2. 客户端初始化添加成员意图
初始化Discord客户端实例时,必须在intents配置中加入成员相关权限,参考配置:
const { Client, Intents } = require('discord.js'); const client = new Client({ intents: [ Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES, // 必须添加以下意图,否则无法拉取全量成员 Intents.FLAGS.GUILD_MEMBERS ] });
3. 命令逻辑中拉取全量成员后再统计
不要直接读取缓存数据,命令执行时先调用fetch()拉取当前服务器的完整成员列表,刷新缓存后再做统计,修复后的核心代码如下:
async execute(interaction) { // 拉取当前服务器全量成员,强制刷新本地缓存 await interaction.guild.members.fetch(); const botCount = interaction.guild.members.cache.filter(m => m.user.bot).size; const humanCount = interaction.guild.memberCount - botCount; const Embed = new Discord.MessageEmbed() .setColor(interaction.member.displayHexColor) .setDescription(`**Informations**`) .setThumbnail(interaction.guild.iconURL({dynamic: true})) .addFields( { name: ":bookmark_tabs: **Informations**", value: ` Guild name : ${interaction.guild.name} Owner : <@${interaction.guild.ownerId}> Creation : ${moment.utc(interaction.guild.createdAt).format("LL")} ` }, { name: ":leaves: **Guild users**", value: ` Members : ${humanCount} Bots : ${botCount} Total : ${interaction.guild.memberCount} ` } ) .setFooter(`Commande effectuée par ${interaction.member.user.username}`, interaction.member.user.displayAvatarURL({dynamic: 'true'})); await interaction.reply({embeds : [Embed]}); }
补充说明
- 若机器人加入的服务器总数超过100,开启
Server Members Intent需要完成Discord的机器人验证流程,或按平台要求提交数据使用声明后才能正常生效 - 对于成员规模过万的大服务器,
members.fetch()会产生数百毫秒的请求延迟,属于正常现象 - 不要在机器人启动时批量拉取所有服务器的成员列表,会占用大量不必要的内存,在命令触发时按需拉取即可。
内容的提问来源于stack exchange,提问作者Dystopia
相关产品推荐
相关产品推荐

