Drakeu0909
Drakeu0909

Reputation: 27

Discord.js Know how many users are in all the guilds of the bot

I'm coding a discord bot in discord.js v12. And I want to know how many users are in all of the servers that my bot is in. And I don't want to count the same user multiple times, that will false the results. Also I don't want to count the bots.

Here's my code, (that gives me the amount of users and bots, and also give me multiple times one user, because he is in multiple servers that the bot is in):

bot.on('message', msg => {
    if(msg.content === PREFIX + "total members") {
        msg.channel.send(bot.guilds.cache.reduce((a, g) => a + g.memberCount, 0))
    }
})

Hope you can help. Thanks!

Upvotes: 1

Views: 1889

Answers (3)

Thunder
Thunder

Reputation: 501

Adding onto Skulaurun Mrusal's answer, you want to make sure that all users of the bot are in the cache before counting the size. So to do that, you'd fetch all of the users before getting the size of the cache.

Code below:

// Get all the users and dump to cache before filtering
await client.users.fetch()
const users = client.users.cache.filter(user => !user.bot);
console.log(users.size);

(Because in large bots not all users are cached, and without fetching all users might count 25-50% of the true count of users)

Upvotes: 1

Skulaurun Mrusal
Skulaurun Mrusal

Reputation: 2837

You can use Client.users and filter out the bots.

You can't fetch all the Users, they are cached automatically up to 75k users when an event GUILD_CREATE is emitted on the websocket for each guild. According to Discord Developer Portal. For discord.js v13, you would need to enable the GUILD_PRESENCES intent.

Note that you can't use UserManager.fetch() to fetch all the users, because it has a required parameter id. (Referring to Thunder's answer.)

// A Discord.Collection of users
const users = client.users.cache.filter(user => !user.bot);
// Use .size property to access the total count of cached users
console.log(users.size);

There is no guarantee, that all the users will be sent over to the client on the GUILD_CREATE event, for more accurate solution see the one below.

You could use GuildMemberManager.fetch() to fetch all the GuildMembers of each guild. See example below (userIds should be guaranteed to contain all the unique ids of users, even if they are offline):

// Initialize a storage for the user ids
const userIds = new Set();
// Iterate over all guilds (always cached)
for (const guild of client.guilds.cache.values()) {
    // Fetch all guild members and iterate over them
    for (const member of (await guild.members.fetch()).values()) {
        // Fetch the user, if user already cached, returns value from cache
        // Will probably always return from cache
        const user = await client.users.fetch(member.id);
        // Check if user id is not already in set and user is not a bot
        if (!userIds.has(user.id) && !user.bot) {
            // Add unique user id to our set
            userIds.add(user.id);
        }
    }
}
// Use .size property to access the size of the set
console.log(userIds.size);

Note that client is an instance of Discord.Client.

Tested using discord.js ^12.5.3.

Upvotes: 1

Ramy Hadid
Ramy Hadid

Reputation: 162

There is a fast and proven code that i wrote:

var usersCount= 0;
client.guilds.cache.mapValues(guild => {
const _x = client.guilds.cache.get(guild.id);
      usersCount += client.guilds.cache.reduce((a, g) => a + g.memberCount, 0)
});
message.channel.send(usersCount);
usersCount = 0;

Upvotes: -1

Related Questions