Ban/kick command crashes on use - javascript

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 :)

Related

Bot keeps crashing when wrong command is sent. [Discord JS]

I'm trying to make an Arby's Bot. Whenever someone sends a message in the channel, the bot crashes and bot doesn't work.
client.on("message", (message) => {
if (message.content.startsWith("arbys") || message.guild.channel == message.guild.channels.cache.get("843008525335920651")) {
} else
setTimeout(() => message.delete(), 1);
message.author.send("**arbys** Only Arbys. GOT IT?")
});
If someone could please help me that would be amazing.
its because message.guild does not have a channel property, instead do this
if (message.content.startsWith("arbys") || message.channel.id == "843008525335920651"){
hope this helped >:D
message.guild doesn't have a channel property, but that's not the only problem. You can't compare an object (message.guild.channel) to another object (message.guild.channels.cache.get("843008525335920651")) like that. You can, however, check if the channel the message is sent in has the same ID as you want (843008525335920651).
You can also delete the message after you sent a DM to the message author using the .then() method. Check out the code below:
client.on('message', (message) => {
if (
message.content.startsWith('arbys') ||
message.channel.id === '843008525335920651'
) {
// do something ?
console.log('Correct channel or command');
} else {
// send a DM to the author
message.author
.send('**arbys** Only Arbys. GOT IT?')
// and delete the original message
.then(() => message.delete())
// catch them errors :)
.catch((error) => console.log(error));
}
});

Discord.js Bots // Trying to add multiple bots in main file, setting status', randomize welcome messages, multiple prefixes

I planned to create a discord server with bots. There are quite a lot (6 in total) and are just supposed to be fictional characters with some background story. I'm quite new and all of that is way too complicated for me to code myself, therefor I ask for your help! I just want to have a nice server for my friends and I with enjoyable bots and all of these desperate hours of trying to get some useful code is driving me nuts..
I only managed to get one bot to do stuff, using the prefix "-".
It can change it's status (watching, listening, playing) and the name of the thing he's doing.
I'm not quite sure why streaming doesn't work or if that's possible in general but it would be really cool if it would.
My status code: (1st Problem)
client.once('ready', () => {
console.log('Bot is ready!');
if (config.activity.streaming == true) {
client.user.setActivity(config.activity.game, {type: 'WATCHING'}); //STREAMING, PLAYING, LISTENING
} else {
client.user.setActivity(config.activity.game, {url: 'https://twitch.tv/usrname'});
client.user.setStatus('idle'); //dnd, idle, online, invisible
}
});
config.json
"activity": {
"streaming": true,
"game": "Whatevergame"
}
}
As I said, streaming is not working for some reason and the status (idle, dnd..) is also not working.
2nd Problem
If I try to add other bots with the login, it will log both bots on, but only one of them will work, what's actually pretty logical since the commands are all made for only one bot. So I'm trying to figure out how to get them all packed into the main file.
3rd Problem
I used the try - catch function to execute commands, which I pre- set up, and if theres none, it sends an error message. See for yourself:
client.on('message', message =>{
if (!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).split(/ +/);
const command = args.shift().toLowerCase();
try {
client.commands.get(command).execute(message, args);
}
catch {
message.channel.send("I don't know that, sorry.");
}
});
So everytime I type another command, from which I do not want the bot to respond to, it will respond with "I don't know[...]" It would be sufficient to just set up another prefix for the "other command" to fix that problem so the bot knows that for every prefix starting with a.e "-", it has to send an error message if that command is not existing. But for other prefixes, a.e "?", it's supposed to execute the other command/s.
4th Problem
My (current) last problems are the welcome messages. My code:
index.js
const welcome = require("./welcome");
welcome (client)
welcome.js
module.exports = (client) => {
const channelId = '766761508427530250' // welcome channel
const targetChannelId = '766731745960919052' //rules and info
client.on('guildMemberAdd', (member) => {
console.log(member)
const message = `New user <#${member.id}> joined the server. Please read through ${member.guild.channels.cache.get(targetChannelId).toString()} to gain full access to the server!`
const channel = member.guild.channels.cache.get(channelId)
channel.send(message)
})
}
The code is working perfectly fine, however it would be way more exciting with a little more variety. I'm trying to get multiple welcome messages that get randomly chosen by the bot.. I thought about a Mathfloor as an approach but I'm not quite sure how that would work..
Thank you for reading through my text and I hope that I will soon be able to enjoy the server with my guys!
Cheers!
First problem
I'm not sure why ClientUser.setActivity() and ClientUser.setStatus is not working. In the STREAMING example, it might be because you didn't specify the type of activity. Either way, there's an easier way to what you're doing, which is ClientUser.setPresence(). This method is kind of like a combination of the other two.
client.once('ready', () => {
console.log('Bot is ready!');
config.activity.streaming
? client.user.setPresence({
activity: { name: config.activity.game, type: 'WATCHING' },
})
: client.user.setPresence({
activity: {
name: config.activity.game,
type: 'STREAMING',
url: 'https://twitch.tv/usrname',
},
status: 'idle', // note: the idle icon is overwritten by the STREAMING icon, so this won't do much
});
});
Second Problem
It's pretty hard to make multiple bots, both duplicates of each other, in one file. I would recommend just using a lot of Array.prototype.forEach() loops to apply all events and such to both clients.
[1, 2, 3].forEach((num) =>
console.log(`The element I'm currently iterating a function through is ${num}`)
);
// example main file
const { Client, Collection } = require('discord.js');
const [roseClient, sunflowerClient] = [new Client(), new Client()];
// adding properties:
[roseClient, sunflowerClient].forEach((client) => client.commands = new Collection())
// events
[roseClient, sunflowerClient].forEach((client) =>
client.on('message', (message) => {
// ...
});
);
// login
roseClient.login('token1');
sunflowerClient.login('token2');
Third problem
Again, forEach() loops save the day (❁´◡`❁). This time, however, you should actually use Array.prototype.every(), which will return true if every element of an array passes the given test.
Basically, if we were to use a normal forEach() loop, then even if one of the prefixes found the match, the other wouldn't and the error message would always be sent out. So instead we'll use every() to only send out an error message if both prefixes find no match.
// what if we ony wanted the error message if *every* number was 3
[1, 2, 3].forEach((num) => {
if (num === 3) console.error('Error message');
});
console.log('--------------------');
// now it will only send if all numbers were three (they're not)
if ([1, 2, 3].every((num) => num === 3))
console.error('Error message');
client.on('message', (message) => {
if (['-', '?'].every((prefix) => {
if (!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).split(/ +/);
const command = args.shift().toLowerCase();
try {
// it did not pass the test (the test being finding no match), and the error message should not be displayed
return false;
client.commands.get(command).execute(message, args);
} catch {
// it did pass the test (by finding no match). if the next test is failed too, the error message should be displayed
return true;
message.channel.send("I don't know that, sorry.");
}
});
});
Fourth Problem
You're on the right track! Math.floor() is definitely the right way to get a random element from an array.
function chooseFood() {
// make an array
const foods = ['eggs', 'waffles', 'cereal', "nothing (●'◡'●)", 'yogurt'];
// produce a random integer from 0 to the length of the array
const index = Math.floor(Math.random() * foods.length);
// find the food at that index
console.log(`Today I will eat ${foods[index]}`);
};
<button onClick="chooseFood()">Choose What to Eat</button>
module.exports = (client) => {
client.on('guildMemberAdd', (member) => {
console.log(member);
const welcomes = [
`Welcome ${member}!`,
`Woah! Didn't see you there ${member}; welcome to the server!`,
`${member} enjoy your stay at ${member.guild}!`,
];
const message = `${
welcomes[Math.floor(Math.random() * welcomes.length)]
} Please read through ${member.guild.channels.cache.get(
'766731745960919052'
)} to gain full access to the server!`;
member.guild.channels.cache.get('766761508427530250').send(message);
});
};
That was a mouthful (╯°□°)╯︵ ┻━┻

I want to make my discord bot be able to reply to a command with a username with a link that contains the inputted username

I want the user to input !fn maxtl and the bot would reply by putting out this link
https://fortnitetracker.com/profile/all/maxtl/event
This is what I am thinking it would look like. Can someone provide me with any suggestions on how to improve this Discord bot API usage?
bot.on("message", (msg) => {
if (msg.content === `!fn ${Username}`) {
msg.reply(`https://fortnitetracker.com/profile/all/${Username}/events`);
}
});
Assuming you aren't doing any other processing of the message, this is what you'll probably need to do.
bot.on("message", (msg) => {
if (!msg.content.startsWith('!')) return;
const arguments = msg.content.split(' ');
const command = arguments.shift();
if (command === '!fn') {
msg.reply(`https://fortnitetracker.com/profile/all/${arguments[0]}/events`);
}
});
This will
Check and see that the message begins with your command identifier (assuming it's "!")
Split the message in to an array of arguments;
Remove and store the command in a command variable
Check to see if the command is equal to "!fn"
Reply with a url that includes argument[0] which at this point would be equal to the username if one was provided.
I think this block of code is something you are looking for, I am not 100% because I don't know what the rest of your bot is doing.
This code will
Listen for a message
The bailout of the code execution if the message doesn't start with !fn
Attempts to find the message with mentioned Username (your snippet shows this variable
available so I assume it's known beforehand, if not we can figure that out too)
The Bot tries to post the message
bot.on('message', async (msg) => {
if (!msg.content.startsWith('!fn')) return;
const commandFound = msg.content.find(mentioned => mentioned === `!fn ${Username}`)
const arguments = commandFound.split(' ');
const userName = arguments.shift();
if (userName) {
try {
await msg.reply(`https://fortnitetracker.com/profile/all/${userName}/events`);
} catch (err) {
console.warn('Failed to respond to mention.');
console.warn(err);
}
}
});

Im trying to make a discord bot mostly just for fun but i cant seem to get the if else statements used in my kick command to work properly

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)

How to check if someone has a certain role

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.

Categories