Reputation: 27
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
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
Reputation: 2837
You can use Client.users
and filter out the bots.
You can't fetch all the User
s, 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 GuildMember
s 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
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