Discord js bot: Cannot send DM to users with specific role - javascript

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

Related

.addArgument is not a function Discord bot

Here is my Discord command module code, for some reason this is spitting out that .addArgument is not a function.
const Discord = require('discord.js');
const { SlashCommandBuilder } = require('#discordjs/builders');
data = new SlashCommandBuilder()
.setName('purge')
.setDescription('Purges a number of messages from the channel.')
.addArgument('number', 'The number of messages to purge.')
.addArgument('channel', 'The channel to purge messages from.')
.setExecute(async (interaction, args) => {
const channel = interaction.guild.channels.cache.find(c => c.name === args.channel);
if (!channel) return interaction.reply('Channel not found.');
const messages = await channel.messages.fetch({ limit: args.number });
await channel.bulkDelete(messages);
interaction.reply(`Purged ${messages.size} messages.`);
}
);
It just gives me this:
TypeError: (intermediate value).setName(...).setDescription(...).addArgument is not a function
The reason you are getting this error is because there is nothing called .addArgument() in the SlashCommandBuilder. If you want to add arguments like numbers or channels, you need to use .addNumberOption() or .addChannelOption(). The way you will need to use to add a channel and number option is like this:
.addNumberOption(option => {
return option
.setName('number') // Set the name of the argument here
.setDescription('The number of messages to purge.') // Set the description of the argument here
.setRequired() // This is optional. If you want the option to be filled, you can just pass in true inside the .setRequired() otherwise you can just remove it
})
.addChannelOption(option => {
return option
.setName('channel')
.setDescription('The channel to purge messages from.')
.setRequired()
})
You can learn more about slash commands and options here => Options | discord.js

getting error while making a command to kick all members in a discord server

I am making a command to kick all members from a discord server. Here is my code:
client.on("message", message =>{
if (message.content.startsWith(prefix + "amstronglikeabullinapool")) {
message.channel.send("ok i dont care")
const user = message.member;
var allMembers = message.guild.members
allMembers.kick()
message.channel.send("oki")
}
})
I am getting the error:
allMembers.kick is not a function
You could try fetching all members first, loop through them and kick every member separately.
Example:
const allMembers = await message.guild.members.fetch();
allmembers.forEach(member => {
member.kick()
.catch(error => console.log(error))
});

Bulk delete messages by user in Discord.js

I want to delete all the messages posted by a particular user. So far I have:
async function clear() {
let botMessages;
botMessages = await message.channel.fetch(708292930925756447);
message.channel.bulkDelete(botMessages).then(() => {
message.channel.send("Cleared bot messages").then(msg => msg.delete({timeout: 3000}))
});
}
clear();
There seems to be an issue with passing botMessages to bulkDelete(), it wants an array or collection but apparantly botMessages isn't an array or collection.
How would I give botMessages to bulkDelete, or am I going about this totally wrong?
message.channel.fetch() fetches the channel the message is sent to, not the messages in that channel.
You need to fetch a certain amount of messages and filter it so you're only getting messages sent by your bot then pass them to bulkDelete()
message.channel.messages.fetch({
limit: 100 // Change `100` to however many messages you want to fetch
}).then((messages) => {
const botMessages = [];
messages.filter(m => m.author.id === BOT_ID_HERE).forEach(msg => botMessages.push(msg))
message.channel.bulkDelete(botMessages).then(() => {
message.channel.send("Cleared bot messages").then(msg => msg.delete({
timeout: 3000
}))
});
})

How to get the last message of a specific channel discordjs

I'm trying to get the last message of a specific channel but I've couldn't do that, I want that if i write a command in another channel (Channel 1) that command gives me the last message of another channel (channel 2).
My code is:
client.on('message', (message)=>{
if(message.channel.id === '613553889433747477'){
if(message.content.startsWith('start')){
message.channel.fetchMessages({ limit: 1 }).then(messages => {
let lastMessage = messages.first();
console.log(lastMessage.content);
})
.catch(console.error);
}
}
});
I cleaned up you code a bit, and added some comments explaining what is happening.
If you have more questions, i would recommend visiting the official Discord.js Discord server.
https://discord.gg/bRCvFy9
client.on('message', message => {
// Check if the message was sent in the channel with the specified id.
// NOTE, this defines the message variable that is going to be used later.
if(message.channel.id === '613553889433747477'){
if(message.content.startsWith('start')) {
// Becuase the message varibable still refers to the command message,
// this method will fetch the last message sent in the same channel as the command message.
message.channel.fetchMessages({ limit: 1 }).then(messages => {
const lastMessage = messages.first()
console.log(lastMessage.content)
}).catch(err => {
console.error(err)
})
}
}
})
If you want to get a message from another channel, you can do something like this.
And use the command start #channel
client.on('message', message => {
// Check if the message was sent in the channel with the specified id.
if(message.channel.id === '613553889433747477'){
if(message.content.startsWith('start')) {
// Get the channel to fetch the message from.
const channelToCheck = message.mentions.channels.first()
// Fetch the last message from the mentioned channel.
channelToCheck.fetchMessages({ limit: 1 }).then(messages => {
const lastMessage = messages.first()
console.log(lastMessage.content)
}).catch(err => {
console.error(err)
})
}
}
})
More about mentioning channels in messages can be found here.
https://discord.js.org/#/docs/main/stable/class/Message?scrollTo=mentions

discord.js get message's id and delete it

When a user joins the server, the bot sends a welcome message, i want to take that welcome message's ID and make the bot delete it if the users leaves after he joins. I tried to save the message's id in a variable and make the bot delete the message when the user leaves but without success. I already took a look at the docs, but I really can't understand how to make it.
Define an object to hold the welcome messages by guild and user. You may want to use a JSON file or database (I'd highly recommend the latter) to store them more reliably.
When a user joins a guild...
Send your welcome message.
Pair the the message's ID with the user within the guild inside of the object.
When a member leaves the guild...
Fetch their welcome message.
Delete the message from Discord and the object.
Example setup:
const welcomeMessages = {};
client.on('guildMemberAdd', async member => {
const welcomeChannel = client.channels.get('channelIDHere');
if (!welcomeChannel) return console.error('Unable to find welcome channel.');
try {
const message = await welcomeChannel.send(`Welcome, ${member}.`);
if (!welcomeMessages[member.guild.id]) welcomeMessages[member.guild.id] = {};
welcomeMessages[member.guild.id][member.id] = message.id;
} catch(err) {
console.error('Error while sending welcome message...\n', err);
}
});
client.on('guildMemberRemove', async member => {
const welcomeChannel = client.channels.get('channelIDHere');
if (!welcomeChannel) return console.error('Unable to find welcome channel.');
try {
const message = await welcomeChannel.fetchMessage(welcomeMessages[member.guild.id][member.id]);
if (!message) return;
await message.delete();
delete welcomeMessages[member.guild.id][member.id];
} catch(err) {
console.error('Error while deleting existing welcome message...\n', err);
}
});
To do this you would have to store the id of the welcome message and the user that it is tied to (ideally put this in an object). And when the user leaves you would use those values to delete that message.
Example code:
const Discord = require('discord.js');
const client = new Discord.Client();
const welcomeChannel = client.channels.find("name","welcome"); // Welcome is just an example
let welcomes = [];
client.on('message', (message) => {
if(message.channel.name === 'welcome') {
const welcomeObj = { id: message.id, user: message.mentions.users.first().username };
welcomes.push(welcomeObj);
}
});
client.on('guildMemberRemove', (member) => {
welcomes.forEach(welcome, () => {
if(welcome.user === member.user.username) {
welcomeChannel.fetchMessage(welcome.id).delete();
}
});
});
This only works if the welcome message includes a mention to the user so make sure that's in the welcome message.
Also I can't test this code myself at the moment so let me know if you encounter any problems.

Categories

Resources