Make a Slack Bot
Introduction
Ever wanted to have your own Slack bot which responds to your commands, automates your tasks, and other stuff in Hack Club? In this guide, you will learn how to:
- Create a Slack app
- Build a Slack bot using JavaScript
- Add slash commands such as
/ping - Deploy your bot in Hack Club Nest for free
- Keep your bot online 24/7
This guide assumes no JavaScript experience. If you want a short intro to JavaScript first, read MDN’s friendly overview: MDN JavaScript Introduction
The stack we’ll use:
- JavaScript (no prior coding required)
- Node.js
- Slack Bolt
- Socket Mode
- Nest @ Hack Club
By the end of this tutorial you’ll have your own fully hosted Slack bot.
What you'll need
Before you start, gather these things:
- A Hack Club Slack account
- A GitHub account (for publishing your code)
- A Hack Club Nest account (used for hosting — see notes below about applying)
- Node.js and npm installed locally
- A code editor — VS Code is recommended
What we’re building
A Slack bot that responds to slash commands. A slash command is a command you type starting with a slash — for example:
/dsb-ping
/dsb-hello
/dsb-status
When a user runs one of these commands, the bot can show information, send messages, run automations, hit APIs, run workflows, and more. If you make a command like /dsb-joke, you can have the bot fetch a joke from an API and send it in the channel.
Set up your Slack app
Before you can write any code, you need to register your bot with Slack and grab the tokens it’ll use to authenticate.
1. Create the app
- Go to the Slack Apps dashboard: https://api.slack.com/apps and click Create New App → From scratch.
- Give it a name and pick the Hack Club workspace.
- Click Create App.
2. Enable Socket Mode
Socket Mode lets your bot talk to Slack over a WebSocket so you don’t need a public URL.
- Open the Socket Mode page in your app’s left sidebar.
- Toggle Enable Socket Mode on.

Socket Mode needs an App-Level Token with the connections:write scope:
- Open Basic Information in the left sidebar.

- Scroll to App-Level Tokens and click Generate Token and Scopes.

- Give the token a name (e.g.
my-bot-socket) and add theconnections:writescope.

- Click Generate and copy the token immediately. App-level tokens start with
xapp-.

3. Set bot scopes
Scopes tell Slack what your bot is allowed to do.
-
Open OAuth & Permissions in the left sidebar.

-
Under Bot Token Scopes, add:

chat:write commands app_mentions:read channels:historyThese permissions let your bot send messages, use slash commands, read mentions, and access channel messages. You can always add more later.
4. Install the app to your workspace
- Go to Install App in the left sidebar and click Install to Workspace.
- Grant permissions.

- Back on OAuth & Permissions, you’ll see the Bot User OAuth Token (starts with
xoxb-). Copy and save it.

5. Add a slash command
- Open Slash Commands in the left sidebar and click Create New Command.

- Enter a command name like
/dsb-pingand provide a short description and usage hint. - Click Save.
Where to find tokens later
If you lose a token, you can always go back:
- App-Level Token (
xapp-) — Basic Information → App-Level Tokens → click the token name. - Bot User OAuth Token (
xoxb-) — OAuth & Permissions → look for Bot User OAuth Token after installing the app.
Build the bot locally
Now we’ll create the Node project, drop in the bot code, and run it on your machine.
1. Create the project
-
Create a new folder for your project and open it in VS Code.
-
Open the integrated terminal with Terminal → New Terminal so commands run inside the project folder.
-
Initialize the project and install dependencies:
npm init -y npm install @slack/bolt dotenv
2. Store your tokens in .env
Create a .env file in the project folder and paste your two tokens:
SLACK_BOT_TOKEN=xoxb-... # Bot User OAuth Token (from OAuth & Permissions)
SLACK_APP_TOKEN=xapp-... # App-Level Token (from Basic Information → App-Level Tokens)
Then create a .gitignore so .env never gets committed:
node_modules
.env
3. Write the bot
Create index.js in the project folder and paste this:
require("dotenv").config();
const { App } = require("@slack/bolt");
const app = new App({
token: process.env.SLACK_BOT_TOKEN,
appToken: process.env.SLACK_APP_TOKEN,
socketMode: true
});
app.command("/dsb-ping", async ({ command, ack, respond }) => {
const start = Date.now();
await ack();
const latency = Date.now() - start;
await respond({ text: `Pong!\nLatency: ${latency}ms` });
});
(async () => {
await app.start();
console.log("bot is running!");
})();
4. Run the bot
node index.js
If it works, you’ll see:
bot is running!
Test your slash command in Slack — type /dsb-ping in any channel. The bot should reply with the latency.

How the command code works
app.command("/command-name", async ({ ack, respond }) => {
// your code here
});
| Part | What it does |
|---|---|
app.command() |
Registers a slash command |
"/command-name" |
The command Slack listens for |
async |
Allows asynchronous operations like API calls |
ack() |
Acknowledges the command to Slack |
respond() |
Sends a message back to Slack |
Add more commands
Your bot is up. Now let’s extend it with a help command and a couple of API-backed commands.
Help command
app.command("/dsb-help", async ({ ack, respond }) => {
await ack();
await respond({
text:
`Available Commands:
/dsb-ping - Check bot latency
/dsb-catfact - Get a cat fact`
});
});

Cat fact command (using an API)
To make API requests, install axios:
npm install axios
At the top of index.js, add:
const axios = require("axios");
Then add this command:
app.command("/dsb-catfact", async ({ ack, respond }) => {
await ack();
try {
const response = await axios.get("https://catfact.ninja/fact");
await respond({ text: `Cat Fact:\n${response.data.fact}` });
} catch (err) {
await respond({ text: "Failed to fetch a cat fact." });
}
});

Joke command (one more example)
app.command("/dsb-joke", async ({ ack, respond }) => {
await ack();
try {
const response = await axios.get("https://official-joke-api.appspot.com/random_joke");
await respond({
text:
`${response.data.setup}
${response.data.punchline}`
});
} catch (err) {
await respond({ text: "Failed to fetch a joke." });
}
});
How API commands work
Both the cat fact and joke commands follow the same flow:
- User runs a slash command
- The bot receives the command
- The bot sends a request to an API
- The API returns data
- The bot sends that data back into Slack
The common ingredients:
axios— to make API requeststry/catch— to prevent crashes if the API failsrespond()— to send messages back to Slack
You can repeat this pattern for as many commands as you want. Just remember to register each command in the Slack dashboard too. Browse free-apis.github.io for free APIs to play with.
Push to GitHub
Before deploying, get your code into a GitHub repository.
-
Create a new (empty) repository on GitHub.
-
In your project folder, run:
git init git add . git commit -m "Initial commit" git branch -M main git remote add origin https://github.com/YOUR_USERNAME/YOUR_REPO.git git push -u origin main
Run it 24/7 on Nest
Right now your bot stops the moment you close your terminal. To keep it online 24/7, we’ll deploy it to Nest and run it as a systemd service.
1. SSH into Nest
- Make sure you have a Nest account (see the Nest Quickstart Guide if you’re unsure how to log in).
- SSH into your Nest server with your credentials.
2. Install prerequisites (git, Node.js, npm)
You only need to run this if you have not installed git or node in your container before.
apt update
apt install -y curl git
curl -fsSL https://deb.nodesource.com/setup_24.x | bash -
apt install -y nodejs
2. Clone your repo
Once everything is installed, run:
git clone https://github.com/<your-github-username>/<your-repo-name>
cd <your-repo-name>
npm install
3. Recreate the .env on the server
Your .env isn’t in the repo (we gitignored it), so you need to create it on Nest:
nano .env
Paste in the same SLACK_BOT_TOKEN and SLACK_APP_TOKEN you had locally. To save and exit in nano: press Ctrl+O, then Enter, then Ctrl+X.
Test it runs:
node index.js
Try a slash command in Slack. If the bot responds, kill the process (Ctrl+C) — we’ll set it up to run on its own next.
4. Run as a systemd service
Without systemd your bot will stop when you disconnect SSH, when Nest restarts, or when the process crashes. Systemd keeps it alive.
-
Create a service file:
nano /etc/systemd/system/slackbot.service -
Paste this in (edit
WorkingDirectoryto match your repo name):[Unit] Description=Slack Bot After=network-online.target Wants=network-online.target [Service] Type=simple Restart=always WorkingDirectory=/root/ ExecStart=/usr/bin/node index.js TimeoutStartSec=0 [Install] WantedBy=multi-user.targetSave and exit (
Ctrl+S,Ctrl+X). -
Start it:
systemctl daemon-reload systemctl enable --now slackbot.service
Congratulations — your bot is now running 24/7!
Troubleshooting & next steps
Checking logs
If anything misbehaves on Nest, check the systemd logs:
journalctl --user -u slackbot.service
Common deployment issues
- Wrong token — confirm
xoxb-is inSLACK_BOT_TOKENandxapp-is inSLACK_APP_TOKEN. - Missing
.env— the file lives on the server now, not in your repo. - Wrong working directory — the
WorkingDirectory=line inslackbot.servicemust point to the absolute path of your project on Nest. - Missing dependencies — re-run
npm installinside the project folder on Nest.
Lifecycle commands
Control the running bot from the Nest shell:
systemctl --user start slackbot.service # start
systemctl --user stop slackbot.service # stop
systemctl --user restart slackbot.service # restart
Further reading
Ideas to extend your bot
- Daily standup reporter (posts a summary at 9am)
- Fun facts bot (
/dsb-fact) - Moderation: auto-flag messages with banned words
- Games: trivia bot with score tracking
- Integrations: post GitHub PR updates