Home > Back-end >  Getting the number of people with specified precence (Discord.js)
Getting the number of people with specified precence (Discord.js)

Time:09-27

So I have this piece of code that worked for d.js v12 but is now broken in v13, I have been trying for a while now to find a fix, also asked in their discord server but no one knows, the problem is that the code just stops running when getting length of people online offline etc, no errors, just stops running.

when just getting 1 user and logging their status it shows, not when getting everyones statuses.

const members = message.guild.members.cache;
const online = members.filter((m) => m.presence.status === 'online').length;
const offline = members.filter((m) => m.presence.status === 'offline').length;
const dnd = members.filter((m) => m.presence.status === 'dnd').length;
const afk = members.filter((m) => m.presence.status === 'idle').length;

CodePudding user response:

There are two issues in your code, but they are so subtle that most would not notice them. Most people would immediately assume the issue is intents, but intents are not the true issue here.

The first issue is that GuildMember.presence can be undefined when using guild.members.cache. That means trying to do m.presence.status when m.presence is undefined will cause an error. For example, while messing around with the eval command of my discord bot, I tried filtering out the IDs of all members in my testing guild that have undefined or null presences. I found that all members who had been offline/invisible since before the bot had come online (such as myself), had undefined presences. When I set my status to do not disturb and then back to invisible, the cache then updated and my presence was no longer undefined (and was "offline", as expected). I am not sure why exactly this occurs, as even fetching all members in the guild does not remove the undefined presences. I have all relevant intents as well.

The second issue is that guild.members.cache.filter() returns a Collection, not an Array. The Collection class does not have a .length property; you have to use .size instead.

Here's one example of how you would fix these issues:

const members = message.guild.members.cache;
const online = members.filter(m => m.presence?.status === 'online').size;
const offline = members.filter(m => !m.presence || m.presence.status === 'offline').size;
const dnd = members.filter(m => m.presence?.status === 'dnd').size;
const afk = members.filter(m => m.presence?.status === 'idle').size;

I'm using the ?. optional chaining operator for convenience here. You can replace m.presence?.status with m.presence && m.presence.status if you are uncomfortable using the optional chaining (or unable to due to a lower node version).

Basically, this answer solves the first issue by checking if m.presence is undefined before determining the member's status. Since m.presence is undefined for some offline users, if m.presence is undefined for a member we include them in the offline member count and exclude them from all other member counts. How this answer solves the second issue is pretty straightforward; we just replace .length with .size.

Relevant resources:
https://discord.js.org/#/docs/collection/main/class/Collection?scrollTo=filter https://discord.js.org/#/docs/main/stable/class/GuildMember?scrollTo=presence

  • Related