Articles on: Community Tutorials

Command and Event Handler (Node.js)

This tutorial is made by Fyrlex#2740

Command and Event Handler


Please make sure you have read Startup Configuration before reading this.

Command/Event Handlers are the best way for you to organize all commands and events that can be used in your bot.


The Handler-Handler


Here is the basic setup of your commands and their aliases as well as your events. Put this your index.js file below your client but above your login.
bot.aliases = new Discord.Collection(); // define aliases collection
bot.commands = new Discord.Collection(); // define commands collection
bot.events = new Discord.Collection(); // define events collection

require(`./handlers/command`)(bot);
require(`./handlers/event`)(bot);


Collections are fast ways to store temporary data that can be used at any time when your bot is online. The 3 collections above will be used later. You can create other collections for other features you might create. This is not for storing server data or user data, but collections can be used to load the data.

For each type of handler provided in the array, handler is the variable we created that will run for each item in the array. This will require the two files in the handler folder we are about to create!

Create Files and Folders


In your main directory, create a folder named handlers. Inside, create command.js and event.js

Then create a commands folder and an events folder in your main directory. We will add basic files later in this tutorial!

Command Handler


In the command.js file, use this adjustable code to load your commands into the commands collection.
const fs = require("fs"); // built in file system
module.exports = (bot) => { // define the function
  fs.readdir("./commands/", (err, files) => { // read commands directory
    if (err) console.log(err); // catch errors on startup
    let jsfiles = files.filter(file => file.split(".").pop() === "js"); // find the .js files
    if (jsfiles.length <= 0) { // basic check if there are no command files
      return console.log("There are no commands to load...");
    } else {
      jsfiles.forEach(file => { // if there are .js files
        let pull= require(`../commands/${file}`); // get command information
        console.log(`Command ${file} loaded!`); // log the command name
        bot.commands.set(pull.name, pull); // put the command name and options in command collection
        if (pull.aliases) // check if you set aliases
          pull.aliases.forEach(alias => bot.aliases.set(alias, pull.name)); // put aliases in the aliases collection
      });
    }
  });
};


Event.js


In the event.js file, use this adjustable code to load your events into the events collection.
const fs = require("fs"); // built in file system
module.exports = (bot) => {
  fs.readdir("./events/", (err, files) => {
    if (err) console.log(err); // catch errors on startup
    let jsfiles = files.filter(file => file.split(".").pop() === "js") // find the .js files
    if (jsfiles.length <= 0) { // basic check if there are no event files
      return console.log("There are no events to load...")
    }
    jsfiles.forEach(file => { // if there are .js files
      let pull = require(`../events/${file}`); // get event information
      console.log(`Event ${file} loaded!`); // log the event name
      bot.events.set(pull.name, pull); // put event settings into the events collection
    });
  });
};

Your handlers are now finished! Let's initiate the events in your index.js file and then create your ready event! Commands are initiated when creating the files in the commands folder!

Initiate Events



Your bot needs to run the event in your index.js file in order to connect it to your events folder. This is an example of how all the events you are using will look in the index.js file. Events and their paramaters can be found here. If an event has multiple paramaters, make sure to separate them with a comma! The following code can be above the handler-handler but below your bot

// when your bot encounters the event provided
bot.on("eventName", (paramaters) =>{
// get the event from the events collection
  let event = bot.events.get("eventName");
  
  // run your bot and the paramaters above
  if (event) event.run(bot, paramaters);
});

Required event paramaters can be found here. Each event has it's own paramaters that must be given in the event initiated.

In the event.run() section, you can also provide your own additional paramters/functions.

Here are two very important events to initiate in your index.js file.
bot.on("message", message => { // message is the paramter for the messge event
    let event = bot.events.get("message");
    if (event) event.run(bot, message) // run your bot and message to use in the file
});
bot.on("ready", () => { // there are no paramaters for the ready event
    let event = bot.events.get("ready");
    if (event) event.run(bot) // run your bot/client so you can use it in the file
});


Make sure to run your client in every event you use!

Basic Commands & Events Setup



Here is a little rundown of what all your event and command files should look like based on what we have already coded. Notice the similarities between the two event files below, everything outside the run function is required! Make sure you put in the right names and paramaters.

Prefix (for single prefix bots)


If you do not have a config.json file already, create one in your main directory where your main bot file (index.js or bot.js) should also be. Just below where you define your Discord.Client(), type the following:
bot.config = require("./config.json")

This will allow you to get every key inside your config.json by typing bot.config.KEY

Every JSON file must contain an outer set of [] or {} and we will be using {}.

Provide the following lines of code in the file you just created.
{
  "prefix": "YOUR PREFIX HERE"
}

When you use bot.config.prefix you will now get your prefix automatically in your code!

Message.js


Before you can actually use commands, you need to run your message event. Every time a message is sent in a server with your bot, this event will trigger. We will make your bot ignore anything that doesn't start with its prefix. Go back to both handlers above to understand how your code connects! This will help you create future commands/features!

module.exports = {
  name: "message",
  run: async (bot, message) => { // use the paramaters from the event
    
    // highly advised, prevents other bots from using your bot 
    if (message.author.bot) return;
    
    // all other code recommended to go here
	
	// get your prefix
	let prefix = bot.config.prefix;
	
	// if the user does not start their message with the prefix, ignore
	if (!message.content.startsWith(prefix)) return;
	
	// get all of the message except the prefix and split the users message by spaces " "
    let args = message.content.slice(prefix.length).trim().split(' ');
    
    // get the command they use
    let cmd = args.shift().toLowerCase(); // get the first word used
	
	// create an unassigned variable
	let command;
	
	// if the command provided exists in the collection
    if (bot.commands.has(cmd)) {
    
      // command is now the information of the command provided
      command = bot.commands.get(cmd);

      // if the command provided is an alias
    } else if (bot.aliases.has(cmd)) { 
    
    // command is the information of the command received from the aliases collection
    command = bot.commands.get(bot.aliases.get(cmd));
    
    // if a command isn't provided, ignore
    } else return;

    // allow you to use your client, the message and the arguments in the command files
    command.run(bot, message, args);

	// say in your console what command was used
    console.log(`Command Used: ${command.name}`)
  }
}


Ready.js


A ready event is triggered once your bot goes online, this is where you can load or set a variety of things. For now, we will just set the presence of your bot.

module.exports = {
  name: "ready",
  run: async (bot) => { // use the paramaters from the event
    
    // let yourself know when your ready event is loading
    console.log("Ready event loading...");
   
    // presence example
    // presence settings
    let mypresence= {
      activity: {
        name: 'with Something.Host'
      },
      status: 'online'
    }
    // set the presence
    bot.user.setPresence(mypresence)
      .then(console.log)
      .catch(console.error)
    
    // let yourself know that the ready event worked
	console.log("Ready event success!")
  }
}

Your bot is now online! Let's create your first command.

Command Setup


Your first command will be using the same code you ran in your message.js file. Here is an example of what your command files will start with given what we created before.

const Discord = require("discord.js");
module.exports = {
  aliases: [],
  description: "", // used later
  name: "",
  run: async (bot,message,args) => {
    // command code
  }
}


Ping Command


Using the template above, let's create a ping-pong command. Create a file in your commands folder. It is best to have the file name the same as the command name.
const Discord = require("discord.js");
module.exports = { // the command information from the commands collection
  aliases: ["p"], // if you type your prefix then "p", this command will run
  name: "ping", // pull.name in command.js and in message.js
  run: async (bot,message,args) => { // command.run() from message.js
	  message.reply("pong!") // this will send a message tagging the author a comma, then the message
  }
}

Updated on: 13/12/2020

Was this article helpful?

Share your feedback

Cancel

Thank you!