javascriptdiscord.jsbotsrestart

Update discord.js bot without killing it


is there a way to update my discord bot's code without killing its process ?

Like if I change a single letter in a command code, do I have to restart the bot entirely to update it ? And what about non-command code ?

I'm restarting my bot to update/test the code a lot lately, and discord sent me a message saying my bot restarts too often.

Should i ignore the message, or do you have a solution for updating without restarting it?

Thanks.


Solution

  • For example, if a command handler is created like this,

    index.js

    const { Collection } = require("discord.js");
    
    client.slash = new Collection();
    const slashCommandFolders = fs.readdirSync("./slash");
    for (const folder of slashCommandFolders) {
      const commandFiles = fs
        .readdirSync(`./slash/${folder}`)
        .filter((file) => file.endsWith(".js"));
      for (const file of commandFiles) {
        const command = require(`./slash/${folder}/${file}`);
        client.slash.set(command.name, command);
      }
    }
    

    (command file is in slash/<category>/<command_name>.js)

    slash/general/ping.js

    const { CommandInteraction } = require("discord.js");
    
    module.exports = {
      name: "ping",
      /**
       *
       * @param {CommandInteraction} i
       */
      execute(i) {
        i.reply({ content: "Pong" });
      },
    };
    

    (The interactionCreate event needs to be handled properly, but we will skip that here)

    By creating such a reload command:

    src/admin/reload.js

    const {
      CommandInteraction,
      Client,
      CommandInteractionOptionResolver,
    } = require("discord.js");
    const fs = require("fs");
    
    module.exports = {
      name: "reload",
      /**
       *
       * @param {CommandInteraction} i
       * @param {Client} client
       * @param {CommandInteractionOptionResolver} options
       */
      async execute(i, client, options) {
        const commandName = options.getString("command").toLowerCase();
        const command =
          i.client.slash.get(commandName) ||
          i.client.slash.find(
            (cmd) => cmd.aliases && cmd.aliases.includes(commandName)
          );
    
        if (!command)
          return i.reply({ content: "No command found", ephemeral: true });
        const commandFolders = fs.readdirSync("./slash");
        const folderName = commandFolders.find((folder) =>
          fs.readdirSync(`./slash/${folder}`).includes(`${command.name}.js`)
        );
        delete require.cache[
          require.resolve(`../${folderName}/${command.name}.js`)
        ];
    
        try {
          const newCommand = require(`../${folderName}/${command.name}.js`);
          i.client.slash.set(newCommand.name, newCommand);
          i.reply({ content: "reloaded", ephemeral: true });
        } catch (error) {
          console.error(error);
          i.reply({ content: "reload failed", ephemeral: true });
        }
      },
    };
    

    We can apply changes without restarting bot. so dapper system