I looked at Discord API about interactions (see Interactions structure) and I noticed they don't include the id of the member who invoked them. I want to use Discord.JS to fetch those members, but can't find a guild member without his ID. Is there a way to either get a member without his ID, or get the ID of the member who called a interaction ?
Because there appears to be no id field for members, you can get it from the user object instead. From there, Discord.js lets you do <guild>.member('ID here') to fetch member object of a user resolvable from a certain guild, which the ID works as.
Related
How can I issue a role to a guild member based on their custom status? For instance, if a member has the word "rainbow" within their status, then they are given the role 'Rainbow'?
A user's custom status is stored under a Presence.
You can access a status under member.presence.activities, you can listen to the event presenceUpdate for when a user changes their custom status which is emitted whenever a guild member's presence (e.g. status, activity) is changed.
With this, you can pick up on whatever text set in their status and based on specific words, in your instance if the word "rainbow" is within their status, then give then a role with GuildMemberRoleManager#add.
Is there any way to properly save a user's role history without the need for a database and/or a JSON file on Discord.js? I would like to create a function that logs the roles a user has at the beginning of the command and gives them back after a specific function is triggered.
There is an easy way to save a user's Role history on Discord without the need for a Database and/or any JSON file, you must add a few lines to your code in order to do this.
You first need to make sure your Discord bot has "Privileged Gateway Intents" enabled within the Discord Developer Portal panel, this will highly improve the accuracy of the bot's cache fetching tasks. Next, create a constant for the user mention or user ID, just like the following:
const saveRolesFor = (message.mentions.members.first() || message.guild.members.cache.get(args[0]));
With these 2 arguments, you will be able to state the id of the user or mention the user instead.
Then you must save the roles for the specified user inside another constant variable, just like the following:
const roleHistory = saveRolesFor.roles.cache.map(r => r.id);
The reason why mapping the roles is the best thing to do is due to the roles cache containing other elements, aside from the actual user roles, mapping them would simply include the actual roles of the user, preventing potential issues.
Now you must state the new role you'd like the user to have, just like the following:
let roleToAdd = message.guild.roles.cache.find(r => r.name === 'Role');
Time to remove all of the previous roles and add the roleToAdd to the user, you should do it as:
await(saveRolesFor.roles.set([roleToAdd.id]));
You will want to set the user's roles, as this function automatically removes any other role the user had, and add the single role you have stated, you no longer require the .remove and .add functions.
After these functions have been performed, you can be creative and add the rolehistory back after certain functions are completed.
A very simple example of this would be to add the roles back to the user once a message is sent, for example:
message.channel.send(`The roles for ${saveRolesFor} have been added back!`)
.then(saveRolesFor.roles.set(roleHistory));
All of the user's previous roles will be added successfully, and the roleToAdd will be removed, as you .set the roleHistory of the user, meaning you added those specific roles only. The .then function is calling the roleHistory set after the message is sent to the channel, you could modify it to properly fit into what you attempt to obtain out of your code.
This won't be the best way to add the roles back, as it will take less than a second, but the functions shown above will be highly useful at the time of creating a similar command.
Hope it was helpful!
I have a command that currently gives a count of how many people have a specific role. That functions properly. I am attempting to make a subcommand of that command that will list the members who have that role and I can get it to list their names as usernames, but I'm looking for it to list it as a display name instead.
This is the code that currently works
let nameList= message.guild.roles.resolve('Role-ID').members.map(m=>m.user.username).join('\n');
The "Role-ID is the actual ID in my code. I know that the displayName is a property of the GuildMember but I don't know how to integrate it here. Thoughts?
I figured it out, but instead of deleting my post I figured I would post the solution.
All I needed to do was change .user.username to .displayName
let nameList= message.guild.roles.resolve('Role-ID').members.map(m=>m.user.username).join('\n');
I have some user tags like this one Nickname#1234, I need to fetch the user with that tag to the bot cache, i've tried this method:
message.channel.guild.members.fetch([options])
but it only seems to work with the user ID, it's there a way to fetch the specified member without it's ID?, or get the user ID from a member which isn't in the cache?
You cannot actually fetch by a user tag because Discord Api doesn't support that yet so you can just fetch all members and find them -
message.channel.guild.members.fetch({cache : false}).then(members=>members.find(member=>member.user.tag === "Nickname#1234"))
client.guilds.cache.get('<id>').channel.create(message.author.username, 'text');
I'm trying to use this code here to create a text channel titled with the message author's username, but I can't get the specified server (the ID is correct).
If you want to create a channel, you need the GuildChannelManager of a guild. To get this, you need to call the Guild.channels property. Instead you have .channel without the s at the end. Try using .get('<id>').channels.create and see how that works.