How to Build a Slack Bot Like Doraemon

Last time, I shared the personal story behind Doraemon — a Slack bot that started as a hackathon idea and eventually found its way back into my hands.
This time, I want to switch gears and focus on the practical side: how to actually build a Slack bot like Doraemon, from setting up the app to running it locally.
No theory, no shortcuts — just the steps that worked.
What You’re Building
A Slack bot that:
- Runs in Socket Mode (no public HTTP endpoint required)
- Responds to messages and mentions (for example:
hi @doraemon) - Uses a clean, handler-based structure
- Can run locally and later be containerized or deployed to Kubernetes
This is meant to be useful, not clever.
1) Create a Slack App
- Go to https://api.slack.com/apps
- Click Create New App
- Choose From scratch
- Give it a name (for example:
doraemon) - Select your workspace
2) Copy the IDs and Secrets
In Basic Information, copy and store the following values:
- App ID
- Client ID
- Client Secret
- Signing Secret
- Verification Token
Treat these like credentials. Don’t commit them or hardcode them.
3) OAuth & Permissions
Open OAuth & Permissions and add these scopes:
- app_mentions:read
- channels:history
- channels:join
- chat:write
- commands
- incoming-webhook
- pins:read
- reactions:read
- reactions:write
Scroll back to the top and click Install to Workspace.
After installation, copy the Bot User OAuth Token:
xoxb-...
4) Enable Socket Mode
Socket Mode avoids inbound HTTP traffic and is ideal for internal tools.
- Go to Socket Mode
- Turn it ON
- Click Generate App Token
- Name it (for example:
doraemon-token) - Add scope:
connections:write
- Name it (for example:
- Copy the token:
xapp-1-...
5) Run It Locally
Prerequisites
- Python 3.11
- Two environment variables:
SLACK_BOT_TOKEN=xoxb-...SLACK_APP_TOKEN=xapp-...
Install and start
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
export SLACK_BOT_TOKEN="xoxb-your-token"
export SLACK_APP_TOKEN="xapp-your-token"
python app.py
If everything is wired correctly, the process will stay running and you’ll see logs as Slack events arrive.
6) Test It in Slack
Invite the bot to a channel:
/invite @doraemon
Then test it:
hi @doraemon
You should receive a threaded reply:
Hello <@you>! 👋
You can also DM the bot and type hi.
Code Wireframe (Minimal, Working Shape)
requirements.txt
slack_bolt
slack_sdk
PyYAML
PyJWT
PyJWT[crypto]
requests
packaging
Suggested layout
.
├── app.py
├── requirements.txt
├── handlers/
│ └── greeting.py
└── utils/
└── logger.py
handlers/greeting.py
import re
from utils.logger import logger
GREETINGS = {"hi", "hello"}
def handle(event, say):
text = event.get("text", "").lower().strip()
user = event.get("user")
thread_ts = event.get("thread_ts") or event.get("ts")
if any(text == g or text.startswith(g + " ") for g in GREETINGS):
logger.info(f"Greeting received from {user}")
say(f"Hello <@{user}>! 👋", thread_ts=thread_ts)
app.py
import os
from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler
from handlers import greeting
from utils.logger import setup_logger
setup_logger()
SLACK_BOT_TOKEN = os.environ.get("SLACK_BOT_TOKEN")
SLACK_APP_TOKEN = os.environ.get("SLACK_APP_TOKEN")
app = App(token=SLACK_BOT_TOKEN)
@app.event("message")
@app.event("app_mention")
def handle_all_messages(event, say):
greeting.handle(event, say)
if __name__ == "__main__":
SocketModeHandler(app, SLACK_APP_TOKEN).start()
utils/logger.py
import logging
logger = logging.getLogger("doraemon")
def setup_logger():
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
)
Dockerfile
FROM python:3.11.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt && pip check
COPY app.py .
CMD ["python", "app.py"]
At this point, you have a Slack bot that responds, logs what it’s doing, and runs cleanly on your machine. You can talk to it in a channel, mention it directly, or DM it — and more importantly, you now have a structure that won’t fight you as it grows.
Start small. Let real usage guide what you add next.