Differencebetween a User and a Guildmember in Discord.Js

What is the difference between a User and a GuildMember in discord.js?

From Official Discord.js Guide - Common Questions:

A lot of users get confused as to what the difference between Users and GuildMembers is. The simple answer is that a User represents a global Discord user and a GuildMember represents a Discord user on a specific server. That means only GuildMembers can have permissions, roles, and nicknames, for example, because all of these things are server-bound information that could be different on each server that user is in.


Many errors in the code in question occur because you are trying to call a guild specific function on a global user. For example, GuildMember.kick() and GuildMember.ban(). A very common mistake that leads to this is using the message.mentions.users collection. As the name suggests, this returns a collection of Users.

If you simply want, for example, the mentioned user's avatar, or maybe they're username and discriminator, it would work out fine. But it will lead to errors if you ever try to, for example, try to get the date they joined your server using GuildMember.joinedAt()

Luckily, there are many easy ways to circumvent this issue. For example, using MessageMentions.members (returns a collection of GuildMembers) instead of MessageMentions.users

const member = message.mentions.members.first()
member.ban() // no error here!

Another common workaround is using the Guild.member() method, which accepts a User object or ID!

const user = client.user // get the user object
const guild = client.guilds.cache.get('Guild ID') // get the guild object

const member = guild.member(user) // convert the User object to a GuildMember!

Other useful tricks to easily convert Users to GuildMembers include:

  • Using message.member instead of message.author
  • Using guild.members.cache.get() instead of client.users.cache.get()
  • Using guild.members.fetch() instead of client.users.fetch()
  • Using presence.member instead of presence.user

It's also very useful to remember if specific event parameters provide Users or GuildMembers. For example, both guildMemberAdd() and guildMemberUpdate pass GuildMembers, but messageReactionAdd(), guildBanAdd(), and typingStart() all pass Users.


While many GuildMember properties and methods are not available for a User, the same is true the other way around. For example, GuildMember.tag does not exist. However, converting a GuildMember to a User is much easier than converting a User to a GuildMember. This is because of GuildMember.user:

The user that this guild member instance represents

So, although GuildMember.tag will return undefined, GuildMember.user.tag will not!

Is there a difference between GuildMemberManager.resolve() and Guild.member() in discord.js?

The two methods are identical.

The source for Guild#member shows that it simply calls GuildMemberManager#resolve:

  member(user) {
return this.members.resolve(user);
}

UserResolvable and GuildMemberResolvable are also the same. UserResolvable can be a User, Snowflake, Message, or GuildMember; and a GuildMemberResolvable can be a GuildMember or UserResolvable. In this way, the type GuildMemberResolvable is essentially redundant and could be substituted for UserResolvable.

// Using TypeScript syntax to show the types
type UserResolvable = User | Snowflake | Message | GuildMember

// same as GuildMember | User | Snowflake | Message
type GuildMemberResolvable = GuildMember | UserResolvable

None of my discord.js guildmember events are emitting, my user caches are basically empty, and my functions are timing out?

Discord is now enforcing privileged intents



What are intents?

Maintaining a stateful application can be difficult when it comes to the amount of data you're expected to process, especially at scale. Gateway Intents are a system to help you lower that computational burden.

Gateway intents allow you to pick and choose what events you choose to "subscribe" to so that you don't have to use up storage on events you're not using. This feature was introduced to discord.js in v12

What are privileged intents?

Some intents are defined as "Privileged" due to the sensitive nature of the data. Those intents are:

  • GUILD_PRESENCES
  • GUILD_MEMBERS

As of October 27th, these intents have been turned off by default.

Some problems you might be facing because of this

  1. GUILD_PRESENCES

    • member and user caches are empty (or very close to it) on startup
    • Guild.memberCount returns count as of ready
    • All events involving Presences do not trigger (presenceUpdate)
    • Some Presence data returns null or undefined
    • All GuildMembers appear to the bot as offline.
    • client.login() times out if you specified the fetchAllMembers option in your ClientOptions
  2. GUILD_MEMBERS

    • member and user caches are empty (or very close to it) on startup
    • GuildMemberManager.fetch() and UserManager.fetch() methods time out
    • All events involving GuildMembers do not trigger (guildMemberAdd, guildMemberRemove, guildMemberUpdate, guildMemberSpeaking, and guildMembersChunk)

How do I enable intents?

Through the Discord Developer Portal:

Firstly, you must manually enable the intents from the Discord Developer site. Go to applications, select your app, and find the "bot" tab on the sidebar. Then you can scroll down until you see this:

intents

As shown in the screenshot, your bot will require verification if in more than 75 guilds.

If your bot is verified:

Once your bot is verified, you won't be able to manually flip the intent switches in the Developer Portal. To request whitelisted access to an additional privileged gateway intent for a verified bot, please send our support team a ticket here!
Make sure to include your bot's ID, which intents you're requesting, a basic description of your use case for the requested intent, and screenshots or video of that use case in action (or code snippets, if not user facing!).

Through the discord.js module:

Once you have either/both intents checked off, you just have to enable them through discord.js. The discord.js intents guide thoroughly explains how to do this, but I will paraphrase it here.

You don't need to go through these steps if you want every intent. Discord enables all intents (except these two, obviously) by default. As long as you checked off both intents in the Developer Portal, you can stop here if you don't care about blocking any other intents. If you do, just remember intents are only supported by discord.js v12+, so you might have to upgrade.

One of the ClientOptions (ClientOptions is a typedef of potential options to pass when creating your client) is ws (yet another typedef of potential websocket options). In there, you'll find the intents property.

intents accepts a IntentsResolvable, which can be a string or an array of strings of an intent(s) (such as 'GUILD_PRESENCES'. All available intents), a bitfield (a number corresponding to an intent(s)), an instance of the Intents class.

Examples:

// using a string
const client = new Discord.Client({ ws: { intents: 'GUILD_PRESENCES' }});

// using an array
const client = new Discord.Client({ ws: { intents: ['GUILD_PRESENCES', 'GUILD_MEMBERS'] }});

// using a bitfield value
const client = new Discord.Client({ ws: { intents: 32509 }));

// using Intents class
const client = new Discord.Client({ ws: { intents: Discord.Intents.PRIVILEDGED }});
const client = new Discord.Client({ ws: { intents: new Discord.Intents(Discord.Intents.ALL) }});

Resources:

  • Discord.js Official Guide - Gateway Intents
  • Discord Developer Documentation - Gateway Intents
  • Gateway Update FAQ
  • Discord API Github - Issue 1363 - Privileged Intents
  • Discord Blog - The Future of Bots on Discord


TL;DR

To fix this issue, go to:

Discord Developer Portal > Applications > Your Application > Bot > Check both/either intent(s) (screenshot above)

Joinedat difficulties discord.js

Message#author is a User. .joinedAt only exists on GuildMembers which you can get with Message#member

{name: 'Joined at', value: `${moment(message.member.joinedAt).format('MMMM Do YYYY, h:mm:ss a')} //remember capitalization

Additionally, .createdAt only exists on Users, not GuildMembers

Comparing a message authors roles

const highest = message.author.roles.highest;

author of a message is a user and users don't have roles. That is the reason it's saying: cannot read prperty of undefined because author.roles is not a thing. You have to get the member, to get the roles. So do this:

const highest = message.member.roles.highest;

Here you are taking the author(user) of the message as a GuildMember(member) and then asking for the highest roles this member have.

message.member.displayAvatarURL(); is not a function

displayAvatarURL is a function on User, not GuildMember.

You can either get the user from the member like this:

message.member.user.displayAvatarURL();

or just directly use the author property:

message.author.displayAvatarURL();

How to check the role of a reacting member discord.js

You can use the second parameter of the messageReactionAdd event, the User that reacted, and the Guild.member() method.

Guild.member() can convert a global user object to a guildmember object in which you can see the roles of. To learn the difference between the two, check out What is the difference between a User and a GuildMember in discord.js?.

if (
reaction.message.guild
.member(user)
.roles.cache.some((role) => role.name == 'Goof Archivist ')
)


Related Topics



Leave a reply



Submit