If this is the millionth article you've found on how to build a Slack bot with Node.js, I'm sorry.
I've built a few Slack bots, some of which have launched on the Slack App Directory. I'm going to give you a no-bullshit tutorial on creating a Slack bot with Node.js.
We'll build an internal tool that your team can use to get information about your customers using a slash command. I'm not going to teach you how to build a Slack app for the Slack App Directory.
You need to use Ngrok to connect your Slack workspace (on the internet) to your locally-running Slack bot (on your machine). It has a free plan, but the basic plan is affordable and extremely useful for building Slack bots.
Security note: Ngrok exposes your machine to the internet, making it a potential attack vector. If you're building your Slack bot on your work machine, get Ngrok approved by your security team.
Create a Ngrok account and follow the set-up steps. When you're finished, expose a web server on port 8080:
ngrok http 8080
This should produce the Ngrok console UI:
ngrok by @inconshreveable
Tunnel Status online
Version 2.0/2.0
Web Interface http://127.0.0.1:4040
Forwarding http://92832de0.ngrok.io -> localhost:8080
Forwarding https://92832de0.ngrok.io -> localhost:8080
Connnections ttl opn rt1 rt5 p50 p90
0 0 0.00 0.00 0.00 0.00
If you're on the free Ngrok plan, don't close this terminal window. The forwarding URL is randomly generated, and will change when you restart Ngrok.
Take note of the Forwarding
URL. In the example above, it is: https://92832de0.ngrok.io
.
Before we start writing code, we need to create a Slack App.
<NGROK_FORWARDING_URL>
with your Ngrok forwarding URL in the App Manifest YAML file below.In the Ngrok example above, we would use
https://92832de0.ngrok.io
. So, theredirect_urls
example below would become:https://92832de0.ngrok.io/slack/oauth_redirect
_metadata:
major_version: 1
minor_version: 1
display_information:
name: NodeBot
description: Our internal Slack bot.
features:
bot_user:
display_name: NodeBot
always_online: true
slash_commands:
- command: /customer
url: <NGROK_FORWARDING_URL>/slack/events
description: Get data about a customer
usage_hint: /customer <customer id>
should_escape: false
oauth_config:
redirect_urls:
- <NGROK_FORWARDING_URL>/slack/oauth_redirect
scopes:
bot:
- commands
- chat:write
- chat:write.public
settings:
org_deploy_enabled: false
socket_mode_enabled: false
token_rotation_enabled: false
App Manifest for your Slack bot 4. Select Next, then select Create.
Scroll down to the **App credentials **section and take note of the following values:
Client ID
Client secret
Signing secret
Finally, install the app to your Slack workspace.
Bot User OAuth Token
.Let's ensure your local environment is set up correctly. The dependencies for this Slack bot are as follows:
node >=12.13.0
npm >=6.12.0
Start by creating a new directory for the Slack bot and initialising npm
:
mkdir slackbot-node
cd slackbot-node
npm init
Follow the prompts (tip: hold down the Enter key).
Let's install the project dependencies. Our main dependency is Bolt, the official Slack framework for building Slack apps with JavaScript.
npm install --save @slack/bolt dotenv
npm install --save-dev nodemon
.env
file..env
file, and add the values you took note of in the Set up your Slack app section.SLACK_CLIENT_ID=<YOUR SLACK CLIENT ID>
SLACK_CLIENT_SECRET=<YOUR SLACK CLIENT SECRET>
SLACK_SIGNING_SECRET=<YOUR SLACK SIGNING SECRET>
SLACK_BOT_USER_TOKEN=<YOUR SLACKBOT USER TOKEN>
SLACK_OAUTH_STATE_SECRET='my-state-secret'
index.js
file. This will be the entry point for our bot server.require("dotenv").config();
const { App } = require("@slack/bolt");
const port = process.env.PORT || 8080;
const app = new App({
token: process.env.SLACK_BOT_USER_TOKEN,
signingSecret: process.env.SLACK_SIGNING_SECRET,
});
// Slash command handler goes here.
(async () => {
await app.start(port);
console.log(`🤖 Slack bot at your service (http://localhost:${port})`);
})();
nodemon
.
nodemon
restarts the server whenever we edit ourindex.js
file
nodemon --exec node index.js
You should get the following output:
[nodemon] 2.0.13
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node index.js`
🤖 Slack bot at your service (http://localhost:8080)
The App Manifest file that we used to create our Slack app has already added a slash command for us; it's called /customer
. Whenever somebody in your Slack workspace types /customer
, Slack will send a POST request to your bot server; we need to program our bot server to respond correctly to the /customer
slash command.
Add the following code to index.js
:
// Handle the /customer slash command
app.command('/customer', async ({ command, ack, respond }) => {
// Acknowledge command request
await ack();
await respond('Slack bot at your service!');
});
Now, we can test the slash command in Slack. Type /customer
in Slack. This should yield the following result:
Finally, the juicy part. The method for getting customer data will vary based on your tech stack and where your customer data lives. Typically, you'll execute a database query here. For now, let's return some dummy user data.
Format your response with the Slack Block Kit Builder.
const customerData = {
name: "Jane Doe",
email: "[email protected]",
activeUsers: 10,
plan: "Enterprise",
totalSpend: "$1002.26",
};
// Format the text however you like; Slack supports Markdown.
const header = `*${customerData.name}* (${customerData.email})`;
const body = `>${customerData.plan} plan\n>${customerData.activeUsers} users\n>${customerData.totalSpend} total spend`;
const response = {
response_type: "in_channel", // make the response public
blocks: [
{
type: "section",
text: {
type: "mrkdwn",
text: `${header}\n${body}`,
},
},
],
};
await respond(response);
Let's run it in Slack and see the result. Type /customer
in Slack:
Building and maintaining internal Slack bots is a hassle. I built Runtime to help you rapidly create custom Slack bots. Write your internal script in your technology of choice, and Runtime handles the rest. Let me know what you think on Twitter.
Also published on https://blog.runtimehq.com/create-a-slack-bot-in-6-steps/.