I seem to be having serious trouble sending DM's to all users with a specific role.
Here is my bot code:
bot.on('message', async message => {
members = message.guild.roles.cache.find(role => role.id === "12345678998765").members.map(m => m.user.id);
members.forEach(member_id => {
sleep(5000).then(() => {
message.users.fetch(member_id, false).then((user) => {
user.send("some message");
});
});
});
});
This code gives me the error:
Cannot read properties of null (reading 'roles')
on this line:
members = message.guild.roles.cache.find(role => role.id === ....
However that is not the issue. When I comment out the sleep command to send the message and output the member roles using:
members.forEach(member_id => {
console.log(member_id)
//sleep(5000).then(() => {
// bot.users.fetch(member_id, false).then((user) => {
// user.send("some message");
// });
//});
});
I get a list returned in the console of all the user ID's.. So it must be returning the roles.
How do I send a message to all users with a specific role ID ?? I want to be able to loop through them and put a wait in to reduce the API requests and spam trigger.
To fix your first issue, message.guild will be null in DM. Make sure it isn't DM, or if it has to be, choose a guild with client.guilds.cache.get("id").
bot.on("message", async message => {
let { guild } = message
if (!guild) guild = bot.guilds.cache.get("id")
//...
})
To fix your other issue, you can run GuildMember#send() rather than getting the IDs and fetching the users
bot.on("message", async message => {
let { guild } = message
if (!guild) guild = bot.guilds.cache.get("id")
let members = guild.roles.cache.get("12345678998765").members
// I used .get here because it's getting by ID
members.forEach(member => {
sleep(5000).then(() => member.send("some message"));
});
})
The above code will get all the GuildMembers and loop through every one of them, "sleeping" for 5 seconds (if the sleep parameter is milliseconds) and send the member a DM
So what's going on is that I'm trying to make a set role/set channel command for logs and a mute role to mute people with and I'm wondering how to do this. I have looked at the docs and other stackoverflow threads and it still doesn't work.
if(!args[1]) return message.channel.send('Please specify a arg')
let roleName = args.slice(2).join(" ");
var role = message.guild.roles.cache.find(role => role.name === roleName)
if(!role){
message.channel.send("Thats not a role!")
}
if(role){
await GuildConfigSchema.update({ Guild: message.guild.id }, { MuteRole: role })
message.channel.send(`The mute role is now ${role}`)
}
First you can use if(role){ } else { } something like that and second on comments you said when I ping it for your code ping will not work because you use role.name if you want to catch role with ping then use let role = message.mentions.roles.first();
I want to make a discord bot program. when someone new goes to the server they have to type !daftar to be able to enjoy the server. and when they type !daftar message list will appear on #welcome channel. but I get an error that is in the title. here is my code
const { GuildMember } = require("discord.js");
module.exports = {
name: 'daftar',
description: "This is for add roles to a member",
execute(message, args) {
let role = message.guild.roles.cache.find(r => r.name === "Members")
if (message.member.roles.cache.some(r => r.name === "Members")) {
message.channel.send('Kamu sudah menjadi MEMBER Di grup ini');
} else {
message.member.roles.add('817360044622217276');
message.member.roles.remove('817965925122048010');
message.channel.send('Baiklah silahkan menikmati Server');
GuildMember.guild.channels.cache.get('817957997312737290').send(`Selamat Datang <#${GuildMember.user.id}>`)
}
}
}
GuildMember is not exactly defined. Yes, you are destructuring it as the property of discord.js, but it's not exactly defined as who the member actually is. Right now it's just an empty object that belongs to no one, meaning that it also has no properties itself as it does not know what it refers to.
Assuming that you're wanting to give the role to the member who typed this command, you'd have to make the GuildMember object the property of the Message object that is defined as message in your parameters. We can get this object using the member property of message => message.member.
Now, assuming that the channel you're looking to send the message to is found in the same guild as the message object, there is no sense behind using a GuildMember object to find a certain channel, when we can instead use the Message object, as seen below:
Final Code
module.exports = {
name: 'daftar',
description: "This is for add roles to a member",
execute(message, args) {
let role = message.guild.roles.cache.find(r => r.name === "Members")
if (message.member.roles.cache.some(r => r.name === "Members")) {
message.channel.send('Kamu sudah menjadi MEMBER Di grup ini');
} else {
message.member.roles.add('817360044622217276');
message.member.roles.remove('817965925122048010');
message.channel.send('Baiklah silahkan menikmati Server');
message.guild.channels.cache.get('817957997312737290').send(`Selamat Datang <#${GuildMember.user.id}>`)
}
}
}
I am making a roster command, and this is my code so far, the error is when it comes to the admin it bugs out like in the picture and it doesn't continue... It also saves all of the answers in a file.
So an admin does $roster setup and it starts saving replies for the names of each file. This is the only part I've done for now, so the setup. And I am getting that bug there, there's no error in the console.
client.on('message', async message => {
if (message.content.startsWith(prefix + "roster")) {
if (!message.member.hasPermission('ADMINISTRATOR')) return message.channel.send('You do not have that permission! :x:').then(message.react(':x:'))
if (message.author.bot){}
else {
!fs.existsSync(`./roster/` + message.guild.id) && fs.mkdirSync(`./roster/` + message.guild.id, { recursive: true })
const args = message.content.slice(prefix.length + 7).split(/ +/)
let uReply = args[0];
if(!uReply) return message.channel.send("Please use the following options: `setup`, `send`, `add` or `remove`!")
//SETUP
if(uReply === "setup") {
const collector = new Discord.MessageCollector(message.channel, m => m.author.id === message.author.id, { time: 10000 });
message.channel.send("Please write the exact role name of leader role (with emojis if it has).")
collector.on('collect', message => {
let leaderRole = message.content
fs.writeFileSync(`./roster/${message.guild.id}/`+ `Leader`+".txt", message.content, (err) => console.error);
message.channel.send(`Ok, the leader role is called \`${leaderRole}\`.`)
collector.off
message.channel.send("Now, whats the role name of co-leader or co-owner role (with emojis if it has)?")
collector.on('collect', message => {
let coleaderRole = message.content
fs.writeFileSync(`./roster/${message.guild.id}/`+ `Co-Leader`+".txt", message.content, (err) => console.error);
message.channel.send(`Ok, the co-leader/co-owner role is called \`${coleaderRole}\`.`)
collector.off
message.channel.send("Now, whats the role name of admin role (with emojis if it has)?")
collector.on('collect', message => {
let adminRole = message.content
fs.writeFileSync(`./roster/${message.guild.id}/`+ `Admin`+".txt", message.content, (err) => console.error);
message.channel.send(`Ok, the admin role is called \`${adminRole}\`.`)
collector.off
message.channel.send("Awesome, now whats the role name of staff role (with emojis if it has)?")
collector.on('collect', message => {
let staffRole = message.content
fs.writeFileSync(`./roster/${message.guild.id}/`+ `Staff`+".txt", message.content, (err) => console.error);
message.channel.send(`Ok, the staff role is called \`${staffRole}\`.`)
collector.off
message.channel.send("Cool, now whats the role name of tiny-staff role (with emojis if it has)?")
collector.on('collect', message => {
let tinyStaffRole = message.content
fs.writeFileSync(`./roster/${message.guild.id}/`+ `Tiny-Staff`+".txt", message.content, (err) => console.error);
message.channel.send(`Ok, the tiny-staff role is called \`${tinyStaffRole}\`.`)
collector.off
message.channel.send("Just a few more, now whats the role name of higher ranked members role (with emojis if it has)?")
collector.on('collect', message => {
let HigherRankedRole = message.content
fs.writeFileSync(`./roster/${message.guild.id}/`+ `HigherRanked`+".txt", message.content, (err) => console.error);
message.channel.send(`Ok, the higher ranked members role is called \`${HigherRankedRole}\`.`)
collector.off
message.channel.send("Last one, whats the role name of the normal members role (with emojis if it has)?")
collector.on('collect', message => {
let NormalMembersRole = message.content
fs.writeFileSync(`./roster/${message.guild.id}/`+ `NormalMembers`+".txt", message.content, (err) => console.error);
message.channel.send(`Awesome, the normal members role is called \`${NormalMembersRole}\`.`)
message.channel.send("That's it for setup.")
collector.off
})})})})})})})
}
}
}});
Picture:
I believe that the error comes from the original MessageCollector listener not being properly disabled, so the original listener still triggers for each additional message.
It looks like you tried to stop the original listener with collector.off, but because this is a statement instead of a function call, it doesn't do anything. Furthermore, if it did function, it would end the parent collector and none of the subsequent collector.on callbacks would work.
Instead, I would replace the collector.on functions with collector.once and remove the collector.off statements. Changing it to collector.once automatically ends the listener after it receives the first event, which is what you want in this scenario. If you wanted to receive more than one event, you'd have to use something else.
For example, the listener would look something like this:
collector.once('collect', message => {
let leaderRole = message.content
fs.writeFileSync(`./roster/${message.guild.id}/`+ `Leader`+".txt", message.content, (err) => console.error);
message.channel.send(`Ok, the leader role is called \`${leaderRole}\`.`)
/* ... Rest of code ... */
}
I have this on my code but when I execute the command twice (the name command, user, and role) it doesn't return this message. It keeps on saying "I added [role name] to [user]"
if (message.guild.members.cache.some(role => role.name)) {
const embed = new Discord.MessageEmbed()
.setColor('RANDOM')
.setDescription(`${message.mentions.users.first()} has that role already!`);
return message.channel.send(embed);
}
Did you save the code? Also, instead of
if (message.guild.members.cache.some(role => role.name))
do
if (message.guild.members.cache.some(role => role.name === 'roleName')) //insert role name.
Hope this helps :)