Introduction
In this tutorial, you will be learning how to create a Minecraft bot that syncs messages from Discord to Minecraft and vice versa. You will be utilizing the Discord.js library, Mineflayer library, and Node.js runtime to create this application. Without further ado, let's get started!
Brief Description of Discord.js, Mineflayer, and Node.js
Discord.js is a popular library used to easily create and control bots through the Discord API.
Mineflayer is a library that allows you to control Minecraft bots through a stable and high-level JavaScript API. It can do things such as digging and building, crafting, interacting with entities, inventory management, chat, and more.
Node.js is a cross-platform JavaScript runtime based on Chrome's V8 engine used in all environments. Node.js also includes NPM, a package registry that hosts open-source packages or modules. This tutorial uses a few community-made packages to make it easier to get started.
Prerequisites
Before you begin, you should:
- Deploy an Ubuntu 20.04 server.
- Update the server.
- Log in to your server as the root user.
- Install Node.js and NVM.
You will also need:
- A Discord account to create a new developer application that will link with your Minecraft bot.
- A server for your Minecraft bot.
- This server can be your own or another server IP for your bot. To create your own, you can deploy a Rcs One-Click Minecraft installation or install it on your current server by following this guide.
- A Minecraft account.
Create a New Discord Application
To allow your application to connect with the Discord API, you must create a new Discord application.
Go to the Discord Developer Portal and click the New Application button.
Give it a name and click Create.
Head to the Bot section on the left.
Click Add Bot.
Click Yes, do it! to confirm.
Click the Copy button under the Token section and note it down. You will need it when configuring the Discord bot.
Keep this token a secret! If anyone gets access to this token, they have access the bot account. If someone does gain access, you can hit the "Regenerate" button next to the copy button. Keep in mind that it will invalidate the existing one.
Scroll down to Authorization Flow and uncheck the Public Bot option. If you don't mind that anyone can invite your bot, then leave this option checked.
Scroll down to Privileged Gateway Intents and check Message Content Intent. The message intent allows the bot to receive message events from the Discord API and allows the bot to respond to them.
Click Save Changes at the bottom of the page.
Add the Discord Bot to Your Server
To add the bot, you must generate an OAuth2 URL. Head to the OAuth2 section on the left side of the developer dashboard and click URL Generator. Because Discord uses a scope-based system for its permissions, you need to specify that you would like to use the bot
scope. You can find it in the middle of the scope selection. After that, a section called Bot Permissions will appear. The bot in this tutorial uses message.delete()
to delete messages, so you should add the Manage Messages permission. Also, the Read Messages/View Channels, Send Messages, Embed Links, and Read Message History permissions will allow your bot to respond to messages.
When finished, copy the link from the Generated URL section. You can now visit this link in your browser to bring up the authorization page. Click the dropdown menu, select the server you want to add it to and click Authorise.
It will now ask you to confirm the permissions. If it doesn't look right, you can always uncheck the permissions or add them later with a role. Click Authorise again, and it will show that you have authorized the bot to join your server.
Copy the Server and Channel IDs
The server ID and channel ID where the bot will send messages are also required.
Log in to Discord and click the gear at the bottom left that says User Settings. Scroll down on the sidebar until you see App Settings and head into the Advanced settings. Enable Developer Mode and exit the settings menu. Developer Mode will enable the Copy ID button.
Navigate to your desired server and right-click the server icon. Then, click Copy ID and write it down as the "server ID".
Right-click a text channel on the same server that you would like the bot to send its messages. It must be a text channel that is on the same server. Click Copy ID and make a note of it for later.
Install the Required Libraries
Create a new folder and navigate to it.
# mkdir discord-minecraft-bot # cd discord-minecraft-bot
Install the Mineflayer library using NPM.
# npm install mineflayer
Install the Discord.js library, also using NPM.
# npm install discord.js
Install the dotenv library, which will read the
.env
file.# npm install dotenv
You have the required libraries installed and now you are ready to set up the application.
Set Up Your Application
Create a new JavaScript file called index.js
and open it in your text editor.
# nano index.js
Once you have opened the file, you can insert this starter code to set up the application structure.
require('dotenv').config();
const mineflayer = require('mineflayer');
const Discord = require('discord.js');
const discordBot = new Discord.Client({
allowedMentions: { parse: ['users', 'roles'], repliedUser: true },
intents: [Discord.Intents.FLAGS.GUILD_MESSAGES],
});
const minecraftBot = mineflayer.createBot({
host: 'YOUR_SERVER_IP',
username: 'example@example.com',
password: 'password',
});
// ID variables
const discordServerID = 'YOUR_SERVER_ID';
const chatChannelID = 'YOUR_CHANNEL_ID';
// Console log bot logins and disconnects
discordBot.on('ready', () => {
console.log(`The Discord bot ${discordBot.user.username} is ready!`);
});
minecraftBot.on('login', () => {
console.log('Minecraft bot has logged in!');
});
minecraftBot.on('end', () => {
console.log('Minecraft bot disconnected from the server.');
});
// Discord message handler
async function toDiscordChat(msg) {
await discordBot.guilds.cache.get(discordServerID).channels.fetch();
return discordBot.guilds.cache.get(discordServerID).channels.cache.get(chatChannelID).send({
content: msg,
});
}
This starter code will load the required libraries, define the discordBot
and minecraftBot
, enable the discordServerID
and chatChannelID
variables, and log both of the bot's logins and disconnects. The Discord.Client()
options disable mentions for @everyone
and @here
and add the important Message Content Intent you enabled earlier.
The toDiscordChat()
function allows sending messages to the IDs defined by discordServerID
and chatChannelID
by fetching the channels from the Discord bot's cache and sending the message to the channel.
Configure Your Discord Bot
You can now set the server ID and channel ID. These allow the bot to find the correct server and channel to send the messages to. You can find the discordServerID
and chatChannelID
variables near the top of the code, pre-filled with "YOUR_SERVER_ID" and "YOUR_CHANNEL_ID". Paste the corresponding IDs into the variables, like the example below.
const discordServerID = '829678508585648138';
const chatChannelID = '916599650079870977';
Add the Discord -> Minecraft Chat Module
You can now add an event listener to the discordBot
that listens to messageCreate
from the Discord.js library. This will allow the bot to respond to messages.
discordBot.on('messageCreate', async (message) => {
try {
if (message.author.id === discordBot.user.id || message.channel.id !== chatChannelID || message.author.bot) return;
minecraftBot.chat(`${message.author.username}: ${message.content}`);
toDiscordChat(`[DISCORD] ${message.author.username}: ${message.content}`);
await message.delete();
} catch (error) {
console.error(error);
}
});
This code runs when the Discord bot receives a message event. It will check if the bot sent the message itself, if it's in the "chat" channel (the channel ID defined in chatChannelID
), or if a different bot sent the message. If any of these conditions match, it will ignore the message. Otherwise, it will send the message to the Minecraft server and the same message to the Discord chat channel with the [DISCORD] prefix. Afterward, it will delete the original message. This condenses them into the same format. It also catches any errors and logs them to the console.
Allow the Bot to Log In Using a Token
To allow the bot to log in to the Discord API, it requires the token saved earlier. You will store this token in a .env
file in a later step. Then, append the code that references the .env
file using process.env
to the bottom of the file.
discordBot.login(process.env.DISCORD_TOKEN);
Configure Your Minecraft Bot
Using mineflayer.createBot()
, you can set options such as the server IP, account username, and account password. Note that a valid Minecraft account is required for you to connect to 'online' multiplayer servers. To add the account information, you will need to add it to the .env
file as they are sensitive values. You will add them in a later step. For now, you can reference the .env
file by filling in the username
field with process.env.EMAIL
and the password
field with process.env.PASSWORD
.
To allow unauthenticated users to connect to your server, it must be in "offline" mode. The password
field can be blank for the Minecraft bot options, and the username
field can be any username. Please only use this option if you know what you are doing.
If you have migrated your Mojang account to a Microsoft account, you need to add the `auth: 'microsoft" option.
If you host your server locally, use localhost
for the host
option. Otherwise, use the IP you have assigned to your server or the IP of an existing server.
For example, you have migrated your account, and your server IP is localhost
. Your mineflayer.createBot()
options should look like the one below.
const minecraftBot = mineflayer.createBot({
host: 'localhost',
username: process.env.EMAIL,
password: process.env.PASSWORD,
auth: 'microsoft',
});
Adding the Minecraft -> Discord Chat Module
Add the new chat
event listener above the discordBot.login()
line.
minecraftBot.on('chat', (username, message) => {
if (username === minecraftBot.username) return;
toDiscordChat(`[MC] ${username}: ${message}`);
});
This code listens to the chat
event from the Mineflayer library and picks up the username
and message
from the event. It then checks if the username from the message is the bot's username. It will just ignore it to prevent a message loop if it is. It then sends the username and message to the Discord chat channel with the [MC] prefix.
Note that if any plugins or mods change the server's chat, it will not match the expected vanilla chat pattern. See the Mineflayer documentation for adding custom chat patterns.
Securely Add Login Credentials and Tokens
To securely add your login credentials and tokens, you can use the dotenv
library. This library will allow you to store your login credentials and tokens in a separate .env
file. It is crucial for keeping our "secrets" safe, as separating them from the code prevents accidental leakage when copying, pasting, or publishing code.
Exit the index.js
file using Ctrl + X, then pressing Y, followed by Enter to confirm your changes.
You can now create the .env
file in the same folder as your index.js
file.
# nano .env
Add the following lines to the file.
BOT_TOKEN=(insert bot token here)
EMAIL=(insert Minecraft account email here)
PASSWORD=(insert Minecraft account password here)
Replace the placeholder text and the parentheses with your actual Minecraft account credentials and the bot token copied from an earlier step.
Run Your Application
Close your text editor by using Ctrl + X, then pressing Y, followed by Enter to confirm your changes.
Congratulations! You have now set up and configured your own Minecraft bot and Discord bot that can mirror messages between both chats.
To test your bot, run your code using node
.
# node index.js
Then, join the bot's server and enter anything into the chat. It should show up in Discord with the [MC] prefix. Next, send a message in the same Discord channel, and the bot should output it to the Minecraft server. It also should delete your message and re-send it with the [DISCORD] prefix.