Problem: Slack Bots Are Painful to Build From Scratch
Writing a Slack bot means OAuth flows, event subscriptions, webhook handlers, token storage, and retry logic — before you write a single line of AI logic.
n8n collapses all of that into a visual workflow. You connect a Slack trigger to an AI node, set a system prompt, and you're done.
You'll learn:
- How to trigger a workflow when a Slack message mentions your bot
- How to call GPT-4o (or Claude) and return the response in the same thread
- How to add memory so the bot tracks conversation history
Time: 20 min | Difficulty: Intermediate
Why n8n Is the Right Tool Here
Building this in raw code requires a Slack app, a server to receive events, a tunneling tool for local dev, and manual OpenAI SDK wiring. n8n handles the transport layer for you.
The Slack trigger node manages event verification, retries, and OAuth. The AI Agent node handles prompt construction and LLM calls. You focus on behavior, not plumbing.
This approach also means the bot is editable without redeployment — change the system prompt in the UI and it takes effect immediately.
Solution
Step 1: Create a Slack App and Enable Events
Go to api.slack.com/apps and click Create New App → From scratch.
Give it a name (e.g., n8n-assistant) and select your workspace.
Under OAuth & Permissions, add these Bot Token Scopes:
app_mentions:read
chat:write
channels:history
im:history
im:read
im:write
Under Event Subscriptions, enable events and subscribe to:
app_mention
message.im
You'll fill in the Request URL in the next step. For now, save and install the app to your workspace.
Copy the Bot User OAuth Token — it starts with xoxb-. You'll need it in n8n.
Step 2: Set Up n8n and Add Slack Credentials
If you don't have n8n running yet:
# Docker — fastest path
docker run -it --rm \
--name n8n \
-p 5678:5678 \
-v ~/.n8n:/home/node/.n8n \
docker.n8n.io/n8nio/n8n
Open http://localhost:5678.
Go to Credentials → New → Slack API and paste your xoxb- token.
For local dev, you also need a public URL so Slack can reach your n8n instance. Use ngrok:
ngrok http 5678
Copy the https://xxxx.ngrok-free.app URL — you'll use it as the Slack event webhook base.
Step 3: Build the Workflow — Slack Trigger
Create a new workflow. Add the first node:
Node type: Slack Trigger
Event: app_mention (and message for DMs if you want both)
n8n will generate a webhook URL like:
https://xxxx.ngrok-free.app/webhook/slack-bot
Paste this into your Slack app's Event Subscriptions → Request URL. Slack will send a verification challenge — n8n handles it automatically.
Test it: Mention your bot in a Slack channel. The trigger node should show incoming data in the "Test output" panel.
The key fields from the trigger payload you'll use downstream:
{{ $json.event.text }} → the message text
{{ $json.event.channel }} → channel ID to reply to
{{ $json.event.thread_ts }} → thread timestamp (for threaded replies)
{{ $json.event.user }} → Slack user ID of the sender
Step 4: Add an AI Agent Node
Add the next node: AI Agent
Configure it:
- Model: OpenAI GPT-4o (or select Anthropic Claude if you prefer)
- System Prompt:
You are a helpful assistant in a Slack workspace.
Keep responses concise — under 200 words unless the user asks for detail.
Use plain text, not markdown. Slack renders its own formatting.
Never start your reply with "Sure!" or "Of course!".
- User Message:
{{ $json.event.text }}
Connect your OpenAI credential (or Anthropic). Under Credentials → New → OpenAI, paste your API key.
Expected output from this node:
{
"output": "Here's what I found about your question..."
}
Step 5: Send the Reply Back to Slack
Add a Slack node to post the response.
Configure it:
- Operation: Send a message
- Channel:
{{ $('Slack Trigger').item.json.event.channel }} - Message:
{{ $json.output }} - Thread Timestamp:
{{ $('Slack Trigger').item.json.event.thread_ts }}
Setting thread_ts makes replies land in the same thread as the original message, which keeps channels clean.
If it fails:
channel_not_found→ The bot hasn't been invited to the channel. Run/invite @n8n-assistantin Slack.not_in_channel→ Same fix as above.missing_scope→ Check OAuth scopes in your Slack app;chat:writeis required.
Step 6: Add Conversation Memory (Optional but Recommended)
Without memory, the bot treats every message as a fresh conversation. To fix this, add a Window Buffer Memory node between the Slack Trigger and AI Agent.
Node type: Window Buffer Memory
Session ID: {{ $('Slack Trigger').item.json.event.user }}
Context Window Length: 10 (last 10 messages per user)
Connect it to the AI Agent node's Memory input.
This stores per-user context in n8n's internal storage. For production, swap the memory node backend to Redis:
# Add to your docker run command
-e N8N_DEFAULT_BINARY_DATA_MODE=filesystem
-e QUEUE_BULL_REDIS_HOST=your-redis-host
Verification
Invite your bot to a Slack channel:
/invite @n8n-assistant
Then mention it:
@n8n-assistant what's the capital of Vietnam?
You should see: A reply in the same thread within 3–5 seconds.
Test memory by following up without re-mentioning context:
@n8n-assistant and what's the population there?
The bot should answer correctly because it retains the previous turn.
To confirm the workflow ran, open n8n and check Executions — each Slack message creates one execution entry with full input/output logs.
What You Learned
- n8n handles Slack OAuth and event verification — you only configure, not code
- The
thread_tsparameter is what keeps bot replies threaded correctly - Window Buffer Memory uses Slack user ID as session key — one memory context per user
- For production, replace ngrok with a real webhook URL on a hosted n8n instance
Limitation: This bot responds to every mention, including bot messages in some Slack setups. Add a filter node after the trigger to skip messages where {{ $json.event.bot_id }} is not empty, preventing infinite loops if your bot ever messages itself.
Tested on n8n 1.82, GPT-4o (2025-04-01), Slack API v2, Docker on Ubuntu 24.04