Creating a Baby Slack Bot with Node.js

In the past year I have been hearing a lot of buzz around bots in messaging apps. Specially in Slack and Messenger. My curiosity startled when I read What it’s like to build and market a chat-bot when you’re only 14 years old on a Medium article. However, only today (almost a year after I know) I decided to make some digging and try to build my own slack bot. Here it goes a quick overview of what is needed and what I have done to put my bot up and running on a Slack channel.

 

Slack Setup

I went up to Slack to create my work-space. I followed the instructions and created the work-space (URL, name, etc…) and my profile information.

Still on the Sack website, I headed to the App Directory (https://myworkspace.slack.com/apps) and clicked “Add Configuration” to create the my bot. I choose the username and clicked “Add bot integration”. Once created, a new page is shown with the bot integration settings. What allows to connect the bot with my node.js file is the API Token, the long string starting with “xoxb-*********”.

Next, I headed to my work-space and created a new channel. In the Create a channel form in the field “Send Invites to” I added my bot. Slack will auto suggest the bot for you.

 

Node Setup

I already had Node installed but if you are following along my process download Node and install it on your computer.

Then I created my application folder and run the following command inside it to setup my project .

npm init

For simplicity, I only inserted he name of the application and the main file as index.js. The rest of the fields were left by default by pressing enter until node created the package.json file.

{
  "name": "slack-sudo-bot",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@slack/client": "^3.15.0"
  }
}

Alternatively, you can download the entire project on my Github repository.

 

Install Slack Library

To be able for my project to communicate with slack I run the following command to install the Slack SDK. This command is used to install node modules in our project.

npm install @slack/client –save

 

My basic bot application

After setting up my Slack channel and my node environment, it was time to code my basic bot. 

First thing I had to insert was the bot dependencies. Slack as the Real Time Messaging API (RTM) that allows to receive events from Slack in real time as well as send messages as users. 

var RtmClient = require(‘@slack/client’).RtmClient; 
var CLIENT_EVENTS = require(‘@slack/client’).CLIENT_EVENTS;
var RTM_EVENTS = require(‘@slack/client’).RTM_EVENTS; 

The RtmClient is the reference to the RTM API. The CLIENT_EVENTS are the events that the RtmClient will listen from Slack. RTM_EVENTS is used specifically to listen all the messages of my channel.

To initialize the real time messaging with Slack I created a new RtmClient instance and started the session. Here I had to insert the token generated when I created my bot application on Slack.

var rtm = new RtmClient(‘xoxb-***********************’);
rtm.start();

Then I simply added three RTM event listeners:

AUTHENTICATED: Slack response when the bot successfully authenticates. In this response the work-space information can be extracted. As you will see below. 

rtm.on(CLIENT_EVENTS.RTM.AUTHENTICATED, (rtmStartData) => {
    for (const c of rtmStartData.channels) {
        if (c.is_member && c.name === 'sudobot') {
            channel = c.id
        }
    }
    bot = '<@' + rtmStartData.self.id + '>';
    console.log(`Logged in as ${rtmStartData.self.name} of team  ${rtmStartData.team.name}`);
});

RTM_CONNECTION_OPENED: This listener will send a greetings message to the channel once the bot (RTM Client) successfully connects with the work-space. 

rtm.on(CLIENT_EVENTS.RTM.RTM_CONNECTION_OPENED, function () {
 rtm.sendMessage(“Hello! I am Sudo Bot! What we do over here??”, channel);
});

MESSAGE: This listener waits for every message sent on the work-space. As you will see below, I filtered the listener to only process the messages of one channel.

rtm.on(RTM_EVENTS.MESSAGE, function (message) {
    if (message.channel === channel) {
        if (message.text !== null) {
            var pieces = message.text.split(' ');
            if (pieces.length > 1) {
                if (pieces[0] === bot) {
                    var response = '<@' + message.user + '>';
                    switch (pieces[1].toLowerCase()) {
                        case "jump":
                            response += '"Kris Kross will make you jump jump"';
                            break;
                        case "help":
                            response += ', currently I support the following commands: jump, joke, hodl';
                            break;
                        case "joke":
                            response += ', becoming a vegetarian is a huge missed steak.';
                            break;
                        case "hodl":
                            response += ', Yes please!!!! Crypto is mooning!';
                            break;
                        default:
                            response += ', For a list of supported commands, type: ' + bot + ' help';
                            break;
                    }
                    //bot is thinking...
                    setTimeout(() => {
                        rtm.sendMessage(response, message.channel);
                    }, 2000);
                }
            }
        }
    }
});

 

The moment of truth!

Finally was time to test my bot with the following command.

node index.js

 If you are following the process, runt this command and check if in your terminal you get the message “Logged in as [your-bot-name] of team [yout-team-name]”. 

If you got that message, your bot is connected to your slack work-space. Now when you open your slack account, under the channel you added your bot you should see the greetings message from the bot. Awesome right?!

 

In my MESSAGE listener, I checked if any user “called” the bot inside the message and if the appropriate command is given. The Bot then will give an answer depending on the user command. If a command is not recognized, the bot will notify the user the he is confused and suggests the help command for a list of commands.

Here it is! Under 70 lines of code I got my bot is up an running. I hope you guys like it. Drop a comment if you have any question or have any challenges for me. 

Disclaimer: This code was based on the this article from Jamie Munro.

Leave a Reply

Your email address will not be published. Required fields are marked *

*