9 min read
2022-01-09
Pre-Prerequisites: This blog will assume that you have a code editor (such as VSCode), know how to navigate your file system, and how to use GitHub. Additionally, this blog assumes that you have npm
already installed on your computer.
With that being said, we will be coding our discord bot in node.js
, even though it is entirely possible to do it with other languages as well!
The discord bot we are building today will respond to user messages starting with the command $define
, and define the word they specify after the command. However, this code is EASILY extendable to handling other commands.
blog-example-bot
npm
using the command: npm init -y
Running this command should create a new file in your directory called package.json
, which tells npm which packages we are going to use.
5. To install the discord.js
package, we will use the npm install
command.
npm install discord.js
nodemon
package, which can be installed with:npm i nodemon
dotenv
package, which can be installed via:npm i dotenv
This is what your file directory should look like so far!
src
. This is where the code for the bot will go. src
folder, create a file called bot.js
. .env
, which will store the secrets of our bot!using dotenv
allows us to reference sensitive information through environment variables!
After creating files and folders, this is what your file directory should look like!
src
folder, navigate to the bot.js
file. dotenv
and discord.js
packages in order to create our discord bot! The lines of code to require these packages are:require('dotenv').config();
const { Client, Intents } = require('discord.js');
These lines of code should be at the top of your bot.js
file.
Now, we will need to register our bot with discord!
Navigate to the Discord Developer Portal
Click the New Application
button at the top right of the screen
Give your bot a name! I'm going to name mine: Blog Example Bot
Click the Create
button!
On the left side of the screen, click on the Bot
tab.
Click Add Bot
Click Yes, do it!
To get our bot token, click Click to Reveal Token
Click the Copy
button. Don't share your token with anyone else, I have blurred out my token.
Within your .env
file, set an environment variable called BOT_TOKEN
, and paste the value you just copied!
BOT_TOKEN=your-pasted-bot-token
OAuth2
. Look under that tab, and click on URL Generator
.bot
box on the first set, and the Send Messages
, Manage Messages
, Read Message History
, and Add Reactions
bot permissions!
Blog Example Bot Server
bot.js
file, we need to declare which permission our bot has access to. Place the following line after the require
statements:const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] });
$
:const PREFIX = "$";
client.login()
command!client.login(process.env.BOT_TOKEN);
We are using the BOT_TOKEN
env variable that we set previously!
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
});
package.json
file, we will specify the command to run our bot! Place the following code into your package.json
file, and change the name to be your folder's name!{
"name": "CHANGE_TO_YOUR_FOLDER_NAME",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "nodemon ./src/bot.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"discord.js": "^13.5.1",
"dotenv": "^10.0.0",
"nodemon": "^2.0.15"
}
}
npm run dev
At this point, your bot.js
file should look like:
require('dotenv').config();
const { Client, Intents } = require('discord.js');
const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] });
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
});
client.login(process.env.BOT_TOKEN);
client.on('messageCreate', async (message) => {
console.log(message);
});
bot.js
file before sending a message!So far, your bot.js
file should look like:
require('dotenv').config();
const { Client, Intents } = require('discord.js');
const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] });
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
});
client.on('messageCreate', async (message) => {
console.log(message.content);
});
client.login(process.env.BOT_TOKEN);
message.reply();
require('dotenv').config();
const { Client, Intents } = require('discord.js');
const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] });
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
});
client.on('messageCreate', async (message) => {
if (message.author.bot) return;
message.reply(`Hello ${message.author.username}!`);
});
client.login(process.env.BOT_TOKEN);
In order to have our user "summon" our bot, they will need to add a prefix (in our case is $
) to show that we want the bot to respond.
For our discord bot, we are going to have it define simple words, so our command that we are going to handle is $define
messageCreate
callback, delete the message.reply()
, as we will not need it anymore. client.on('messageCreate', async (message) => {
if (message.author.bot) return;
if (message.content.startsWith(PREFIX)) {
await handleCommand(message);
}
});
handleCommand()
function, which should take in the message
object as a parameter.handleCommand()
function, we need to extract out both the command and the argument that the user is specifying with that command.async function handleCommand(message) {
const [command, ...args] = message.content
.trim()
.substring(PREFIX.length)
.split(/\s+/);
if (command === 'define') {
handleDefine(message, args);
}
}
Our bot will be able to define simple words that the user feeds it!
word-definition
npm package:npm i word-definition
require(discord.js)
oneconst wd = require("word-definition");
handleDefine(message, args)
, which takes in the message object and the arguments that the user passed it.async function handleDefine(message, args) {
const word = args.join(" ");
try {
wd.getDef(word, "en", null, async function (definition) {
let reply = `**${word}** (${definition.category}): ${definition.definition}`;
if (!definition.definition) {
reply = `No definition found`;
}
message.reply(reply);
});
} catch (e) {
return message.reply(e);
}
}
If the bot can find a definition, we will reply to the message with the definition of that word, but if it can't, the reply is "No definition found"
Great job! We're done!
Here is my entire bot.js
file:
require('dotenv').config();
const { Client, Intents } = require('discord.js');
const wd = require("word-definition");
const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] });
const PREFIX = "$";
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
});
client.on('messageCreate', async (message) => {
if (message.author.bot) return;
if (message.content.startsWith(PREFIX)) {
await handleCommand(message);
}
});
async function handleCommand(message) {
const [command, ...args] = message.content
.trim()
.substring(PREFIX.length)
.split(/\s+/);
if (command === 'define') {
handleDefine(message, args);
}
}
async function handleDefine(message, args) {
const word = args.join(" ");
try {
wd.getDef(word, "en", null, async function (definition) {
let reply = `**${word}** (${definition.category}): ${definition.definition}`;
if (!definition.definition) {
reply = `No definition found`;
}
message.reply(reply);
});
} catch (e) {
return message.reply(e);
}
}
client.login(process.env.BOT_TOKEN);
My package.json
:
{
"name": "blog-example-bot",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "nodemon ./src/bot.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"discord.js": "^13.5.1",
"dotenv": "^10.0.0",
"nodemon": "^2.0.15",
"word-definition": "^2.1.6"
}
}
My file structure:
Now, if you want the bot to be active FULL TIME, not just when you run the command npm run dev
in your terminal, you can deploy it for free using Heroku.
Here is a great resource on how to do that!
~ Ganning Xu © 2024