Comment créer un SlackBot avec Node.js et SlackBots.js

Slack est un ensemble américain d'outils logiciels de collaboration d'équipe et de services en ligne basés sur le cloud, développés par Slack Technologies. Slack est un espace de travail où les équipes peuvent communiquer et collaborer.

Le travail d'équipe dans Slack se déroule dans les canaux - un seul endroit pour la messagerie, les outils et les fichiers - ce qui permet à chacun de gagner du temps et de collaborer.

L'une des fonctionnalités impressionnantes de Slack est les applications Slack, les intégrations et les Slack Bots.

Un bot Slack est un type d'application Slack conçu pour interagir avec les utilisateurs via une conversation. Votre bot peut envoyer des DM, il peut être mentionné par les utilisateurs, il peut publier des messages ou télécharger des fichiers, et il peut être invité à des chaînes. Cool non?

Si vous utilisez déjà Slack, vous devez être familiarisé avec certains bots créatifs Slack tels que Standupbot, Birthdaybot, etc.

Dans cet article, je vais vous expliquer comment créer votre premier bot Slack du début à la fin avec Node.js et SlackBots.js

PS: Cet article a d'abord été publié sur mon blog.

Description de SlackBot

Nous allons créer un Slackbot simple qui affiche des citations et des blagues de technicien inspirantes aléatoires pour les développeurs / concepteurs.

J'ai construit une extension chrome qui affiche des citations techniques inspirantes aléatoires pour les développeurs / concepteurs sur votre nouvel onglet (vous pouvez le télécharger ici). Nous utiliserons les citations JSON de cette extension comme API de citations et l'API Chuck Norris Jokes pour les blagues.

Lorsqu'un utilisateur mentionne notre bot et ajoute « Inspirez-moi» , le bot renvoie une citation aléatoire d'inspireNuggets. Lorsque l'utilisateur tape une blague aléatoire , il renvoie une blague aléatoire de l'API Chuck Norris. Et lorsque l'utilisateur tape help, il renvoie le guide d'instructions.

@inspirenuggets m'inspire

blague aléatoire @inspirenuggets

@inspirenuggets aide

Cet article ne porte pas vraiment sur ce que nous allons construire - il s'agit simplement de vous montrer le concept derrière les bots Slack et comment construire le vôtre. Après l'avoir parcouru, vous pouvez penser à autre chose et créer un robot différent, car il existe de nombreuses possibilités.

Vous pouvez cloner ou diviser le projet final ici.

Assez intéressant, non? Commençons.

Conditions préalables

Nous allons construire ce bot avec Node.js et SlackBots.js. Vous n'avez pas besoin de savoir comment écrire Node.js, puisque je vais vous guider à travers. Pourtant, le savoir est un avantage. Vous devriez aussi avoir

  • Connaissance de base de JavaScript
  • JavaScript ES6
  • Espace de travail Slack
  • Une certaine expérience avec Slack
  • Quelques compétences en contrôle de version

Environnement de configuration

Configurons et installons d'abord Node.js et Npm.

  • Téléchargez le nœud ici. Si vous l'avez déjà installé, ignorez cette étape. Si vous préférez utiliser un gestionnaire de packages pour l'installation, lisez ceci pour tous les systèmes d'exploitation.
  • Vérifiez si Node est installé
node -v 
  • Node.js est fourni avec Npm, vous n'avez donc pas à l'installer à nouveau.
npm -v 

Maintenant que nous avons la configuration de Node.js, initialisons notre projet.

Créez votre répertoire de projet (j'ai appelé le mien Slackbot) et initialisez git:

git init 

Ensuite, créez un index.jsfichier:

touch index.js 

Et initialisez Npm:

npm init 

Répondez simplement à toutes les questions qui viennent après. Si vous rencontrez des problèmes, voici le mien package.json:

{ "name": "slackbot", "version": "1.0.0", "description": "A simple Slackbot that displays random inspiring techie quotes for developers/designers.", "main": "index.js", "scripts": { "start": "index.js" }, "repository": { "type": "git", "url": "git+//github.com/BolajiAyodeji/slackbot.git" }, "author": "Bolaji Ayodeji", "license": "MIT", "bugs": { "url": "//github.com/BolajiAyodeji/slackbot/issues" }, "homepage": "//github.com/BolajiAyodeji/slackbot#readme" } 

Installer les dépendances

Maintenant, installons et configurons toutes les bibliothèques dont nous avons besoin.

SlackBots.js

SlackBots.js est une bibliothèque Node.js pour une utilisation facile avec l'API Slack.

npm install slackbots 

Dans index.js:

const SlackBot = require('slackbots'); 

Axios

Axios est un client HTTP basé sur la promesse pour le navigateur et node.js. Si vous connaissez Fetch ou AJAX, c'est juste une bibliothèque qui fait la même chose avec des fonctionnalités bien plus cool. Tu peux les voir ici.

npm install axios 

Dans index.js:

const axios = require('axios') 

Nodemon

Pour exécuter un script dans Node.js, vous devez exécuter node index.js. Chaque fois que vous apportez des modifications à ce fichier, vous devez réexécuter node index.js. C'est nul quand vous faites autant de changements que nous allons le faire. C'est pourquoi nous avons besoin de nodemon, un outil qui aide à développer des applications basées sur node.js en redémarrant automatiquement l'application de nœud lorsque des modifications de fichier dans le répertoire sont détectées.

npm install -g nodemon 

Dans package.json, recherchez la section scripts et ajoutez un nouveau script de démarrage:

"scripts": { "start": "node index.js" } 

Si vous exécutez npm start, le fichier s'exécutera mais ne redémarrera pas en cas de modification. Pour résoudre ce problème, utilisez le nodemon que nous avons installé à la place du nœud comme ceci:

"scripts": { "start": "nodemon index.js" } 

Dotenv

I won't explain this in-depth. In a few days, I'll publish an article around environmental variables, but for now just know that we use this to hide secret keys and tokens like the Slack Access Token we would be using. This way you don't have to push your secret keys to GitHub.

There are several ways to do this, but I prefer using dotenv. Dotenv is a zero-dependency module that loads environment variables from a .env file into process.env.

npm install dotenv 

In index.js:

const dotenv = require('dotenv') dotenv.config() 

After all installation, your package.json should look like this:

{ "name": "inspireNuggetsSlackBot", "version": "1.0.0", "description": "A simple Slackbot that displays random inspiring techie quotes and jokes for developers/designers.", "main": "index.js", "scripts": { "start": "nodemon index.js" }, "repository": { "type": "git", "url": "git+//github.com/BolajiAyodeji/inspireNuggetsSlackBot.git" }, "author": "Bolaji Ayodeji", "license": "MIT", "bugs": { "url": "//github.com/BolajiAyodeji/inspireNuggetsSlackBot/issues" }, "homepage": "//github.com/BolajiAyodeji/inspireNuggetsSlackBot#readme", "devDependencies": { "dotenv": "^8.0.0" }, "dependencies": { "axios": "^0.19.0", "slackbots": "^1.2.0" } } 

Create your Slack workspace

Now that we have that all set up, we need a Slack workspace to run our bot in development. Creating a workspace is pretty easy, read this to learn more.

Register your Slack Bot

Now that you have a workspace, you should have a Slack URL with your workspace name. Mine is mekafindteam.slack.com.

Now you'll need to create a Slack App. Create one here.

Enter your App name and ensure you're in the workspace you created if you're in multiple workspaces.

Now you'll see the settings > Basic Information page. Click the first tab Add features and functionality:

Since we're building a bot, select the Bots field.

Now you'll see the Bot user page:

Click the Add a Bot User button.

Your display name will automatically be filled in from your already chosen App name. You can update it, but I'll advise you use the same name everywhere with the same alphabet case to avoid errors.

Now, toggle the Always Show My Bot as Online switch to always show your bot as Online. Remember this bot is just like a user in your workspace. Afterwards, click the Add Bot User button.

Save all changes now:

Next, return to the Basic Information page and select the Install your app to your workspace tab.

Click the Install App to Workspace:

Click allow and wait to be redirected back to the Basic Information page.

Note the Manage distribution tab: this section is needed when you want to make your Bot available for installation by others. For now we're just building in development and I won't be covering distribution in this article. In my next article, I'll show you how to deploy your Slack bot and make it available as an App to other workspaces.

If you check your Slack workspace now, you should see the App installed in the Apps section.

For now, it's offline - once we start building the bot, we'll turn this on.

Customize your Slack bot

Now we've created our bot, let's do some customization.

Still, on the Basic Information page, scroll down to the Display Information section:

This is basic stuff: just upload a logo, change your background color, and add a short description.

Your icon should be 512x512px or bigger and your background color should be in HEX. Read more on the App guidelines here.

Here's what mine looks like after customization:

Slack bot OAuth Tokens

Now that we have our Slack bot setup, let's grab out token keys.

In the navigation bar, locate the Features section and click the OAuth & Permission tab:

You'll see two Access Tokens:

  • OAuth Access Token
  • Bot User OAuth Access Token

Copy the Bot User OAuth Access Token.

Cela changera chaque fois que vous réinstallez cette application ou lorsque vous l'installez dans un autre espace de travail. Le jeton doit commencer par xoxb-.

La sécurisation des informations d'identification est importante, que vous développiez des bibliothèques et des outils open source, des intégrations internes pour votre espace de travail ou des applications Slack à distribuer dans des espaces de travail du monde entier. - mou

C'est pourquoi nous avons installé Dotenv - nous le configurerons dans la section suivante.

Construire le bot

Maintenant, construisons notre bot :).

Tout d'abord, gardons notre jeton d'accès quelque part.

Créez un .envfichier et ajoutez ceci:

BOT_TOKEN=YOUR_SLACK_ACCESS_TOKEN_HERE 

Maintenant, commençons notre SlackBot.js:

const bot = new SlackBot({ token: `${process.env.BOT_TOKEN}`, name: 'inspirenuggets' }) 

Nous venons de créer une variable de bot qui initialise une nouvelle instance SlackBot qui a deux valeurs, notre jeton et le nom de l'application.

I used the ES6 template string syntax to bring in our token key from our .env file. dotenv has this covered for us.

Make sure you use the same name you used while creating your Slack app, or else you'll have authentication errors.

Now start the app:

npm start 

nodemon should be running now and our Slack app should be online too.

Start handler

Our Bot does nothing now even though it's running. Let's return a message.

bot.on('start', () => { const params = { icon_emoji: ':robot_face:' } bot.postMessageToChannel( 'random', 'Get inspired while working with @inspirenuggets', params ); }) 

The bot.on handler sends the welcome message. We passed two parameters, the 'start' and a function which holds a params variable which also holds the slack emoji. Slack emoji have codes, and you can find them here. I used :robot_face:, but you can change this to your preferred emoji.

We also initialized the bot.postMessageToChannel function which is a SlackBot.js method to post a message to a channel. In this function, we pass the channel name we want to post to, the message in a string, and the params variable we declared earlier for the emoji. I used the #random channel and sent Get inspired while working with @inspirenuggets to it. Your app should restart automatically and your bot should do this:

Cool right?

You can also post messages to users and groups.

 // define existing username instead of 'user_name' bot.postMessageToUser('user_name', 'Hello world!', params); // define private group instead of 'private_group', where bot exist bot.postMessageToGroup('private_group', 'Hello world!', params); 

Error Handler

Let's also write a function to check for errors and return them:

bot.on('error', (err) => { console.log(err); }) 

Message Handler

Now let's build the main bot functionality.

Like I said earlier, we'll be using the quotes JSON from the extension I built as our quotes API. The JSON can be found with this URL: //raw.githubusercontent.com/BolajiAyodeji/inspireNuggets/master/src/quotes.json

When a user mentions our bot and adds inspire me, the bot returns a random quote from inspireNuggets. When the user types random joke, it returns a random joke from the Chuck Norris API. And when the user types help, it returns the instruction guide.

First, let's check for our command words from the user message (inspire me, random joke, and help):

function handleMessage(message) { if(message.includes(' inspire me')) { inspireMe() } else if(message.includes(' random joke')) { randomJoke() } else if(message.includes(' help')) { runHelp() } } 

Now let's create the three function we need

inspireMe()

Our demo JSON is not really an API, it's just some JSON I used in the Chrome Extension. We're only accessing it from GitHub raw contents. You can use any API you prefer, you'll just have to iterate differently to get your data depending on if your API returns an array or object - whichever it returns, it's not a big deal.

Check out my previous articles on:

  • Manipulating Arrays in JavaScript and
  • Iterating through JavaScript Objects  -  5 Techniques and Performance Tests.
function inspireMe() { axios.get('//raw.githubusercontent.com/BolajiAyodeji/inspireNuggets/master/src/quotes.json') .then(res => { const quotes = res.data; const random = Math.floor(Math.random() * quotes.length); const quote = quotes[random].quote const author = quotes[random].author const params = { icon_emoji: ':male-technologist:' } bot.postMessageToChannel( 'random', `:zap: ${quote} - *${author}*`, params ); }) } 

We just used Axios to get the JSON file which returns some data:

[ { "number": "1", "author": "Von R. Glitschka", "quote": "The client may be king, but he's not the art director." }, { "number": "2", "author": "Frank Capra", "quote": "A hunch is creativity trying to tell you something." }, . . . . ] 

This JSON currently contains 210 quotes and I update them frequently. So we want to get a random quote plus the author name every time the user request it. From our Axios response, we just do this:

 const quotes = res.data; const random = Math.floor(Math.random() * quotes.length); const quote = quotes[random].quote const author = quotes[random].author 

And just like we did with the welcome message, we just return the quote and author instead of a string message:

`:zap: ${quote} - *${author}*`

Let's test this:

Type @inspirenuggets inspire me

Yayyy! It worked!

PS: You can always change the emoji type for every request. If you noticed I changed the inspireMe() to :male-technologist:

randomJoke()

We're getting the jokes from the Chuck Norris API from this endpoint //api.chucknorris.io/jokes/random.

{ "categories": [], "created_at": "2016-05-01 10:51:41.584544", "icon_url": "//assets.chucknorris.host/img/avatar/chuck-norris.png", "id": "6vUvusBeSVqdsU9C5-ZJZw", "updated_at": "2016-05-01 10:51:41.584544", "url": "//api.chucknorris.io/jokes/6vUvusBeSVqdsU9C5-ZJZw", "value": "Chuck Norris once choked a wildcat to death with his sphincter muscle." } 

This is a real API that returns a random joke on every request, so we don't have to do Math.floor() again.

function randomJoke() { axios.get('//api.chucknorris.io/jokes/random') .then(res => { const joke = res.data.value; const params = { icon_emoji: ':smile:' } bot.postMessageToChannel( 'random', `:zap: ${joke}`, params ); }) } 

By now, you should understand how this works already. Make a post with the channel name, message and params.

runHelp()

This is similar to our welcome message: we just want to return a custom text when the user adds help to the request.

function runHelp() { const params = { icon_emoji: ':question:' } bot.postMessageToChannel( 'random', `Type *@inspirenuggets* with *inspire me* to get an inspiring techie quote, *random joke* to get a Chuck Norris random joke and *help* to get this instruction again`, params ); } 

Now let's test all three commands:

Everything works fine now, congratulations!!!! You just built your SlackBot.

There are an endless number of possibilities of Bots you can build with this to automate your own work or teamwork.

You can build a bot that:

  • Fetches your tasks from somewhere and reminds you when you type hey what next,
  • Welcomes every user to your workspace (I built this during one of the HNG Internship's),
  • Gives you football matches updates while you're working,
  • Tells your team when you hit a milestone in number of registered users,

and many more...

It's just about having somewhere to get the data from, and some basic iteration skills and the bot.postMessageToChannel() method.

Automation is one thing we should learn as developers. We have a lot to do, so we should automate the simpler tasks so we have time for the more difficult ones. I hope with this you can automate your tasks and I look forward to the creative ideas you'll bring to life.

Final Code

Here's our final index.js

const SlackBot = require('slackbots'); const axios = require('axios') const dotenv = require('dotenv') dotenv.config() const bot = new SlackBot({ token: `${process.env.BOT_TOKEN}`, name: 'inspirenuggets' }) // Start Handler bot.on('start', () => { const params = { icon_emoji: ':robot_face:' } bot.postMessageToChannel( 'random', 'Get inspired while working with @inspirenuggets', params ); }) // Error Handler bot.on('error', (err) => { console.log(err); }) // Message Handler bot.on('message', (data) => { if(data.type !== 'message') { return; } handleMessage(data.text); }) // Response Handler function handleMessage(message) { if(message.includes(' inspire me')) { inspireMe() } else if(message.includes(' random joke')) { randomJoke() } else if(message.includes(' help')) { runHelp() } } // inspire Me function inspireMe() { axios.get('//raw.githubusercontent.com/BolajiAyodeji/inspireNuggets/master/src/quotes.json') .then(res => { const quotes = res.data; const random = Math.floor(Math.random() * quotes.length); const quote = quotes[random].quote const author = quotes[random].author const params = { icon_emoji: ':male-technologist:' } bot.postMessageToChannel( 'random', `:zap: ${quote} - *${author}*`, params ); }) } // Random Joke function randomJoke() { axios.get('//api.chucknorris.io/jokes/random') .then(res => { const joke = res.data.value; const params = { icon_emoji: ':smile:' } bot.postMessageToChannel( 'random', `:zap: ${joke}`, params ); }) } // Show Help function runHelp() { const params = { icon_emoji: ':question:' } bot.postMessageToChannel( 'random', `Type *@inspirenuggets* with *inspire me* to get an inspiring techie quote, *random joke* to get a Chuck Norris random joke and *help* to get this instruction again`, params ); }

What Next?

Our bot only runs in development now, and to use it we always have to npm start.

This isn't cool, right? We'll want to host it somewhere it can run every time. In my next article, I'll show you how to host this on either Heroku, Zeit or Netlify and publish it to the Slack Apps store so anyone around the world can use it.

Also, don't forget to add this in your .gitignore before pushing to GitHub:

 /.env /node_modules 
Subscribe to my newsletter to get updated.

Useful Resources

  • Slack API
  • Slack API Docs
  • SlackBot.js
  • Slack Apps
  • Slack Apps Guidelines
  • An introduction to Slack apps
  • inspireNuggets
  • inspireNuggetsSlackBot