Role.members only contains a single value when there are multiple - discord.js

I have a slash command with this option definition:
.addRoleOption(option =>
option.setName('role')
.setRequired(true)
.setDescription("The role associated with the game.")
)
In execute() of the same file/command, I have this part where I want to collect and store all members who have the role.
const existingParticipants = [];
interaction.options.getRole('role').members
.each(member => existingParticipants.push(member.id));
console.log(`Import compiled a list of all role-having members: ${existingParticipants}`);
And this is printed:
Import compiled a list of all role-having members: [userid redacted]
When I have other people do the command, their IDs are added to the list until I restart the bot, at which point the list goes back to just my ID. I have also tried to bypass the cache to see if that was the issue but it still persists:
await interaction.guild.roles.fetch(interaction.options.getRole('role').id, { force: true })
.then(role => role.members
.forEach(member => existingParticipants.push(member.id)))
Is it possible to get all of the guild members that have the role?
I have the GUILD_MEMBERS gateway intent enabled. Running Discord.js v14.7.1.

Related

Remove every user from a discord role

is there a way to delete all users from certain groups in a limit-saving way?
The way to delete every user one by one from a group seems very time consuming to me.
There are both possibilities, via a bot (Discord.js) that is already on the server or the Discord API.
I'd say your best bet is to just delete the role. The Role.delete method returns the Role after it has been deleted. You can just pass that exact return value back into guild.roles.create to clone the options from the previous role, in case you need to keep the properties of the Role but do not want the members anymore.
Ex:
declare const client: Client<true>
const guild = await client.guilds.fetch(`some-guild-id`)
const role = await guild.roles.fetch(`deleting-role-id`)
if (role) {
const deleted = await role.delete()
const recreated = await guild.roles.create(deleted)
}
This would be a pretty clean solution.

How do i make discord.js list all the members in a role?

if(message.content == `${config.prefix}mods`) {
const ListEmbed = new Discord.MessageEmbed()
.setTitle('Mods:')
.setDescription(message.guild.roles.cache.get('813803673703809034').members.map(m=>m.user.tag).join('\n'));
message.channel.send(ListEmbed);
}
Hey so iam making a command which displays all the members with that role but it only seems to be sending 1 of the mods
await message.guild.roles.fetch();
let role = message.guild.roles.cache.find(role => role.id == args[0]);
if (!role) return message.channel.send('Role does not exist'); //if role cannot be found by entered ID
let roleMembers = role.members.map(m => m.user.tag).join('\n');
const ListEmbed = new Discord.MessageEmbed()
.setTitle(`Users with \`${role.name}\``)
.setDescription(roleMembers);
message.channel.send(ListEmbed);
};
Make sure your command is async, otherwise it will not run the await message.guild.roles.fetch(); - this fetches all roles in the server to make sure the command works reliably.
In Discord.jsV12 the get method was redacted and find was implemented.
Aswell as this, I would highly recommend defining variables to use in embeds and for searching since it is much more easy to error trap.
If you have many members with the role, you will encounter the maximum character limit for an embeds description. Simply split the arguments between multiple embeds.

How to give a role to all members, with a interval

I want to make a command so i can give all the users in my discord server a role.
Problem is now with the code i have, that he gives not all the members the specified role because it are to much members and it will spam the discord api.
How can i make it so that after i do the command, the bot will give all the members the specified role, but not directly to prevent spamming the API, but for example every 10 min he gives 5 members the role until all the members got the role.
Hope some one could helpe me
this is what i have now :
module.exports = {
name: "give-roles",
aliases: ["gr"],
category: "roles",
description: "Give's all members the Verified-Member role",
usage: `${prefix}give-roles`,
run: async (Client, message) => {
message.guild.members.fetch()
.then(console.log)
.catch(console.error);
let role = message.guild.roles.cache.find(r => r.name === 'Verified-Member')
if (!role) return message.channel.send(`**${message.author.username}**, role not found`)
message.guild.members.cache.filter(m => !m.user.bot).forEach(member => member.roles.add(role))
message.channel.send(`**${message.author.username}**, role **${role.name}** was added to all members`)
},
}```
A way to get round this is to add a role when a member joins instead of all at once (which will never work since not all members will be cached)
<client>.on('guildMemberAdd', member => {
var memberRole = member.guild.roles.cache.find(role => role.name === "<role name here>");
member.roles.add(memberRole); //auto assign role on join
});
change the code in <> to fit your needs
The reason you cannot add a role to all members is due to the v12 addition of cache.
Managers/Cache
v12 introduces the concept of managers, you will no longer be able to directly use collection methods such as Collection#get on data structures like Client#users. You will now have to directly ask for cache on a manager before trying to use collection methods. Any method that is called directly on a manager will call the API, such as GuildMemberManager#fetch and MessageManager#delete.
I would recommend that you read the docs to further understanding of how bots work here

Why doesn't Collection#find work for offline members who have no roles? (discord.js)

My Goal
My goal is to figure out why Collection#find returns undefined when I try to find a user in my server, but they're offline and have no roles.
Expectation
Usually the console logs an array of all the properties of the user
Actual Result
The console logs Collection#find, as undefined if the user in my server is offline and has no roles
What I've Tried
I've tried using Collection#get, but it turns out that it returns the same response. I've tried searching this up on Google, but no one has asked this question before.
Reproduction Steps
const Discord = require('discord.js');
const client = new Discord.Client();
const {prefix, token} = require('./config.json');
client.once('ready', () => {
console.log('Client is online');
const user = client.users.cache.find(user => user.tag === 'Someone#1234');
console.log(user);
};
client.login(token);
Make sure that whoever is helping you, whether it's an alt account or your friend, that they have no roles, and they're completely offline in your server
Output:
Client is online undefined
I had the same problem. I don't know why this happens, but I used this line to fix that:
((await m.guild.members.fetch()).filter(mb => mb.id === "The ID")).first()`
Basically, this collect all the members, then filters them with the property you want, and the first() at the end is to make it a single object instead of a collection.
Instead of the user.tag property, try using the user.username and the user.discriminator properties. This worked for me
const user = client.users.cache.find(user => user.username === 'Someone' && user.discriminator === '1234');
Also check spelling, capitalization, ect.
A simple solution to my problem is just create an async function and use await guild.members.fetch() to cache the users and then use Collection#find to get the user.

Open and scan dms for key words

I'm working on a bot, and wanted to know if there was a way to open dms from all people in a server, and see if any commands were in there. If so I want the commands to be completed, but only with certain key words. Please help!
You can loop through the Guild's members collection and access the GuildMember's DMchannel using GuildMember.user.dmChannel then fetch all the messages using dmChannel.messages.fetch() then use filter() to get the messages with the keywords you're looking for
message.guild.members.cache.forEach(async (member) => {
const fetchedMsgs = await member.user.dmChannel.messages.fetch()
const messages = fetchedMsgs.filter((message) => message.content.toLowerCase().includes('search term')) // make sure the search term is lowercase
messages.forEach((message) => console.log(`${message.author.username} (${message.author.id}): '${message.content}' # ${message.createdAt}`)
})

Resources