Why does bulkDelete not work with no error? - javascript

I've tried to look for typo and other inaccuracies and tried to add permission requirement for the prune command but still, the ping pong and the "not a valid number" replies work but not the prune when I enter the amount.
Details: I'm trying to make a Discord bot that can prune based on input. I use DJS v12 and follow(ed) this guide https://v12.discordjs.guide/creating-your-bot/commands-with-user-input.html#number-ranges
if (!msg.content.startsWith(prefix) || msg.author.bot) return;
if (!msg.member.hasPermission("BAN_MEMBERS")) {
msg.channel.send("You don\'t have permission.");
}
const args = msg.content.slice(prefix.length).trim().split('/ +/');
const cmd = args.shift().toLowerCase();
if (cmd === `ping`) {
msg.reply('pong.');
} else if (cmd === `prune`) {
if (!msg.guild.me.hasPermission("MANAGE_MESSAGES")) return;
const amount = parseInt(args[0]) + 1;
if (isNaN(amount)) {
return msg.reply('Not a valid number.');
} else if (amount <= 1 || amount > 100) {
return msg.reply('Please input a number between 1 and 99.');
}
msg.channel.bulkDelete(amount, true).catch(err => {
console.error(err);
msg.channel.send('Error!');
});
}
});

The reason why your prune command doesn't work, is because of your command parsing. args is always null whereas cmd always contains the whole string.
So if you enter $prune 3, your args will be empty and cmd contains prune 3. That's why your if here:
else if (cmd === `prune`)
doesn't match (if you specified arguments) and your prune command never gets executed.
To fix that, you have change your command parsing:
const cmd = msg.content.split(" ")[0].slice(prefix.length);
const args = msg.content.split(" ").slice(1);
Note: Also you seem to have a typo in your question:
if (!msg.guild.me.hasPermission("MANAGE_MESSAGES") return;
// Missing ")" here ----^
So change that line to
if (!msg.guild.me.hasPermission("MANAGE_MESSAGES")) return;

Related

How to set a variable to a voice channel specified by a user - Discord.js

I'm pretty new to discord.js and JavaScript in general so apologies if this is something really simple!
I'm working on a Discord bot and I'm trying to make it set a variable to a voice channel specified by the user. Currently, ChosenChannel remains null. It works if I replace args with the channel name directly in the code (line 8) but then it can't be changed by a user.
Thanks in advance for any help!
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();
if (command == 'setchannel') {
//set ChosenChannel to a channel within the current server that matches the name typed by the user (not currently working!)
ChosenChannel = message.guild.channels.cache.find(channel => channel.name === args);
//alert user if ChosenChannel is not an actual channel
if (ChosenChannel == null) {
message.channel.send('Unable to find channel');
//alert user if ChosenChannel is not a voice channel
} else if (ChosenChannel.type !== 'voice') {
message.channel.send('That does not seem to be a voice channel');
//otherwise, confirm that the command worked, and print the name of the channel
} else {
message.channel.send('The chosen channel is: ');
message.channel.send(ChosenChannel.name);
}
}
});
args is an array, the channel's name is a string. So you'll need to convert args to a string by joining it back by a space character.
if (command == 'setchannel') {
//set chosenChannel to a channel within the current server that matches the name typed by the user (not currently working!)
const channelName = args.join(' ')
const chosenChannel = message.guild.channels.cache.find(
(channel) => channel.name === channelName,
);
//alert user if chosenChannel is not an actual channel
if (!chosenChannel) {
message.channel.send('Unable to find channel');
//alert user if chosenChannel is not a voice channel
} else if (chosenChannel.type !== 'voice') {
message.channel.send('That does not seem to be a voice channel');
//otherwise, confirm that the command worked, and print the name of the channel
} else {
message.channel.send('The chosen channel is: ');
message.channel.send(chosenChannel.name);
}
}
Actually, channel names can't have spaces, so it will be always the first element of args, so you could also use it like this:
if (command == 'setchannel') {
//set chosenChannel to a channel within the current server that matches the name typed by the user (not currently working!)
const chosenChannel = message.guild.channels.cache.find(
(channel) => channel.name === args[0],
);
// ...

SyntaxError: Value expected (char 1)

I'm trying to make a !calculate command in Discord.js v12.
I'm using mathjs and this is my current code:
client.on('message', msg => {
if(!msg.content.startsWith('!')) return;
const args = msg.content.split(/[\ ]/g);
const cmd = args[0].slice(1).toLowerCase();
switch (cmd) {
case 'calculate':
case 'calc':
if(!args[0]) return msg.channel.send('Please input a calculation.');
let resp;
try {
resp = math.evaluate(args.join(''));
} catch (e) {
console.log(e);
}
const membed = new Discord.MessageEmbed()
.setColor('#ffaa00')
.setTitle('Math Calculation')
.addField('Input', `\`\`\`css\n${args.slice(1).join(' ')}\`\`\``)
.addField('Output', `\`\`\`css\n${resp}\`\`\``);
msg.channel.send(membed);
break;
However, I get the following console error:
SyntaxError: Value expected (char 1)
at createSyntaxError (D:\Documents\test\Node.js\Discord.js\calculate\node_modules\mathjs\lib\expression\parse.js:1705:17)
at parseEnd (D:\Documents\test\Node.js\Discord.js\calculate\node_modules\mathjs\lib\expression\parse.js:1669:13)
at parseParentheses (D:\Documents\test\Node.js\Discord.js\calculate\node_modules\mathjs\lib\expression\parse.js:1655:12)
at parseNumber (D:\Documents\test\Node.js\Discord.js\calculate\node_modules\mathjs\lib\expression\parse.js:1626:12)
at parseObject (D:\Documents\test\Node.js\Discord.js\calculate\node_modules\mathjs\lib\expression\parse.js:1607:12)
at parseMatrix (D:\Documents\test\Node.js\Discord.js\calculate\node_modules\mathjs\lib\expression\parse.js:1532:12)
at parseSingleQuotesString (D:\Documents\test\Node.js\Discord.js\calculate\node_modules\mathjs\lib\expression\parse.js:1433:12)
at parseDoubleQuotesString (D:\Documents\test\Node.js\Discord.js\calculate\node_modules\mathjs\lib\expression\parse.js:1382:12)
at parseSymbol (D:\Documents\test\Node.js\Discord.js\calculate\node_modules\mathjs\lib\expression\parse.js:1270:12)
at parseCustomNodes (D:\Documents\test\Node.js\Discord.js\calculate\node_modules\mathjs\lib\expression\parse.js:1239:12) {
char: 1
}
The embed looks like this:
You are handling the args array incorrectly. There are 2 issues:
args[0] needs to be changed to args[1], as args[0] is
referencing the command, not the calculation.
if(!args[0]) return msg.channel.send('Please input a calculation.');
// should become
if(!args[1]) return msg.channel.send('Please input a calculation.');
args.join('') needs to be changed to args.slice(1).join(''), so that it only contains the calculation and not the command at the start.
resp = math.evaluate(args.join(''));
// should become
resp = math.evaluate(args.slice(1).join(''));

Discord.JS how to transfer args

I need to transfer arguments from one command to another.
Command that I need to transfer args (Order) from:
const invite = await message.channel.createInvite()
if(cmd === `${prefix}order`){
if(!args) return message.reply("Please specify what you would like to order.")
console.log(args)
baseOrderNumber++;
var order = args.join(" ")
let orderEmbed = new Discord.MessageEmbed()
orderIcon = "https://i.imgur.com/Le0Eist.png"
orderEmbed.setTitle("New Order")
orderEmbed.setColor("#FF2D00")
orderEmbed.setThumbnail(orderIcon)
orderEmbed.addField("Order Number", baseOrderNumber)
orderEmbed.addField("Order", order)
orderEmbed.addField("Customer", message.author)
orderEmbed.addField("Server Invite", invite)
bot.channels.cache.get('723838675489914891').send(orderEmbed)
let eekowo = fs.writeFileSync('orderAuthors.txt', message.author.tag, order);
}
Command I need to transfer to:
if(cmd === `${prefix}deliver`){
if(!args[1]) message.reply("Please provide an order number.")
let eekowo2 = fs.readFileSync('orderAuthors.txt', 'utf8')
deliverEmbed = new Discord.MessageEmbed()
deliverIcon = message.guild.iconURL
deliverEmbed.addField("Invite", invite)
deliverEmbed.addField("Customer", eekowo2)
deliverEmbed.addField("Items", orderEmbed.order)
message.author.send(deliverEmbed)
}
Is this possible? and if so; how?
You have a couple options:
If you are using a command handler, then you can require() the other command file, and call the function containing it's code through module.exports, and pass in args as an parameter.
If you're not using a command handler, and all commands are in your index(or bot).js file, take the code of the 2nd command, and copy it into a function in the global scope, then call the function in its place in the normal part of the if statement, and the first command, passing in args as a parameter to both, in addition to all other necessary information, such as "message".
Copy the code you want to run into the first command. (not recommended, but possible)
My recommendation would be to take option 1, but it appears as though you aren't using a command handler, so here's a possible application of #2:
// 1st command
const invite = await message.channel.createInvite()
if (cmd === `${prefix}order`) {
if (!args) return message.reply("Please specify what you would like to order.")
console.log(args)
baseOrderNumber++;
var order = args.join(" ")
let orderEmbed = new Discord.MessageEmbed()
orderIcon = "https://i.imgur.com/Le0Eist.png"
orderEmbed.setTitle("New Order")
orderEmbed.setColor("#FF2D00")
orderEmbed.setThumbnail(orderIcon)
orderEmbed.addField("Order Number", baseOrderNumber)
orderEmbed.addField("Order", order)
orderEmbed.addField("Customer", message.author)
orderEmbed.addField("Server Invite", invite)
bot.channels.cache.get('723838675489914891').send(orderEmbed)
let eekowo = fs.writeFileSync('orderAuthors.txt', message.author.tag, order);
Deliver(message, Discord, args);
}
// 2nd command
if (cmd === `${prefix}deliver`) {
Deliver(message, Discord, args);
}
// In the global scope
function Deliver(message, embed, args) {
if (!args[1]) message.reply("Please provide an order number.")
// ^ If this is an error check, you may want to put return here, before the reply
let eekowo2 = fs.readFileSync('orderAuthors.txt', 'utf8')
deliverEmbed = new Discord.MessageEmbed()
deliverIcon = message.guild.iconURL
deliverEmbed.addField("Invite", invite)
deliverEmbed.addField("Customer", eekowo2)
deliverEmbed.addField("Items", orderEmbed.order)
message.author.send(deliverEmbed)
}
}

In need of assistance fixing a command for my Discord bot

I'm making a fun bot for my server and I wanted a spam command, to use it you'd need to include a number of how many times it's gonna spam it, then a message. But as it is right now it won't run, nor does it give me any errors.
function repeat(func, times) {
func();
--times && repeat(func, times);
}
exports.run = (client, message, args) => {
if (!args[0] || isNaN(args[0]) || !args[2]) return;
repeat(function(){
message.channel.send(args.slice(1).join(' ')).catch(console.log)
}, args[0]);
}
I expect that it's going to spam the message as many times as the number.
For example:
ME: !spam 3 Hi
BOT: Hi
BOT: Hi
BOT: Hi
Try a for instead.
exports.run = (client, message, args) => {
if (!args[0] || isNaN(args[0]) || !args[2]) return;
for (let index = 0; index < args[0]; index++) {
message.channel.send(args.slice(1).join(' ')).catch(console.log)
}
}
exports.run = (client, message, args) => {
const max = parseInt(args.shift()); // takes the first element of args and converts it to a Number
if (isNaN(max)) return message.channel.send('You need to enter a valid Number'); // check if its really a number
if(!args[0]) return message.channel.send('You need to enter a text to send'); // check if spam text is there
// Add a check to make s sure !spam 100 text is not possible.
for (let i = 0; i < max; i++) { // For - Loop
message.channel.send(args.join('')).catch(console.log); // Send it
}
}

Why doesn't kicking people work using discord.js

const Discord = require("discord.js"),
bot = new Discord.Client();
let pre = "?"
bot.on("message", async msg => {
var msgArray = msg.content.split(" ");
var args = msgArray.slice(1);
var prisonerRole = msg.guild.roles.find("name", "Prisoner");
let command = msgArray[0];
if (command == `${pre}roll`) {
if (!msg.member.roles.has(prisonerRole.id)) {
roll = Math.floor(Math.random()*6)+1;
msg.reply(`You rolled a ${roll}`)
} else {
msg.reply(`HaHa NOOB, you're in prison you don't get priveleges!`)
}
}
if (command == `${pre}kick`) {
var leaderRole = msg.guild.roles.find("name", "LEADER");
var co_leaderRole = msg.guild.roles.find("name", "CO-LEADER");
if (msg.member.roles.has(leaderRole.id) ||
msg.member.roles.has(co_leaderRole.id)) {
var kickUser = msg.guild.member(msg.mentions.users.first());
var kickReason = args.join(" ").slice(22);
msg.guild.member(kickUser).kick();
msg.channel.send(`${msg.author} has kicked ${kickUser}\nReason: ${kickReason}`);
} else {
return msg.reply("Ya pleb, you can't kick people!");
}
}
})
bot.login("token").then(function() {
console.log('Good!')
}, function(err) {
console.log('Still good, as long as the process now exits.')
bot.destroy()
})
Everything works except actually kicking the person. The message sends nut it doesn't kick people. For example, when I type in ?kick #BobNuggets#4576 inactive, it says
#rishabhase has kicked #BobNuggets
Reason: inactive
But it doesn't actually kick the user, which is weird, can you help me?
Change
msg.guild.member(kickUser).kick();
to
kickUser.kick();
also, make sure the bot is elevated in hierarchy
Use kickUser.kick();
I recommend using a command handler to neaten up your code. You don't want all your commands in one .js file.
Try something like this for the Ban command itself. I use this for my Bot:
client.on("message", (message) => {
if (message.content.startsWith("!ban")) {
if(!message.member.roles.find("name", "Role that can use this bot"))
return;
// Easy way to get member object though mentions.
var member= message.mentions.members.first();
// ban
member.ban().then((member) => {
// Successmessage
message.channel.send(":wave: " + member.displayName + " has been successfully banned :point_right: ");
}).catch(() => {
// Failmessage
message.channel.send("Access Denied");
});
}
});
That should work, set the role you want to use it (cAsE sEnSiTiVe) and change !ban to whatever you feel like using. If you change all "ban"s in this to kick, it will have the same effect. If this helped you, mark this as the answer so others can find it, if not, keep looking :)

Categories