how to add aliases to a command handler in discord.js - javascript

I have found on other stack overflow questions that to add aliases you just have to add
const command = client.commands.get(commandName) || client.commands.find(cmd => cmd.aliases && cmd.aliases.includes(commandName));
but this doesn't work. What I don't understand is what cmd is because it is not defined anywhere else in my code although it is passed in through the arrow function anyway. When using this I can still use the commands but when I use the aliases nothing happens, no message or error in the console. Could anyone assist me on this, Thanks for any help. Here is my code for the command handler:
client.on('messageCreate', message => {
if (message.author.bot) return;
if (!message.content.startsWith(process.env.PREFIX)) return;
const args = message.content.slice(process.env.PREFIX.length).trim().split(/ +/);
const commandName = args.shift().toLowerCase();
const command = client.commands.get(commandName) || client.commands.find(cmd => cmd.aliases && cmd.aliases.includes(commandName));
if (!client.commands.has(commandName)) return;
if (message.channel.name == 'general') return message.reply('smh no bot commands in general :raised_hand:');
if (!message.guild.me.permissions.has('SEND_MESSAGES')) return message.member.send(`I need the 'SEND_MESSAGES' permission to be able to reply to commands in the server: ${message.guild.name}`);
try {
command.execute(message, args, distube);
} catch(error) {
console.error(error);
message.reply('Uh oh! It looks like you have encountered a glitch up in the system, please try again later! || <#498615291908194324> fix yo dead bot ||')
}
});
And the command file:
name: 'ping',
description: 'Ping Command',
aliases: ['pg'],
execute(message, args) {
let ping = new Date().getTime() - message.createdTimestamp
message.reply(`pong (${ping}ms)`);
}

This line is the problem
if (!client.commands.has(commandName)) return;
You map the collection in a <string, Object> format but the string is the command name, not the alias. The better way is replacing the above line of code with this:
if (!command) return;
This will return early if command is falsey (it was not found) but it will work with aliases.

Related

I'm getting error while making an alias system in discord.js

I was making an alias system for my discord bot, and I wanted to say: "if the user entered the wrong command name or alias then return: invalid command/alias", but I'm getting an error:
C:\Users\Pooyan\Desktop\PDM Bot Main\events\guild\message.js:16
if(!cmd || client.commands.find(a => !a.aliases && !a.aliases.includes(cmd))) return message.channel.send('Invalid command');
^
TypeError: Cannot read properties of undefined (reading 'includes')
at C:\Users\Pooyan\Desktop\PDM Bot Main\events\guild\message.js:16:83
My code:
module.exports = async (message, client, Discord) => {
const prefix = process.env.PREFIX;
if(!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).split(/ +/);
const cmd = args.shift().toLowerCase();
const command = client.commands.get(cmd) ||
client.commands.find(a => a.aliases && a.aliases.includes(cmd));
if(!cmd || client.commands.find(a => !a.aliases && !a.aliases.includes(cmd))) return message.channel.send('Invalid command');
}
I'm using discord.js v13 and Node.js v16.14.2
I found the solution myself,
All I needed to do was:
if(!command) return message.channel.send('Invalid Command/alias');
after those two lines,
It means if command name was not correct, or if the alias was not correct, return "Invalid Command/alias"
Remove the first ! in your find method, it will fix the error

TypeError: command.execute is not a function when catching an error. Also, cooldown doesn't work. On Discord.js

I've been working on a Discord bot for a while and have implemented a cooldown command for a while too. It never works, and today i decided that i will try to fix it.
At first, it kept sending me an error message saying TypeError: command.execute is not a function and an error message on the channel, so i just removed catch (err) so it wont send that annoying message. But of course, doing that is perhaps the equivalent of removing a scratched limb.
Now that more people uses my bot, i was trying to rework on the cooldown feature, which is located on ../events/guild/message.js and it goes like this:
require('dotenv').config();
const Discord = require('discord.js');
const cooldowns = new Map();
module.exports = async (Discord, client, message) => {
if (message.author.bot) return;
const prefix = message.content.includes("nabe ") ? "nabe " : "n!"
if (message.content.indexOf(prefix) !== 0) return;
const args = message.content.slice(prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
const cmd = client.commands.get(command) || client.commands.find(a => a.aliases && a.aliases.includes(cmd));
if(message.channel.type === "dm")return message.channel.send("you can't use commands on dm")
if(cmd){
cmd.execute(client, message, args, Discord);
}else return
if(!cooldowns.has(command.name)){
cooldowns.set(command.name, new Discord.Collection());
}
const current_time = Date.now();
const time_stamps = cooldowns.get(command.name);
const cooldown_amount = (command.cooldown) * 1000;
if(time_stamps.has(message.author.id)){
const expiration_time = time_stamps.get(message.author.id) + cooldown_amount;
if(current_time < expiration_time){
const time_left = (expiration_time - current_time) / 1000;
return message.reply(`wait **${time_left.toFixed(1)}** more seconds to do ${command.name} again.`).then(msg => { msg.delete({ timeout: 7000 }) });
}
}
time_stamps.set(message.author.id, current_time);
setTimeout(() => time_stamps.delete(message.author.id), cooldown_amount);
try{
command.execute(message, args, cmd, client, Discord);
} catch (err){
message.reply("There was an error trying to execute this command.");
console.log(err);
}
}
How it was implemented on each command files:
module.exports = {
info: {
name: "command name",
description: "command description",
cooldown: 30,
},
async execute(client, message, args, Discord) {
/*code here*/
}
By the way, i got most of this code from CodeLyon on youtube, and here's the sourcebin.
Everytime i executed a command it will return the TypeError: command.execute is not a function error and an error message on the channel. I am aware that some people said that command.execute does not exist, but it works on the tutorial video, and i don't know any alternatives. And it probably won't even fix the cooldown anyway.
I will definitely really appreciate it if anybody can find a solution.
NodeJS 16.13.0, NPM 8.1.0, DiscordJS 12.5.3, Heroku server.
I am aware that some people said that command.execute does not exist
And they would be right. As you can see in your defined command:
module.exports = {
info: {
name: "command name",
description: "command description",
cooldown: 30,
},
You did not appear to specify an execute function in the command body. If you want to run the command, you need to do that:
module.exports = {
info: {
name: "command name",
description: "command description",
cooldown: 30,
execute: (client, message, args, Discord) => {
// command logic goes here
}
},
P.S I believe the sourcebin tutorial that you linked also included an execute function:

discord bot not processing the command

I was adding some new commands to my discord v12 bot. But it's not responding to the code I typed. Any help is appreciated.
This section is inside index.js
client.admins = new discord.Collection();
const admins = fs.readdirSync('./custom/admin').filter(file => file.endsWith('.js'));
for (const file of admins) {
const admin = require(`./custom/admin/${file}`);
client.admins.set(admin.name.toLowerCase(), admin);
};
This is the code to process the above lines
if (message.author.bot || message.channel.type === 'dm') return;
const prefix = client.config.discord.prefix;
if (message.content.indexOf(prefix) !== 0) return;
const args = message.content.slice(prefix.length).trim().split(/ +/g);
const admin = args.shift().toLowerCase();
const adm = client.admins.get(admin) || client.admins.find(adm => adm.aliases && adm.aliases.includes(admin));
if (adm) adm.execute(client, message, args);
And the function which I am trying the bot to do is named delete.js
module.exports = {
name: 'snap' ,
aliases: [],
category: 'admin',
utilisation: '{prefix}snap [number]',
execute(message, args) {
if(isNaN(args)) return message.reply("Bruh,Specify how much message should I delete")
if(args>99) return message.reply("You ain't making me do that much work boi")
if (message.member.hasPermission('ADMINISTRATOR') ){
const {MessageAttachment} = require('discord.js');
const snaping = new MessageAttachment('./snap.gif')
message.channel.send(snaping)
setTimeout(snapCommand , 9000 ,args, message)
}
else
{
message.channel.send("-_- you are not an admin,Then why are you trying to use admin commands");
}
function snapCommand(args, message){
var del= args ;
del = parseInt(del , 10)
message.channel.bulkDelete(del+2);
}
}
}
when I launch the bot it shows no error msg, So that's a good sign I think, but when I use !snap 5
'!' which is my prefix. The bot does nothing. No error in the console also. Does anyone have any idea to solve this?
Never mind, I fixed it by adding client to the delete.js code
execute(client, message, args) {
if(isNaN(args)) return message.reply("Bruh,Specify how much message should I delete")
if(args>99) return message.reply("You ain't making me do that much work boi")

i have an error titled: "TypeError: Cannot read property 'execute' of undefined" and cannot fix it

I am trying to make a discord bot use an advanced command handler and it isn't working.
Error Message:
at Client.<anonymous> (C:\Users\bryce\OneDrive\Desktop\bot\main.js:76:39)
at Client.emit (events.js:315:20)
at MessageCreateAction.handle (C:\Users\bryce\OneDrive\Desktop\bot\node_modules\discord.js\src\client\actions\MessageCreate.js:31:14)
at Object.module.exports [as MESSAGE_CREATE] (C:\Users\bryce\OneDrive\Desktop\bot\node_modules\discord.js\src\client\websocket\handlers\MESSAGE_CREATE.js:4:32)
at WebSocketManager.handlePacket (C:\Users\bryce\OneDrive\Desktop\bot\node_modules\discord.js\src\client\websocket\WebSocketManager.js:384:31)
at WebSocketShard.onPacket (C:\Users\bryce\OneDrive\Desktop\bot\node_modules\discord.js\src\client\websocket\WebSocketShard.js:444:22)
at WebSocketShard.onMessage (C:\Users\bryce\OneDrive\Desktop\bot\node_modules\discord.js\src\client\websocket\WebSocketShard.js:301:10)
at WebSocket.onMessage (C:\Users\bryce\OneDrive\Desktop\bot\node_modules\ws\lib\event-target.js:132:16)
at WebSocket.emit (events.js:315:20)
main.js
const Discord = require('discord.js');
const client = new Discord.Client();
const prefix = '='
const fs = require('fs');
// create the collection
client.commands = new Discord.Collection();
// get an array of every file in the commands folder
const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js'));
// iterate a function through every file
for (file of commandFiles) {
const command = require(`./commands/${file}`);
console.log(file)
// map the command to the collection with the key as the command name,
// and the value as the whole exported object
client.commands.set(command.name, command);
};
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 === 'twitch'){
message.channel.send('https://www.twitch.tv/gamergirlspeed');
}else if (command == 'youtube'){
message.channel.send('https://www.youtube.com/channel/UCHN61ta8sZ-EkJ6JvlGRkng');
}else if (command == 'tiktok'){
message.channel.send('https://www.tiktok.com/#gamergirlspeed?lang=en ')
}else if (command == 'help'){
message.channel.send('**| =twitch**\n**| =youtube**\n**| =tiktok**\n**| =epic**\n**| =mods**\n**| =version**\n**| =author**\n**| =purge (broken)**\n**| =twitter**\n**| =switch**\n**| =rule1**\n**| =rule2**\n**| =rule3**\n**| =rule4**\n**| =rule5**\n**| =rule6**\n**| =rule7**\n**| =rule8**\n**| =rule9**\n**| =botcommands**')
}else if (command == 'epic'){
message.channel.send("Speed's Epic account is: Speed_Ster06")
}else if (command == 'mods'){
message.channel.send("Speed_Ster06's current mods are: FyreFoxe, RAPHBOSS")
}else if (command == 'version'){
message.channel.send("FyreFoxe's SpeedForce Bot is in version 1.7")
}else if (command == 'author'){
message.channel.send('SpeedForce Is Created by Bravmi#6740')
}else if (command == 'twitter'){
message.channel.send('https://twitter.com/GamerGirlSpeed1 ')
}else if (command == 'playstation'){
message.command.send("Speed's Playstation Account is: Speed_Ster06")
}else if (command == 'switch'){
message.channel.send("Speed's Switch Account is: SpeedSter6")
}else if (command === 'purge'){
client.commands.get('purge').execute(message,args);
}else if (command == 'rule1'){
message.channel.send('Do not spam')
}else if (command == 'rule2'){
message.channel.send("Don't be mean to others, It's just not nice.")
}else if (command == 'rule3'){
message.channel.send("No NSFW, It's just, we don't do that here.")
}else if (command == 'rule4'){
message.channel.send("No raiding, I think it's pretty clear what the punishment would be if you did.")
}else if (command == 'rule5'){
message.channel.send(" Don't boycott the discord/minecraft server.")
}else if (command == 'rule6'){
message.channel.send("Don't beg for roles.")
}else if (command == 'rule7'){
message.channel.send("Don’t advertise unless in the correct channel.")
}else if (command == 'rule8'){
message.channel.send("Don't put clips in the clips channel that aren't from my stream.")
}else if (command == 'rule9'){
message.channel.send("Rules are based upon logic or common sense. Don't do things that seem bad, only because it's 'Not a rule'.")
}else if (command == 'botcommands'){
message.channel.send('Bot Commands:\n----------------------------------------------------------------------------------------------------------------\n**1.** “!rank” shows you your rank level\n**2.** “!levels” shows you a leader board of all the other people’s levels\n**3.** “!help” helps find out information about commands\n**4.** “!links” shows the links to my YouTube and Twitch channels\n**5.** “!d bump” help show the discord server to other people\n**6.** “=help” Shows you all the cmds you can do with our custom SpeedForce Bot made by FyreFoxe\n----------------------------------------------------------------------------------------------------------------')
}else if (command === 'warn'){
client.commands.get('warn.js').execute(message, args);
}
//else if (command === 'kick'){
//client.commands.get('kick').execute(message, args)
//}else if (command === 'ban'){
//client.commands.get('ban').execute(message, args)
//}
});
//Copyright LightSide Development, 2021
client.once('ready', () => {
console.log('Online!')
setInterval(() => {
targetGuild = client.guilds.cache.get('782068409646448640')
if(targetGuild) {
client.user.setActivity({ name: targetGuild.memberCount + ' SpeedSters!', type: 'WATCHING' }, { name: 'with commands!', type: 'PLAYING' }, { name: 'You...', type: 'WATCHING' })
.then(console.log)
.catch(console.error);
}
}, 1000 * 60 * 1);
});
client.login('expunged')
warn.js
const Discord = reqire("discord.js");
const fs = require("fs");
const ms = require("ms");
let warns = JSON.parse(fs.readFileSync("./warnings.json", "utf8"));
module.exports.run = async (bot, message, args) => {
//=warn #name <reason>
if(!message.member.hasPermission("MANAGE_MEMBERS")) return message.reply("You don't have permission!");
let wUser = message.guild.member(message.mentions.users.first()) || message.guild.members.get(args[0])
if(!wUser) return message.reply("The user specified does not exist!")
if(wUser.hasPermission("MANAGE_MESSAGES")) return message.reply("You cannot warn them!");
let reason = args.join(" ").slice(22);
if(!warns[wUser.id]) warns[wUser.id] = {
warns: 0
};
warns[wUser.id].warns++;
fs.writeFile("./warnings.json", JSON.stringify(warns), (error) => {
if (err) console.log(error);
});
let warnEmbed = new Discord.RichEmbed()
.setDescription("Warns")
.setAuthor(message.author.username)
.setColor("#fc6400")
.addField("Warned User", `<#${wUser.tag}>`)
.addField("Warned in", message.channel)
.addField("Number of Warnings", warns[wUser.id].warns)
.addField("Reason", reason)
let warnchannel = message.guild.channels.find(`name`, "warnings");
if(!warnchannel) return message.reply("The Logging channel has been deleted or renamed, contact Bravmi#6740");
warnchannel.send(warnEmbed);
if(warns[wUser.id].warns == 5){
message.guild.member(wUser).ban(reason);
warnchannel.send(`${wUser.tag} has been banned for ${reason}`)
}
}
module.exports.help = {
name: "warn"
}
the error occurs when i use the warn command, it crashes the bot and gives me the error message and i don't know what to do.
i have tried looking at it with some friends and they don't know what to do either, is there any way to fix it?
The error "Cannot read property 'execute' of undefined" means exactly what it says.
In your case, you are trying to call the function "execute" on an object that does not exist.
The error is even giving you the line number that it is occurring "(C:\Users\bryce\OneDrive\Desktop\bot\main.js:76:39)".
Without line numbers in the code you posted above, I can't be sure, but it looks to me like the offending code is.
client.commands.get('warn.js').execute(message, args);
Which means client.commands.get('warn.js') is not returning an object. ie. calling the function client.commands.get('warn.js') is returning undefined.
I dare say, you may want to try client.commands.get('warn').execute(message, args)
When you add your files to the collection at the start of your file you use client.commands.set(command.name, command);. This sets the key in the collection to the name of the command.
However, in your command file you use the following code module.exports.help = { name: "warn" } and there is no definition of what should be module.exports.name.
I would suggest changing the module.exports.help to module.exports and then remove the .js from all lines where you have client.commands.get('...')

Making my first discord bot, unable to add anything besides basic commands

I'm using discord.js as well as javascript to code. I'm just trying to work out this test bot I have made and despite all the step-by-step guides that I have pretty much followed to a T, I am only able to get the bot to work with basic "ping pong" like commands. Every time I try to add anything more or less, the bot completely stops working.
Here is an example of the code I have so far. It's a little 'gaggy' some friends and I, as I said, are just trying to work out how to make the test bot first. Maybe it's just completely going over my head and I'm just not doing it the correct way. Either way, some assistance would be helpful. Thanks.
/*
A ping pong bot, whenever you send "ping", it replies "pong".
*/
// Import the discord.js module
const Discord = require('discord.js');
// Create an instance of a Discord client
// This is sometimes called 'bot', but 'client' is prefered
const client = new Discord.Client();
const token = 'MY_BOT_TOKEN';
client.on('ready', () => {
console.log('I am ready!');
});
// Create an event listener for messages
client.on('message', message => {
// If the message is "ping"
if (message.content === 'silas!ping') {
// Send "pong" in the same channel
message.channel.send('pong');
}
});
// Log our bot in
client.login(token);
What I am also trying to do is add a "SAY" command, this is what I have been using, and once I add it, it completely breaks the bot. As well as adding in a prefix.
client.on('message', message => {
if (message.channel.type != 'text' || message.author.bot || !message.startsWith('*'))
return;
if (message.content === '*ping') {
message.channel.send('pong');
}
});
client.on('message', message => {
if (message.channel.type != 'text' || message.author.bot || !message.startsWith('*'))
return;
if (message.content === '*ping') {
message.channel.send('pong');
}
else if (message.content === '*say') {
message.channel.send(message.content);
}
});
Im not sure if this means anything to get help, but this is the error i recieve when trying to add the following code given to me for help
if (!message.content.startsWith(prefix)) return;
^
ReferenceError: message is not defined
at Object. (C:\Users\my location files\index.js:23:1)
[90m at Module._compile (internal/modules/cjs/loader.js:1137:30)[39m
[90m at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)[39m
[90m at Module.load (internal/modules/cjs/loader.js:985:32)[39m
[90m at Function.Module._load (internal/modules/cjs/loader.js:878:14)[39m
[90m at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)[39m
[90m at internal/main/run_main_module.js:17:47[39m
Another, little more advanced, way would be to seperate the prefix and the command.
This allows you to define a prefix without changing all .startsWith() conditions.
With Array.split() you can seperate each following word if they have whitespaces between each other.
This would end up like this:
let prefix = "*";
// Prevents any unnecessary condition checks if the message does not contain the prefix
if (!message.content.startsWith(prefix)) return;
const args = message.content.toLowerCase().split(' ');
let command = args[0];
command = command.slice(prefix.length);
if(command === "say"){
// do whatevery you want :)
}
After it was checked that the message starts with the prefix, you split each word and then take the first one. With slicing the prefix out, you end up with only having the plain command. This allows an even better approach for checking commands since the condition doesn't include the prefix anymore.
Everything after args[0] would be additional arguments you can use for any case you want.
you could make a config.json.
inside your config.json
{
"TOKEN": "",
"PREFIX": "",
}
and then require on you bot main file and also define the client.commands and client.aliases
const config = require("./config.json");
client.commands = new Discord.Collection();
client.aliases = new Discord.Collection();
on your message event you wanna add a command handler
client.on("message", async(message) => {
if (message.author.bot) return;
if (!message.guild) return;
if (!message.content.startsWith(config.PREFIX)) return;
if (!message.member) message.member = await message.guild.fetchMember(message);
const args = message.content.slice(config.PREFIX.length).trim().split(/ +/g);
const cmd = args.shift().toLowerCase();
if (cmd.length === 0) return;
let command = client.commands.get(cmd);
if (!command) command = client.commands.get(client.aliases.get(cmd));
try {
if (command)
command.run(client, message, args);
} catch(error) {
console.log(error)
}
})
after that, add a new folder call handlers and inside the handlers folder make a new file call command.js
const { readdirSync } = require("fs");
const ascii = require("ascii-table");
let table = new ascii("Command");
table.setHeading("Command", "Load Status");
module.exports = (client) => {
readdirSync("./commands/").forEach(dir => {
const commands = readdirSync(`./commands/${dir}/`).filter(file => file.endsWith(".js"));
for (let file of commands) {
let pull = require(`../commands/${dir}/${file}`);
if (pull.name) {
client.commands.set(pull.name, pull);
table.addRow(file, '✅');
} else {
table.addRow(file, `❌ -> missing a help.name, or help.name is not a string.`);
continue;
}
if (pull.aliases && Array.isArray(pull.aliases)) pull.aliases.forEach(alias => client.aliases.set(alias, pull.name));
}
});
console.log(table.toString());
}
and then require on the bot main file
["command"].forEach(handler => {
require(`./handlers/${handler}`)(client);
});
make a new folder call commands inside add new folder command category such as info
simple ping command
module.exports = {
name: "ping",
aliases: ["pong"],
description: "Check Bot Ping",
usage: "",
run: async(client, message, args) => {
messsage.channel.send("PONG")
},
};
hope this guide is helpful :)

Categories

Resources