To get the files with commands (such as ping.js)
module.exports = {
name: 'ping',
description: 'Play some ping pong.',
execute(message, args) {
const bot = require('../bot.js');
message.channel.send('pong!');
bot.log(message, '$ping', message.guild.name);
},
};
I use this in bot.js
const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js'));
for(const file of commandFiles){
const command_file = require(`./commands/${file}`);
client.commands.set(command_file.name, command_file);
}
I'm trying to set the variable for the command with this:
let command = '';
if(message.content.includes(' ')){
command = message.content.substr(1, message.content.indexOf(' ')).toLowerCase();
} else {
command = message.content.substr(1).toLowerCase();
}
which returns the name of the command as a string, like 'info' or 'ping'.
But, when I put that variable into client.commands.has() it doesnt find the command and returns back with this:
if(!client.commands.has(command)) return;
I cant find any answers to this online so I figured I'd ask, sorry if this doesnt fit
Try this instead:
const cmd =
message.client.commands.get(command) ||
message.client.commands.find(
(cmd) => cmd.aliases && cmd.aliases.includes(command) // if you're also using aliases
);
if (!command) return;
Related
When I include spaces in my command names, those commands won't run. I'm using a command handler and in my index.js file, we have:
client.on('message', msg => {
if (!msg.content.startsWith(prefix) || msg.author.bot) return;
const args = msg.content.slice(prefix.length).trim().split(/ +/g);
const commandName = args.shift().toLowerCase();
const command = client.commands.get(commandName)
|| client.commands.find(cmd => cmd.aliases && cmd.aliases.includes(commandName));
if (!command) return;
try {
command.execute(msg, args);
} catch (error) {
console.error(error);
msg.reply("I'm encountering an error trying to execute that command. Please try again.");
}
});
and in my command.js file, we have:
module.exports = {
name: 'command name',
execute(msg, args) {
msg.channel.send("command");
},
};
When I change command name to command-name or to commandname it works! But when it's command name, my bot doesn't output any response... not even an error message. Where am I going wrong? Is there some simple solution or workaround that I'm overlooking? Thanks in advance.
This is because you shift() your arguments in the line
const commandName = args.shift().toLowerCase();
This takes the first argument and returns it, any following arguments will not be included.
To take the first 2 argument use
const commandName = args.splice(0, 2);
Change command to the following to account for any other arguments.
const command = client.commands.get(commandName.join(' ').toLowerCase())
|| client.commands.find(cmd => cmd.aliases && cmd.aliases.includes(commandName.join(' ').toLowerCase()));
I have subfolders for each of my commands and I'm wondering how I would check the name of the command's folder without having to add code into the command file itself. I've tried folders.filter(folder => folder.includes(command) and I'm hoping there's a similar way that could help me.
const folders = fs.readdirSync(`./categories`);
for (const folder of folders) {
const files = fs.readdirSync(`./categories/${folder}`);
for (const file of files) {
const command = require(`./categories/${folder}/${file}`);
client.commands.set(command.name, command);
};
};
client.on("message", async message => {
if (command.args && !args.length) {
const commandArgs = new Discord.MessageEmbed()
.setAuthor(command.category) // HERE - how would i check what subfolder the given command is in?
.setTitle(command.name)
.setDescription(command.description);
}
//code...
});
You can simply add a property when retrieving it:
const command = require(`./categories/${folder}/${file}`);
command.folder = folder;
client.commands.set(command.name, command);
Now you can use it when referencing the object:
const commandArgs = new Discord.MessageEmbed()
.setTitle("From folder: " + command.folder);
so i'm trying this 8ball bot, and everything is working fine, but i can't get how can i leave in the condition that only when the bot get "!verda arg1 arg2" it answers one of the replies in the array.
meanwhile my condition is if the user type the prefix "!verda" only, it replies , i want to include the argument too in the condition
const Discord = require("discord.js");
const client = new Discord.Client();
const cfg = require("./config.json");
const prefix = cfg.prefix;
client.on("message", msg => {
if (!msg.content.startsWith(prefix) || msg.author.bot) return;
const args = msg.content.slice(prefix.length).split(/ +/);
const command = args.shift().toLowerCase;
if (msg.content === prefix){
let replies = [
"Yes.",
"No.",
"I don't know.",
"Maybe."
];
let result = Math.floor((Math.random() * replies.length));
msg.channel.send(replies[result]);
}
else if (msg.content === "!help"){
msg.channel.send("I have only 1 command [!verda]");
}
})
client.login(cfg.token);
const command = args.shift().toLowerCase;
toLowerCase is a function and therefore should be
const command = args.shift().toLowerCase();
By doing msg.content === prefix, you are checking if the whole content of the message is equal to that of cfg.prefix
if(msg.content.startsWith(`${prefix}8ball`) {
}
The answer was simple as i figured it out, i simply had to join the spaces
if (msg.content === `${prefix} ${args.join(" ")}`)
Its my code
var args = message.content.slice(prefix.length).trim().split(/ +/g);
var command = args.shift().toLowerCase()
if(command == "myinv"){
var invs = (await message.member.guild.fetchInvites().then(invites => invites.findAll("memberCount"))).values()
return message.channel.send(elo)
}
When i use command i got error like this:
(node:22680) DeprecationWarning: Collection#findAll: use Collection#filter instead
(node:22680) UnhandledPromiseRejectionWarning: Error: Value must be specified.
Can anyone help me?
Discord collection has no method .findAll, the one way to get count of invites uses, its
get serverinvites, then filter this collection, because discord not guaranteed property of invite.uses, then you can reduce it for get a summ.
var args = message.content.slice(prefix.length).trim().split(/ +/g);
var command = args.shift().toLowerCase()
if(command == "myinv"){
let invites = message.member.guild.fetchInvites().then(invites => {
let countInvites = invites.filter(invite => (invite.hasOwnProperty('uses'))).reduce((a, b) => {
a.uses + b.uses
}, 0)
message.channel.send(`Total server invite uses: **${countInvites}**`)
})
}
I don't know how to do this and I have been looking for answer but am unable to find it.
if message.content.startswith('^trivia autostart'):
await client.send_message(message.channel, "Game is starting!\n" +
str(player1) + "\n" + str(player2) + "\n" + str(player3) + "\n" +
str(player4) + "\n" + str(player5) + "\n" + str(player6) )
--
I have this code and i'm trying to make it so it when that code gets run that it calls my ^trivia play command without typing it in chat.
Is this possible?
The solution to that would be defining functions for each command you need to be called globally by your bot. Take the following example:
const Discord = require('discord.js');
const bot = new Discord.Client();
bot.on('error' => console.log);
bot.on('message', message => {
let prefix = '!';
let sender = message.author;
let msg = message.content;
let cont = msg.split(' ');
let args = cont.slice(1);
let cmd = msg.startsWith(prefix) ? cont[0].slice(prefix.length).toUpperCase() : undefined;
// Ping function
// can be: function pingCommand () {...}
let pingCommand = () => {
message.channel.send(`Pong!\nTime: ${bot.ping} ms`);
}
// Main command
if (cmd === 'PING') {
pingCommand();
}
// Calling command in another command
if (cmd === 'TEST') {
message.channel.send('Running a ping test on the bot');
pingCommand();
}
});
bot.login(token);
Hope you understand how it would work