What is the difference between a User and a GuildMember in discord.js?
I've gotten many errors in my code that I believe has been the result of mix-ups between GuildMembers
and Users
. Can someone explain the difference?
const user = message.mentions.users.first();
// TypeError: user.kick() is not a function
user.kick({ reason: 'spamming' });
// TypeError: user.ban() is not a function
user.ban({ reason: 'DM Advertising' });
// TypeError: message.author.hasPermission() is not a function
if (!message.author.hasPermission('ADMINISTRATOR')) return;
console.log(user.displayName); // undefined
// TypeError: message.member.createdAt() is not a function
embed.addField('Account Created', message.member.createdAt());
client.on('guildMemberUpdate', (oldMember, newMember) => {
console.log(`${newMember.tag} was updated`); // 'undefined was updated'
});
if (message.member.bot) return; // undefined
// TypeError: Cannot read property 'add' of undefined
user.roles.add(newRole)
const target = message.client.users.cache.get(args[0])
console.log(target.displayName) // undefined
Solution 1:
From Official Discord.js Guide - Common Questions:
A lot of users get confused as to what the difference between
Users
andGuildMembers
is. The simple answer is that aUser
represents a global Discord user and aGuildMember
represents a Discord user on a specific server. That means onlyGuildMembers
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 ofmessage.author
- Using
guild.members.cache.get()
instead ofclient.users.cache.get()
- Using
guild.members.fetch()
instead ofclient.users.fetch()
- Using
presence.member
instead ofpresence.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!