Ok, I know that there are similar questions out there but no matter what I try I get the same result. I have been trying for 2 days now to figure out how to check if I had the "OverBot-Admin" role for a ban command. But whenever I run the command it spams the chat! Here is my code:
if (command === "ban") {
if(message.member.roles.has(role => role.name === "OverBot-Admin")) {
let reason = args.slice(1).join(" ");
if (!reason) reason = "No reason provided";
const user = message.mentions.users.first();
if (user) {
const member = message.guild.member(user);
if (member) {
member
.ban({ reason: "They were being bad." })
.then(() => {
message.reply(
":white_check_mark: Successfully banned " +
message.user.id +
"for " +
reason
);
const embed = new Discord.RichEmbed()
.setTitle("Ban")
.addField("Member:", message.user.id)
.addField("Reason:", reason)
.setTimestamp()
.setFooter(
"Created by OverThrow, OverBot SE",
"https://cdn.discordapp.com/avatars/649431468254429224/0b63291c1e7342c2320ca5c3cce806ca.png?size=2048"
);
})
.catch(err => {
message.reply(":x: I was unable to ban that member!");
console.error(err);
});
} else {
message.reply(":x: That user isn't a member to this guild!");
}
} else {
message.reply(":x: You didn't mention a member to ban!");
}
}
} else {
message.reply(":x: I couldn't ban this user, please make sure you have the OverBot-Admin role!")
}
message.member.roles.has() requires a role ID as an argument, whereas here, you are passing in a function. The method I think you are looking for is Collection.exists (although this method is deprecated, if anyone can figure out a different way to go about this, please let me know).
Looking at the message.reply in the then function after banning, I see a message.user.id. However, message.user does not seem to be a valid property of the message object according to the docs. I assume that you would be referring to the user who was just banned, in which case you can reuse the user or member variable you previously defined.
If you have further problems, feel free to comment back.
Related
I'm looking to see if you can check if you can test for a specific user having a role. Only problem is that I'm fairly new to Discord.js and everything I searched up was either outdated, was something I couldn't fully understand or only showed how to test if the author of the message has the role, which is not what I'm trying to find out. What should I change in my current coding?
if (message.member.permissions.has("MANAGE_ROLES")) {
const member = message.mentions.users.first();
const memberTarget = message.guild.members.cache.get(member.id);
const role = message.guild.roles.cache.find(role => role.name === "Awesome Role Name");
if (memberTarget.roles.cache.has(role)) {
message.channel.send(`${memberTarget} has the role!`);
} else {
message.channel.send(`${memberTarget} does not have the role!`);
}
}
}
};
All you have to do is check if the GuildMember.roles.cache has the role. Also, the reason your code isn’t working is because you are using the role object. You need to use the role ID.
if (memberTarget.roles.cache.has(role.id))
More related things:
Getting role by any property
if (memberTarget.roles.cache.some(r => r.name === 'role-name'))
//does not need to be the name
Getting message author's roles
if (message.member.roles.cache.has(role.id))
To check for a role you can do the code:
if (member.roles.cache.has("ROLE_ID"))
If you wanted to check if the sender has the role you could do:
if (message.member.roles.cache.has("ROLE_ID")) {
console.log(true);
} else {
console.log(false);
}
If you wanted to check if someone else has a role you could do:
if (memberTarget.roles.cache.has("ROLE_ID")) {
console.log(true);
} else {
console.log(false);
}
To get a member you could do it in many different ways, one method would be to get them by mentions:
// This will get the first mention who is a member in the server
const memberTarget = message.mentions.members.first()
Read about guild member roles here
the kicking part of the command works correctly and then correctly sends a message saying it has kicked the mentioned person. However I want the bot to send a message saying that you need to mention a user if no user was mentioned. I also want the bot to send a message if either the player trying to use the bot does not have the proper permissions to kick someone or if the bot cant kick the person the user is trying to use the bot to kick.
This is my code for what I'm trying to do.
Crashbot.on('message', message => {
if (message.member.hasPermission("KICK_MEMBERS")) {
if (message.content.startsWith(prefix + 'kick')) {
const user = message.mentions.users.first();
if (user) {
const member = message.guild.member(user);
if (member) {
member.kick('optional reason that will display in the audit logs')
.then(() => {
// We let the message author know we were able to kick the person
message.reply(`Successfully kicked ${user.tag}`);
})
.catch(err => {
message.reply('I was unable to kick that user');
console.error(err);
});
} else {
message.reply("You need to mention a user to kick");
}
}
}
}
});
That's the one I use. It checks if you have mentioned anything to begin with, it gives you a warning message if it can't find the user, it won't work if you don't have permission to kick people and if it can't kick the person it will tell you that he couldn't kick him. Plus you can provide an optional reason for the kick after.
Example usage: !kick #Apolko24 Bad word usage
const kUser = message.guild.member(message.mentions.users.first());
if (!args[0]) return message.channel.send('Please mention someone');
if (!kUser) return message.channel.send(`I can't find ${args[0]}`);
if (!message.member.hasPermission('KICK_MEMBERS')) return message.channel.send("You can't kick users");
if (kUser.hasPermission('MANAGE_GUILD')) return message.channel.send("That user can't be kicked");
const kReason = args.join(" ").slice(22);
if (kReason) {
const kickEmbed = new MessageEmbed()
.setTitle("Kick")
.setColor(0xbbffff)
.addField("Kicked user:", `${kUser}`)
.addField("Kicked by:", `${message.author}`)
.addField("Reason", kReason)
message.guild.member(kUser).kick();
message.channel.send(kickEmbed);
} else {
const kickEmbed = new MessageEmbed()
.setTitle("Kick")
.setColor(0xbbffff)
.addField("Kicked user:", `${kUser}`)
.addField("Kicked by:", `${message.author}`)
message.guild.member(kUser).kick();
message.channel.send(kickEmbed);
}
(you have to put this into your if (message.content.startsWith(prefix + 'kick')) statement)
I've done tons and tons of searches but they're all super complex codes such as, when i say "!Role (role)" then it gives me the role i specified. However, what i am looking for is something much simpler like if i were to say "Hello", then the bot would give me the role that's in the code.
I also tried a lot of the complex ones but most of them used the "addRole" function but the output didn't like it
Do you think you can help me with this?
Discord JS V12:
client.on("message", (message) => {
// Checking if the message equals to "hello".
// Since we use .toLowerCase() which converts any uppercase letter to lowercase, HeLLo will result in hello.
if (message.content.toLowerCase() == "hello") {
// Trying to find the role by ID.
const Role = message.guild.roles.cache.get("RoleID");
// Checking if the role exists.
if (!Role) { // The role doesn't exist.
message.channel.send(`I'm sorry, the role doesn't exist.`);
} else { // The role exists.
// Adding the role to the user.
message.member.roles.add(Role).catch((error) => {console.error(error)});
message.channel.send(`You received the role ${Role.name}.`);
};
}
});
Discord JS V11:
client.on("message", (message) => {
if (message.content.toLowerCase() == "hello") {
const Role = message.guild.roles.get("RoleID");
if (!Role) {
message.channel.send(`I'm sorry, the role doesn't exist.`);
} else {
message.member.addRole(Role).catch((error) => {console.error(error)})
message.channel.send(`You received the role ${Role.name}.`);
};
}
});
bot.on('messageReactionAdd', async (reaction, user) => {
// Define the emoji user add
let role = message.guild.roles.find(role => role.name === 'Alerts');
if (message.channel.name !== 'alerts') return message.reply(':x: You must go to the channel #alerts');
message.member.addRole(role);
});
Thats the part of my bot.js. I want the user to react in a certain channel and receive role Alerts
You haven't really stated what the problem is, what works and what doesn't work but I'll take a wild stab at some parts which catch my eye.
For starters you are calling properties on the variable message whilst in the code you supplied, you didn't create/set a variable named message. My guess is that you want the message to which a reaction has been added. To do that you have to use the MessageReaction parameter which is supplied in the messageReactionAdd event as reaction.
From there you can replace message.<something> with reaction.message.<something> everywhere in the code you supplied.
Something also to note is that you add the role Alerts to message.member. This won't work how you want it to, since it will give the Alerts role to the author of the original message.
What (I think) you want to do, is fetch the user who just reacted with the emoji and assign them the Alerts role. You'll have to find the member in the guild first and then assign them the Alerts role. To do this you'll have to use the User parameter and find the correct Member because you can't add a role to a User object but you can to a Member object. Below is some code which should hopefully put you on the right track.
// Fetch and store the guild (the server) in which the message was send.
const guild = reaction.message.guild;
const memberWhoReacted = guild.members.find(member => member.id === user.id);
memberWhoReacted.addRole(role);
You are using message.member variable despite not defining message.
Any of these methods won't really work in v12 so I updated it for someone else searching.
If you find any mistakes be sure to make me aware of it.
const Discord = require('discord.js');
const client = new Discord.Client({ partials: ['MESSAGE', 'CHANNEL', 'REACTION'] }); //partials arent really needed but I woudld reccomend using them because not every reaction is stored in the cache (it's new in v12)
const prefix = "-";
client.on('messageReactionAdd', async (reaction, user) => {
if (reaction.partial) { //this whole section just checks if the reaction is partial
try {
await reaction.fetch(); //fetches reaction because not every reaction is stored in the cache
} catch (error) {
console.error('Fetching message failed: ', error);
return;
}
}
if (!user.bot) {
if (reaction.emoji.id == yourEmojID) { //if the user reacted with the right emoji
const role = reaction.message.guild.roles.cache.find(r => r.id === yourRoleID); //finds role you want to assign (you could also user .name instead of .id)
const { guild } = reaction.message //store the guild of the reaction in variable
const member = guild.members.cache.find(member => member.id === user.id); //find the member who reacted (because user and member are seperate things)
member.roles.add(role); //assign selected role to member
}
}
})
Here's a quick answer, though way too late. So I'll be updating the answer with Discord.js v.12.x (or the same as Discord.js Master)
bot.on('messageReactionAdd', async (reaction, user) => {
//Filter the reaction
if (reaction.id === '<The ID of the Reaction>') {
// Define the emoji user add
let role = message.guild.roles.cache.find((role) => role.name === 'Alerts');
if (message.channel.name !== 'alerts') {
message.reply(':x: You must go to the channel #alerts');
} else {
message.member.addRole(role.id);
}
}
});
So, I am making a public discord bot, but I am having trouble with one part of my script. My kick/ban commands are made to be done $ban #user It has to be done in a ping. Since this is public, I really want to fix this. I don't want one person to mess up and crash it to crash it for all servers. If someone does $ban user not in a ping, it crashes the bot. Here is my code:
client.on("message", (message) => {
if (message.content.startsWith("$kick")) {
if (!message.member.roles.find("name", "MODS"))
return;
// Easy way to get member object though mentions.
var member = message.mentions.members.first();
// Kick
member.kick().then((member) => {
// Successmessage
message.channel.send(":wave: " + member.displayName + " has been successfully kicked :point_right: ");
}).catch(() => {
// Failmessage
message.channel.send("Access Denied");
});
}
});
I don't want my bot to keep crashing to ruin the use for others, can anyone help out?
Your code crashed when you have no mention because you did not catch this use case.
Adding a simple catch, with a return for example, should work for you :
client.on("message", (message) => {
if (message.content.startsWith("$kick")) {
if(!message.member.roles.find("name", "MODS"))
return;
// Easy way to get member object though mentions.
var member= message.mentions.members.first();
// No mentions catch
if (member === undefined) return;
// Kick
member.kick().then((member) => {
// Successmessage
message.channel.send(":wave: " + member.displayName + " has been successfully kicked :point_right: ");
}).catch(() => {
// Failmessage
message.channel.send("Access Denied");
});
}
});
I think what is happening when you type $ban user (Which isn't a mention), and later when you assign var member = message.mentions.members.first(); it gives you null (Because no one was mentioned). Try to make sure that message.mentions.members isn't empty.
Cheers :)