The Slack Bot Tutorial I Wish Existed

Building useful bots with Node.js and Botkit

Faye Hayes
Jan 9 · 10 min read
From the office: Michael Scott looking as confused as I was when we started.

Setting up your Slack App

Create Slack App webpage.

Setting up your local Node.js application

The setup

var Botkit = require('botkit');
require('dotenv').config();
if (!process.env.CLIENT_ID || !process.env.CLIENT_SECRET || !process.env.PORT || !process.env.VERIFICATION_TOKEN) {
console.log('Error: Specify CLIENT_ID, CLIENT_SECRET, VERIFICATION_TOKEN and PORT in environment');
process.exit(1);
} else {
console.log('Good job, you have the variables!')
}
Your Slack App homepage. Most of the keys you’ll need to start your app are here.
Update scopes to include ‘bot’ and ‘commands’.
Green ‘install app to workspace’ button.
CLIENT_ID=XXXX
CLIENT_SECRET=XXXX
VERIFICATION_TOKEN=XXXX
PORT=8765
BOT_TOKEN=XXXX
CLIENT_SIGNING_SECRET=XXXX

Configuring the bot

var controller = Botkit.slackbot({
json_file_store: ‘./db_slackbutton_slash_command/’,
debug: true,
clientSigningSecret: process.env.CLIENT_SIGNING_SECRET,
})
controller.configureSlackApp({
clientId: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
clientSigningSecret: process.env.CLIENT_SIGNING_SECRET,
scopes: [‘commands’, ‘bot’],
})
var bot = controller.spawn({
token: process.env.BOT_TOKEN,
incoming_webhook: {
url: 'WE_WILL_GET_TO_THIS'
}
}).startRTM();
controller.setupWebserver(process.env.PORT, function(err, webserver){
controller.createWebhookEndpoints(controller.webserver);
controller.createOauthEndpoints(controller.webserver,
function(err, req, res) {
if (err) {
res.status(500).send(‘ERROR: ‘ + err);
} else {
res.send(‘Success!’);
}
});
});

Slack bot functionality

Listening for phrases

controller.hears(‘hi’, ‘direct_message’, function(bot, message) {
bot.reply(message,”Hello.”);
});

Slash commands

controller.on(‘slash_command’, function(bot, message) {
// LOGIC GOES HERE
}
controller.on(‘slash_command’, function(bot, message) {
bot.replyAcknowledge()
switch (message.command) {
case “/echo”:
bot.reply(message, ‘heard ya!’)
break;
default:
bot.reply(message, ‘Did not recognize that command, sorry!’)
}
}

Using ngrok

Authenticating your new URL

Create a new slash command

Interactive webhooks

var bot = controller.spawn({
token: process.env.BOT_TOKEN,
incoming_webhook: {
url: 'https://hooks.slack.com/services/xxxxxx/xxxxxxxx/xxxxxxxx'
}
}).startRTM();
controller.hears('webhook', 'direct_message', function(bot, message) {
bot.sendWebhook({
text: "Hey we've got the webhook!"
},function(err,res) {
if (err) {
console.log('web err', err)
}
});
});
if (message.text == 'webhook') {
bot.config.incoming_webhook.url = [YOUR_NEW_WEBHOOK]
} else {
bot.config.incoming_webhook.url = [YOUR_OLD_WEBHOOK]
}
controller.hears(['webhook', 'webhook2'], 'direct_message', function(bot, message) {
if (message.text == 'webhook') {
bot.config.incoming_webhook.url = 'https://hooks.slack.com/services/YOUR/NEW/WEBHOOK'
} else {
bot.config.incoming_webhook.url = 'https://hooks.slack.com/services/YOUR/OLD/WEBHOOK'
}
bot.sendWebhook({
text: "Hey we've got the webhook!"
},function(err,res) {
if (err) {
console.log('web err', err)
}
});
});

Deployment

"engines": {
"node": "8.x"
},
"scripts": {
"start": "node index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
Heroku dashboard tabs.

Happy bot hacking!


About the Author

Resources

Green Room

Welcome to the Green Room blog. Go behind the scenes at Backstage Capital, where we're betting big on underrepresented tech startup founders.

Faye Hayes

Written by

Freelance #Dev (fayemyrettehayes.com). Making GIFs inclusive with @PlayLoops. Engineer @ Backstage Capital. Alum UC Irvine, Dev Bootcamp. Tweet: @fayemhayes

Green Room

Welcome to the Green Room blog. Go behind the scenes at Backstage Capital, where we're betting big on underrepresented tech startup founders.