DJS - 不包括机器人的成员数

DJS - Member count excluding bots

我想创建一个排除所有机器人的成员计数。 我和一位朋友谈过,他告诉我代码看起来是正确的。但它只给我0分。也许你的眼光比他好!

module.exports = async(client) => {
    const guild = client.guilds.cache.get('912706237806829598');
    
    setInterval(() => {
        const memberCount = guild.members.cache.filter(member => !member.user.bot).size;
        const channel = guild.channels.cache.get('959556115383861298');
        channel.setName(`╭・Members: ${memberCount.toLocaleString()}`);
        console.log('Updating Member Count');
        console.log(memberCount);
    }, 5000);
}

谢谢。

尝试了我的代码并期望一个值代表我服务器上的人数,但只有 0。

如果您想访问包括机器人在内的所有成员,您可以使用 memberCount

const totalCount = guild.memberCount

如果你只想得到 members size

const memberCount = guild.members.cache.filter(member => !member.user.bot).size;

如果您只想获得 bot size

const botCount = guild.members.cache.filter(member => member.user.bot).size;

完整代码:

 const guild = client.guilds.cache.get('912706237806829598')

    const memberCount = guild.members.cache.filter(member => !member.user.bot).size;
    const botCount = guild.members.cache.filter(member => member.user.bot).size;
    const totalCount = guild.memberCount

    console.log(memberCount, botCount, totalCount)

您的代码存在两个潜在问题。首先,您不是在获取成员集合,而是在与缓存进行交互;如果我没记错的话,缓存通常只显示在线会员而不显示离线会员。其次,可怕的 速率限制.

问题

第一个问题很容易解决。您只需要在所有 setInterval 代码之前获取成员而不是使用缓存:

setInterval(async () => {
    const memberCount = (await guild.members.fetch()).filter(member => !member.user.bot).size;
    const channel = guild.channels.cache.get('959556115383861298');
    channel.setName(`╭・Members: ${memberCount.toLocaleString()}`);
    console.log('Updating Member Count');
    console.log(memberCount);
}, 5000);

这可能是您遇到问题的原因。但是,这里还有一个问题,如果您使用此代码,您将 运行 遇到这个问题。速率限制。如果我没记错的话,Discord API 中大多数操作的正常速率限制是每 10 分钟 10,000 个请求。但是,更改频道名称的速率限制仅为每 10 分钟 2 个请求(我最后检查过;我不知道自去年以来他们是否增加了此限制) .您的代码每 5 秒更改一次频道名称。只需 10-15 秒,您就会超过速率限制。

我过去也创建了频道来跟踪我的机器人的服务器统计信息,并且 运行 在我这样做时遇到了这个问题。幸运的是,当我创建自己的统计系统时,我想出了一种绕过速率限制问题的方法。尽管更改频道名称的速率限制非常低,但完全创建频道的正常速率限制为每 10 分钟 10,000 个请求。因此,您可以不直接更改频道名称,而是: a) 克隆频道; b) 在创建克隆时更改其名称; c) 将克隆在频道列表中的位置设置为与实际频道相同的位置; d) 删除原来的频道。克隆的频道将保留原始频道的所有权限、设置等。当然,这一切都假设原始频道不是内部有重要消息或类似内容的文本频道,因为这些消息会用这种方法全部消失。我为我的系统使用了语音通道。

下面是这个绕过的样子:

setInterval(async () => {
    const memberCount = (await guild.members.fetch()).filter(member => !member.user.bot).size;
    const channel = guild.channels.cache.get('959556115383861298');
    const pos = channel.position;

    const clone = await channel.clone({
        name: `╭・Members: ${memberCount.toLocaleString()}`
    });
    await clone.setPosition(pos);
    console.log('Updating Member Count');
    console.log(memberCount);

    await channel.delete();
}, 5000);

通过这种方法,速率限制不再是问题。但是请注意,这仍然可以进一步改进。例如,在间隔内,您可以检查成员计数是否与之前的计数相比发生了变化,并且仅当且仅当计数发生变化时才修改频道名称。整个方法也可能会发生变化;也许您可以使用 guildMemberAddguildMemberRemove 事件来跟踪成员计数何时增加或减少,并且仅在其中之一发生时修改名称(并且仅当成员 added/removed 不是一个机器人)。但是是否添加这些可选的潜在改进中的任何一个取决于您。

注意:为了安全起见,请先在测试频道上试用此代码,然后再将其用于您正在使用的实际频道。