Skip to content

Instantly share code, notes, and snippets.

@simonmeusel
Last active June 23, 2023 09:44
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save simonmeusel/1de7166288b12c04518c59158a85f5ef to your computer and use it in GitHub Desktop.
Save simonmeusel/1de7166288b12c04518c59158a85f5ef to your computer and use it in GitHub Desktop.
Start minecraft server via discord bot
var spawn = require('child_process').spawn;
var discord = require("discord.js");
var bot = new discord.Client();
var mcserver;
// The start.bat has to include a 'cd "C:/Users/_____/Desktop/Server/"' command (See start.bat for more details)
var MC_SERVER_START_SCRIPT = "C:/Users/_____/Desktop/Server/start.bat";
bot.on("message", function(message){
if (message.content == "start") {
// Only start if not running
if (mcserver == null) {
bot.sendMessage(message, "Starting server...");
// Start the server
mcserver = spawn(MC_SERVER_START_SCRIPT);
mcserver.stdout.on('data', (data) => {
console.log("stdout: " + data);
// Not everything is send (because i think there is a send limit per time)
// bot.sendMessage(message, "stdout: " + data);
});
mcserver.stderr.on('data', (data) => {
console.log("stderr: " + data);
bot.sendMessage(message, "stdout: " + data);
});
mcserver.on('close', (code) => {
console.log("child process exited with code " + code);
bot.sendMessage(message, "child process exited with code " + code);
});
}
} else if (message.content == "stop") {
// Only stop if running
if (message.content == "start") {
bot.sendMessage(message, "Stopping server...");
// Stop the server
mcserver.kill();
mcserver = null;
}
}
});
bot.login("email", "pass")
cd C:\Users\_____\Desktop\Server
java -jar spigot.jar
@MasonTRB
Copy link

how does this work?

@Mu7aMNaD
Copy link

Mu7aMNaD commented Jul 3, 2020

can you update this.

@Mu7aMNaD
Copy link

Mu7aMNaD commented Jul 3, 2020

can you update this.

@Whitelisted1
Copy link

I tried to go through this code and update it to the most recent version, I am yet to complete updating it, also I am using a mac, so if you're using windows you may get different results. here is the (so far) updated file:

var spawn = require('child_process').spawn;
var discord = require("discord.js");

var bot = new discord.Client();
var mcserver;

// The start.bat has to include a 'cd "C:/Users/_____/Desktop/Server/"' command (See start.bat for more details)
var MC_SERVER_START_SCRIPT = "{FOLDER PATH}";

bot.on("message", function(message){
if (message.content == "start") {

// Only start if not running
if (mcserver == null) {
    message.channel.send( "Starting server... (this may take a while)");

  // Start the server
  mcserver = spawn(MC_SERVER_START_SCRIPT);

  mcserver.stdout.on('data', (data) => {
    console.log("stdout: " + data);
    // Not everything is send (because i think there is a send limit per time)
    // bot.sendMessage(message, "stdout: " + data);
  });

  mcserver.stderr.on('data', (data) => {
    console.log("stderr: " + data);
      message.channel.send( "stdout: " + data);
  });

  mcserver.on('close', (code) => {
    console.log("child process exited with code " + code);
      message.channel.send( "child process exited with code " + code);
  });

}

} else if (message.content == "stop") {

// Only stop if running
if (message.content == "start") {
    message.channel.send( "Stopping server...");

  // Stop the server
  mcserver.kill();

  mcserver = null;
}

}
});

bot.login("{BOT TOKEN}")

//Make sure you have a seperate file starting the server if using a mac (unsure about windows and ubuntu)
//seperate file could be a "start.command" file that contains
//#!/bin/bash
//cd "$(dirname "$0")"
//exec java -Xmx2G -Xms2G -jar server.jar nogui

@oli-schatzberger
Copy link

My stopserver part doesn't work because I think the content from my message can't be stop and start at the same time. Also .kill() is undefined. Anybody know this issue?

@luminpro
Copy link

luminpro commented Feb 8, 2021

Huge thanks to @simonmeusel for providing this bot code, and @DaCoolKitty for some great improvement ideas.

I made a few adjustments as well:

  • Got it working on the latest discord.js
  • Fixed the kill process
  • Added poor man's rate limiting

Just contributing back since I was able to quickly get my code up and running thanks to the original reference!

var kill  = require('tree-kill');
var spawn = require('child_process').spawn;
var discord = require("discord.js");

var bot = new discord.Client();
var mcserver;
var lastMsgTime = 0;

// The start.bat has to include a 'cd "C:/Users/_____/Desktop/Server/"' command (See start.bat for more details)
var MC_SERVER_START_SCRIPT = "C:/Users/_____/Desktop/Server/server.bat";

bot.on("message", function(message){
  var msgContent = message.content.toLowerCase();

  if (msgContent == "start") {

    // Only start if not running
    if (mcserver == null) {
      // Prevent spamming command messages - only allow one command every 60 sec
      if ((bot.uptime - lastMsgTime) < 60000)
      {
        console.log("Potential command spamming by " + message.author.username);
        message.channel.send("Last command was less than 60 seconds ago. Try again in a minute, " + message.author.username + ".");
      }
      else
      {
        lastMsgTime = bot.uptime;

        message.channel.send("Starting Minecraft server. This will take a minute or so.\nJoin at {SERVER_IP}");

        // Start the server
        mcserver = spawn(MC_SERVER_START_SCRIPT);

        mcserver.stdout.on('data', (data) => {
          console.log("stdout: " + data);
          // Not everything is send (because i think there is a send limit per time)
          // message.channel.send("stdout: " + data);
        });

        mcserver.stderr.on('data', (data) => {
          console.log("stderr: " + data);
          message.channel.send("Error starting Minecraft server. (Code: " + data + ")\nPlease try again or contact the server owner.");

          // Stop the server
          if (mcserver != null) {
            kill(mcserver.pid);
          }

          mcserver = null;
        });

        mcserver.on('close', (code) => {
          console.log("child process exited with code " + code);
          message.channel.send("Minecraft server has been closed. (Code: " + code + ")");

          // Stop the server
          if (mcserver != null) {
            kill(mcserver.pid);
          }

          mcserver = null;
        });
      }
    }
    else
    {
      message.channel.send("Minecraft server is already running.\nJoin at {SERVER_IP}");
    }

  } else if (msgContent == "stop") {

    // Prevent spamming command messages - only allow one command every 60 sec
    if ((bot.uptime - lastMsgTime) < 60000)
    {
      console.log("Potential command spamming by " + message.author.username);
      message.channel.send("Last command was less than 60 seconds ago. Try again in a minute, " + message.author.username + ".");
    }
    else
    {
      lastMsgTime = bot.uptime;

      // Only stop if running
      if (mcserver != null) {
        message.channel.send("Stopping Minecraft server...");

        // Stop the server
        kill(mcserver.pid);

        mcserver = null;
      }
    }
  }
});

bot.login("{BOT_TOKEN");

@JonnyKartofa
Copy link

JonnyKartofa commented Feb 16, 2021

i tried running the code and i got this when i try to start the server
events.js:292
throw er; // Unhandled 'error' event
^

Error: spawn C:UsersJon7nDesktopserver.bat ENOENT
at Process.ChildProcess._handle.onexit (internal/child_process.js:269:19)
at onErrorNT (internal/child_process.js:465:16)
at processTicksAndRejections (internal/process/task_queues.js:80:21)
Emitted 'error' event on ChildProcess instance at:
at Process.ChildProcess._handle.onexit (internal/child_process.js:275:12)
at onErrorNT (internal/child_process.js:465:16)
at processTicksAndRejections (internal/process/task_queues.js:80:21) {
errno: -4058,
code: 'ENOENT',
syscall: 'spawn C:UsersJon7nDesktopserver.bat',
path: 'C:UsersJon7nDesktopserver.bat',
spawnargs: []
}

any ideas as of why this is happening (im new to js)

@Whitelisted1
Copy link

Whitelisted1 commented Feb 24, 2021

ENOENT means that the file that you inputted could not be found or the process does not have access to it, try instead putting the server's file path directly into the "var MC_SERVER_START_SCRIPT = "C:/Users/_____/Desktop/Server/server.bat";" script instead of putting the start.bat file into there, or maybe you have another code process starting the server instead of directly putting the server's path into the "MC_SERVER_START_SCRIPT" variable, like if you had (for mac) start.command, which would launch the process, or for windows I'm pretty sure it would be start.bat (sorry if this is unclear, I'm free to be asked for more questions, I am also not very experienced with programing, so I may not be of much help) @JonnyKartofa

Edit: the next message may help more than this one

@Whitelisted1
Copy link

Whitelisted1 commented Feb 24, 2021

@JonnyKartofa I have looked into the error code more and from what it looks like you didn't put the correct path in the code (or it may just be the error message), the path you would want would be C:Users/Jon7n/Desktop/server.bat you may also want to put the server into a separate file, instead of putting it on the desktop

@ryano022
Copy link

ryano022 commented Feb 26, 2021

@DaCoolKitty
Quick question, will this only work with Minecraft? I am running a Valheim server and was hoping to use this to run that server. I have a working Start.bat (server launches when Start.bat is ran manually, however I still get the following error is VSCode

`node:events:355
throw er; // Unhandled 'error' event
^

Error: spawn C:/Users//Desktop/Server/server.bat ENOENT
at Process.ChildProcess._handle.onexit (node:internal/child_process:282:19)
at onErrorNT (node:internal/child_process:480:16)
Emitted 'error' event on ChildProcess instance at:
at Process.ChildProcess._handle.onexit (node:internal/child_process:288:12)
at onErrorNT (node:internal/child_process:480:16)
at processTicksAndRejections (node:internal/process/task_queues:81:21) {
errno: -4058,
code: 'ENOENT',
syscall: 'spawn C:/Users/
/Desktop/Server/server.bat',
path: 'C:/Users/_____/Desktop/Server/server.bat',
spawnargs: []
}
PS C:\Users\ryang\Desktop\Server Bot> node index.js
node:events:355
throw er; // Unhandled 'error' event
^

Error: spawn C:/Users//Desktop/Server/server.bat ENOENT
at Process.ChildProcess._handle.onexit (node:internal/child_process:282:19)
at onErrorNT (node:internal/child_process:480:16)
at processTicksAndRejections (node:internal/process/task_queues:81:21)
Emitted 'error' event on ChildProcess instance at:
at Process.ChildProcess._handle.onexit (node:internal/child_process:288:12)
at onErrorNT (node:internal/child_process:480:16)
at processTicksAndRejections (node:internal/process/task_queues:81:21) {
errno: -4058,
code: 'ENOENT',
syscall: 'spawn C:/Users/
/Desktop/Server/server.bat',
path: 'C:/Users/_____/Desktop/Server/server.bat',
spawnargs: []`

@ryano022
Copy link

Disregard last, My Dumb self never saved my edits so I was running the original file :) works like a charm now

@JonnyKartofa
Copy link

i really dont know what im doing wrong i get the same error here is the code
var MC_SERVER_START_SCRIPT = "C:Users/Jon7n/Desktop/server.bat";

and the error>>

events.js:292
throw er; // Unhandled 'error' event
^

Error: spawn C:Users/Jon7n/Desktop/server.bat ENOENT
at Process.ChildProcess._handle.onexit (internal/child_process.js:269:19)
at onErrorNT (internal/child_process.js:465:16)
at processTicksAndRejections (internal/process/task_queues.js:80:21)
Emitted 'error' event on ChildProcess instance at:
at Process.ChildProcess._handle.onexit (internal/child_process.js:275:12)
at onErrorNT (internal/child_process.js:465:16)
at processTicksAndRejections (internal/process/task_queues.js:80:21) {
errno: -4058,
code: 'ENOENT',
syscall: 'spawn C:Users/Jon7n/Desktop/server.bat',
path: 'C:Users/Jon7n/Desktop/server.bat',
spawnargs: []
}

@Whitelisted1
Copy link

@JonnyKartofa I know this is late, but show me your code and I might be able to help

sorry I can't help any more than that

@Whitelisted1
Copy link

Made a GitHub repository that showed how to do this

https://github.com/Whitelisted1/startProgram/tree/main

@Stonley890
Copy link

Changed some things to make it (hopefully) better! Some stuff was out-of-date but should work correctly now.

var kill  = require('tree-kill');
var spawn = require('child_process').spawn;
var discord = require("discord.js");

var bot = new discord.Client({ intents: ["GUILDS","GUILD_MESSAGES"]});
var mcserver;
var lastMsgTime = 0;

// IMPORTANT: Change the path below to the start.sh file.
// After that, you're done editing this script.
var MC_SERVER_START_SCRIPT = "C:/path/to/start.bat";

bot.on("ready", () =>{
  console.log('Bot online!');
});

bot.on("messageCreate", function(message){

  var msgContent = message.content.toLowerCase();

  if (msgContent == "start") {

    console.log('Attempting to start server.');
    // Only start if not running
    if (mcserver == null) {
      
      if ((bot.uptime - lastMsgTime) < 0)
      {
        console.log("Potential command spamming by " + message.author.username);
        message.channel.send("Last command was less than 60 seconds ago. Try again in a minute, " + message.author.username + ".");
      }
      else
      {
        lastMsgTime = bot.uptime;

        message.channel.send("Starting Minecraft server. This will take a minute or so.");

        // Start the server
        mcserver = spawn(MC_SERVER_START_SCRIPT);

        mcserver.stdout.on('data', function (data) {
            console.log("stdout: " + data);
            
            message.channel.send("stdout: " + data);

            if (data.includes("Closing Server")) {
              kill(mcserver.pid);
              mcserver = null;
            }
          });
        

        mcserver.on('close', function (code) {
            console.log("child process exited with code " + code);
            message.channel.send("Minecraft server has been closed. (Code: " + code + ")");

            // Stop the server
            if (mcserver != null) {
              kill(mcserver.pid);
            }

            mcserver = null;
          });
      }
    }
    else
    {
      message.channel.send("Minecraft server is already running.");
    }

  } else if (msgContent == "stop") {

    
    if ((bot.uptime - lastMsgTime) < 0)
    {
      console.log("Potential command spamming by " + message.author.username);
      message.channel.send("Last command was less than 60 seconds ago. Try again in a minute, " + message.author.username + ".");
    }
    else
    {
      lastMsgTime = bot.uptime;

      // Only stop if running
      if (mcserver != null) {
        message.channel.send("Force-stopping Minecraft server...");

        // Stop the server
        kill(mcserver.pid);

        mcserver = null;
      }
    }
  }
});

bot.login("BOT_TOKEN");

@TeddySenpai
Copy link

TeddySenpai commented Jul 7, 2022

@Stonley890 I tried your code and got the following error

Bot online!
Attempting to start server.
node:events:368
throw er; // Unhandled 'error' event
^

Error: spawn C:UsersHasnain JavedDocumentsMCServerDiscordBot-masterServersServerBStart.bat ENOENT
at Process.ChildProcess._handle.onexit (node:internal/child_process:282:19)
at onErrorNT (node:internal/child_process:477:16)
Emitted 'error' event on ChildProcess instance at:
at Process.ChildProcess._handle.onexit (node:internal/child_process:288:12)
at onErrorNT (node:internal/child_process:477:16) {
errno: -2,
code: 'ENOENT',
syscall: 'spawn C:UsersHasnain JavedDocumentsMCServerDiscordBot-masterServersServerBStart.bat',
path: 'C:UsersHasnain JavedDocumentsMCServerDiscordBot-masterServersServerBStart.bat',
spawnargs: []
}

I used your code but put in the .bat location ("C:\Users\Hasnain Javed\Documents\MCServerDiscordBot-master\Servers\ServerB\Start.bat") and the Bot Token.

Can you help?

(I'm on Windows if that means anything)

@Stonley890
Copy link

@TeddySenpai I've reworked the script in this repository: Stonley890/mc-console-bot
Try using this one.

@Skywalker8510
Copy link

Skywalker8510 commented Dec 1, 2022

@Stonley890 or @Whitelisted1 is the code currently up to date because i tried it a few months back and couldn't get it to work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment