Discord.js分片环境下如何获取指定服务器成员及用户角色?
分片环境下获取Discord服务器成员及角色的解决方案
问题根源
你之前的代码报错是因为broadcastEval返回的是序列化后的纯数据对象,不是完整的Discord.js Guild实例。序列化过程会丢弃类方法(比如cache.get)和大部分非基础数据,所以你看到的members只是成员ID数组,没有cache属性。
解决方案:直接在分片节点内处理逻辑
不要尝试把整个Guild对象传回主进程,而是在分片内完成成员查询、角色获取的操作,只返回需要的纯数据。
1. 获取指定用户在目标服务器的角色
// 获取指定用户在目标服务器的角色ID数组 const getUserRolesInGuild = async (guildId, userId) => { const results = await client.shard.broadcastEval((c, { guildId, userId }) => { const guild = c.guilds.cache.get(guildId); if (!guild) return null; // 优先从缓存取,缓存无数据则主动fetch用户 return guild.members.fetch(userId) .then(member => member.roles.cache.map(role => role.id)) .catch(() => null); // 用户不在服务器/无权限时返回null }, { context: { guildId, userId } }); return results.find(res => res !== null) || null; }; // 使用示例 const targetUserId = "要查询的用户ID"; const userRoles = await getUserRolesInGuild('myGuildId', targetUserId); console.log("用户角色ID数组:", userRoles);
2. 获取服务器所有成员信息
如果需要获取服务器全部成员,同样在分片内完成fetch操作,返回结构化的纯数据:
// 获取目标服务器所有成员的基础信息(ID、用户名、角色) const getAllGuildMembers = async (guildId) => { const results = await client.shard.broadcastEval((c, guildId) => { const guild = c.guilds.cache.get(guildId); if (!guild) return null; // 注意:大服务器(1000+成员)使用fetch可能触发速率限制,需谨慎 return guild.members.fetch() .then(members => members.map(m => ({ id: m.id, username: m.user.username, discriminator: m.user.discriminator, roles: m.roles.cache.map(r => r.id) }))) .catch(() => null); }, { context: guildId }); return results.find(res => res !== null) || null; }; // 使用示例 const allMembers = await getAllGuildMembers('myGuildId'); console.log("服务器所有成员:", allMembers);
关键注意事项
- 分片环境下禁止跨分片传递Discord.js类实例,序列化会丢失核心方法和数据,只传递纯JSON格式的数据。
- 使用
members.fetch()前,确保机器人拥有GUILD_MEMBERS权限,否则无法获取成员信息。 - 针对超大服务器,建议分批获取成员,避免触发Discord的API速率限制。
内容的提问来源于stack exchange,提问作者Louis
相关产品推荐
相关产品推荐

