In this guide you will learn how to use node-red and Discord.JS to create you own bot! There’s currently multiple discord-nodes available on nodered.org, but they might not fit your needs, and you might want to try out Discord.JS as it offers more flexibility.
Table of contents:
- Create your bot on Discord.com
- Installing the Discord.JS-module in Node-RED
- Creating your event-listener
- Reacting to messages
- Importable example-flow
Create your bot on Discord.com
The first thing you’ll have to do is to create a Discord-application. The application that you’ll be creating will be containing a Discord-bot.
Head over to https://discord.com/developers/applications, log in, and press ‘New Application’ in the upper right corner.
A window will appear and you’ll be asked to name your application. No worries if you’re not able to come up with a fitting name. The name can easily be changed later on :- ).
In the navigation-pane to the left, choose ‘Bot’, and click ‘Add Bot’. When prompted with “ADD A BOT TO THIS APP?”, press ‘Yes, do it!’
You have now successfully added a bot user to your app! Edit your bots username and icon(avatar) to your preference and press ‘Save Changes’! The bots username and avatar will be visible in your servers memberlist. You must also press ‘Click to Reveal Token’ and take note of the token presented. This is your bots password and you should not share this with anyone.
The only step missing is setting your bot’s permissions and inviting it to your discord-server. Head over to ‘OAuth2’ in the navigaton pane. It is considered good practice to follow the principle of least privelege when setting up the permissions.
Select “Bot” under “Scopes”. Because this bot is only going to send messages, im only going to give it the permissions ‘Send messages’ and ‘Read Message History’. When developing your own bot, you’re more than likely going to give it more permissions than i have in this example. When you’re done selecting your permissions, click ‘Copy’ and paste the URL into the address bar of your web browser.
Choose which server you want to add the bot to and click “Continue”. Verify your permissions and click ‘Authorize’
If you head over to your Discord server, you’ll see that your bot is now listed in the servers memberlist. It’s currently disconnected, but follow along and i’ll show you how to connect nodered to discord using Discord.Js :- ).
Installing the Discord.JS-module in Node-RED
Now that you have set up your bot, it’s time to establish a connection between your Node-RED instance and Discord using Discord.JS. The reason why Node-RED version 1.3 or higher is a prerequisite, is because it simplifies the process of adding and importing node modules by quite a lot.
Head over to the Node-RED editor in your web browser and drag a function node onto your workspace. Open the nodes settings by double-clicking. Navigate to the setup tab and press ‘+ add’ in the bottom left corner to add/import(require) a new module. In the field to the right, type “discord.js”, and in the field to the left, remove the dot so it says “discordjs” as seen in the picture below. Press done and deploy the flow. Node-RED will now download the module, and you’ll be able to use it in your function-node. Head over to the next step and we’ll create a message-listener :- ).
Creating your event-listener
Now it’s time to write some code and we’ll be creating a couple of event-listeners. In the same function-node as earlier, click on the ‘On Message’-tab. Each step underneath contains a screenshot, a code-block(for your convenience) and an explanation, so it should be pretty straight forward to follow along in your own environment :- ).
The first thing we’ll do, is to create a client. We’ll store the client in the ‘Client’-variable and in the global context for later use. In short, global context is a place to store stuff so it’s available for other nodes to access. Read more about context here.
From line 1-13, i’ve also implemented a safety net so that we only have one client running at most.
I do like visual feedback, so when the client is logged in or disconnected, i want the node to tell me so. Using the client we created in the previous step, we’ll create event listeners that listens for when the client is ready and when it’s disconnected. node.warn() will write this information to the debug console, and node.status() will display the status underneath the node as seen in the screenshot below.
The third and most important event we’ll be listening to in this guide is ‘message’. This triggers everytime a message get sent to a channel that the bot has sufficent access to. As we do not want the bot to react to its own messages, we’ll check if the author of the message is a bot, and if so, it’ll exit the code.
If the message is not authored by a bot, we want function-node to send() a msg-object which contains the message to the next node in the flow. We also have to tell the client to login() using the API-key obtained from discord.com in one of the first steps in this guide. Press done and deploy your flow.
It is worth nothing that the node.send-method contains two arguments. The first one is our newly created object, and the second one is a boolean telling node-RED not to clone our object before sending. By default, all objects sent by node.send() are cloned. Cloning the message-object from the event-listener causes node-RED to crash, so we have to specify that our object is not cloned. If you were to attach two different nodes to the same output(also called branching), the second node that recieves the message would get a cloned object even if we told it not to clone. Read more about cloning here.
In the Node-RED editor, insert and connect an inject node and a debug node to each side of the function node as shown in the picture below and deploy the flow. Remember not to branch your flow.
The inject-node is actually your bot’s ON-button. Pressing the ON-button causes your code to run which again creates a client. Go ahead and try. Your function-node should say ‘connected’, and if you head over to your discord server, you’ll see that the bot is now online.
If you write something in the Discord-channel, you’ll see in the same message in the debug-panel in the Node-RED editor. This means that your bot is ready to process messages.
Reacting to the messages
Now that your bot is online(if it’s not, you have to retrace your steps), we can now start processing messages. Delete the debug node, and attach a new function node instead. Remember not to branch your flow.
To react to a specific message, we have to first check its content. If we decide we want to react to the message by replying, we can use the reply()-method which comes with the message-object in the payload.
Alternatively, instead of handling the logic inside a function-node, you could use a switch-node and route the message based on conditions. In the example underneath, i’m checking wether the content is ‘ping’ or ‘Have a nice day, bot!’, and then routing the message based on that.
We can now generate two different responses based on what someone writes in the channel. I think wishing the bot a nice day is a nice gesture, so let’s make it reply with thanks and an emoji.
And thats it for this guide! If you’ve followed it step by step, you should now be able to write ‘Have a nice day, bot!’ and the bot should reply with a message and react with heart :- ).
The following json-code contains the whole flow used in this guide and is importable in Node-RED.