Today we will be creating a SlackBot that reacts to every message sent by a specific user. Useful, right? 😄
The first thing we have to do is create a new Slack app. We do this by navigating to api.slack.com and navigating to Your Apps -> Create New App
.
We’ll call our app reacting-bot
. Next up, we have to set up event subscriptions, a bot user, and permissions.
The first thing we have to do is enable Socket Mode. Turning on Socket Mode will route your app’s interactions and events over a WebSockets connection instead of sending these payloads to different Request URLs.
To enable Socket Mode, navigate to Settings -> Socket Mode
and hit Enable Socket Mode. You will be prompted to add scopes and generate an app-level token. Give the token a name, e.g., “token”, and add the following scopes:
connections:write
& authorizations:read
As the names suggest, these will give our app permission to read and write messages.
Next up, we need to enable Event Subscriptions, which can be found beneath Features
in the left-side menu. After enabling Event Subscriptions, you will need to add the following Event Subscriptions.
message.groups
message.channels
If a Bot User has not yet been created, it can be set up on the App Home
tab. Here we can set a display name and its username.
Lastly, we need to ensure that the SlackBot has all the correct permissions needed. Head over to OAuth & Permissions
and add the reactions.write
permission to the Bot Token Scopes.
We have now set up the SlackBot, and we are ready to start coding!
We will be using the bolt-js
library as an interface to the Slack API. It comes with many useful features that make creating SlackBots a breeze.
While in a new directory reacting-bot
, we can initialize the project using npm init -y
. This will create a package.json
file that looks like the following:
{
"name": "reacting-bot",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
For this project, we are going to need two packages. @slack/bolt and dotenv. Bolt is an interface that we use to communicate with the Slack API, and dotenv is used to access environment variables. We can install the packages with the following command:
npm install @slack/bolt dotenv
Next up, we need to create the file .env
which should store our environment variables for when we are running this project locally. The file should contain the following:
SIGNING_SECRET=5c24e...
TOKEN=xoxb-...
APP_TOKEN=xapp-...
USER_ID=UCF8...
SIGNING_SECRET
can be found on the Basic Information page
TOKEN
(xoxb) can be found on the OAuth & Permissions page
APP_TOKEN
(xapp) can be found on the Basic Information page under App-level tokens
USER_ID
can be found when viewing a slack profile under More
In index.js
, we start by importing @slack/bolt
and dotenv
, and we initialize a bolt application in socket mode in the constant app
:
const { App } = require("@slack/bolt");
require("dotenv").config();
const app = new App({
signingSecret: process.env.SIGNING_SECRET,
token: process.env.TOKEN,
socketMode: true,
appToken: process.env.APP_TOKEN,
});
We then write the logic that uses the message()
method to attach a listener for messages.
app.message(async ({ message, context }) => {
if (message.user === process.env.USER_ID) {
try {
const result = await app.client.reactions.add({
token: context.botToken,
name: "heavy_plus_sign",
channel: message.channel,
timestamp: message.ts,
});
} catch (error) {
console.error(error);
}
}
});
We check any given message is sent by the user with the ID
USER_ID
. If we find a match, we use the app.client.reactions.add()
function to add a reaction to the message.
Lastly, we add a function that runs when the application starts. This function will start up the Slack App:
(async () => {
const port = process.env.PORT || 3000;
await app.start(port);
console.log(`⚡️ reacting-bot is running on port ${port}`);
})();
And that’s it! You can now run the app using the npm start
command, and the bot will start reacting to messages once it has been added to the correct channels.
This is what the final code looks like:
const { App } = require("@slack/bolt");
require("dotenv").config();
const app = new App({
signingSecret: process.env.SIGNING_SECRET,
token: process.env.TOKEN,
socketMode: true,
appToken: process.env.APP_TOKEN,
});
app.message(async ({ message, context }) => {
if (message.user === process.env.USER_ID) {
try {
const result = await app.client.reactions.add({
token: context.botToken,
name: "heavy_plus_sign",
channel: message.channel,
timestamp: message.ts,
});
} catch (error) {
console.error(error);
}
}
});
(async () => {
const port = process.env.PORT || 3000;
await app.start(port);
console.log(`⚡️ reacting-app is running on port ${port}`);
})();
Thanks for checking out this guide! You can view the code for this project on my GitHub.
Also published here.