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