You are browsing as a guest. Sign up (or log in) to start making projects!

← Mission home

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

  1. Go to the Slack Apps dashboard: https://api.slack.com/apps and click Create New App → From scratch.
  2. Give it a name and pick the Hack Club workspace.
  3. 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.

  1. Open the Socket Mode page in your app’s left sidebar.
  2. Toggle Enable Socket Mode on.

Image

Socket Mode needs an App-Level Token with the connections:write scope:

  1. Open Basic Information in the left sidebar.
    Image
  2. Scroll to App-Level Tokens and click Generate Token and Scopes.
    Image
  3. Give the token a name (e.g. my-bot-socket) and add the connections:write scope.
    Image
  4. Click Generate and copy the token immediately. App-level tokens start with xapp-.
    Image

3. Set bot scopes

Scopes tell Slack what your bot is allowed to do.

  1. Open OAuth & Permissions in the left sidebar.
    Image

  2. Under Bot Token Scopes, add:
    Image

    chat:write
    commands
    app_mentions:read
    channels:history
    

    These 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

  1. Go to Install App in the left sidebar and click Install to Workspace.
  2. Grant permissions.
    Image
  3. Back on OAuth & Permissions, you’ll see the Bot User OAuth Token (starts with xoxb-). Copy and save it.
    Image

5. Add a slash command

  1. Open Slash Commands in the left sidebar and click Create New Command.
    Image
  2. Enter a command name like /dsb-ping and provide a short description and usage hint.
  3. Click Save.

Where to find tokens later

If you lose a token, you can always go back:

  • App-Level Token (xapp-)Basic InformationApp-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

  1. Create a new folder for your project and open it in VS Code.

  2. Open the integrated terminal with Terminal → New Terminal so commands run inside the project folder.

  3. 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.

image

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`
  });
});

Example

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." });
  }
});

Example

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:

  1. User runs a slash command
  2. The bot receives the command
  3. The bot sends a request to an API
  4. The API returns data
  5. The bot sends that data back into Slack

The common ingredients:

  • axios — to make API requests
  • try/catch — to prevent crashes if the API fails
  • respond() — 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.

  1. Create a new (empty) repository on GitHub.

  2. 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

  1. Make sure you have a Nest account (see the Nest Quickstart Guide if you’re unsure how to log in).
  2. 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.

  1. Create a service file:

    nano /etc/systemd/system/slackbot.service
    
  2. Paste this in (edit WorkingDirectory to 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.target
    

    Save and exit (Ctrl+S, Ctrl+X).

  3. 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 in SLACK_BOT_TOKEN and xapp- is in SLACK_APP_TOKEN.
  • Missing .env — the file lives on the server now, not in your repo.
  • Wrong working directory — the WorkingDirectory= line in slackbot.service must point to the absolute path of your project on Nest.
  • Missing dependencies — re-run npm install inside 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