Slack is the communication hub for many companies. With custom bots, you can send notifications, query data, and trigger workflows directly from Slack. The best part: you don't need programming skills. In this guide, we show you how to create a working Slack bot in 30 minutes. If you use Microsoft Teams instead, check out our Teams bot setup guide. For Telegram, see our Telegram bot tutorial.
Why Create a Slack Bot?
Typical Use Cases:
| Use Case | Description |
|---|---|
| Alerts | Server monitoring, sales notifications |
| Status queries | "/status" shows system status |
| Approvals | Vacation requests, expense approvals |
| Daily standups | Automatic reminders + collection |
| Onboarding | Welcome new employees |
Benefits:
- Right in the work context
- Interactive buttons and dialogs
- No app switching needed
Creating a Slack Bot: Step by Step
Step 1: Create Slack App
Step 2: Add Bot User
- chat:write (send messages)
- commands (slash commands)
- users:read (read user info)
Step 3: Install App
xoxb-...Step 4: Invite Bot to Channel
/invite @automation-bot
Method 1: Incoming Webhooks (Simplest)
For sending messages only - no interaction.
Set Up Webhook
Send Message (n8n)
// Node: HTTP Request
{
"method": "POST",
"url": "https://hooks.slack.com/services/T00/B00/xxxx",
"headers": { "Content-Type": "application/json" },
"body": {
"text": "Hello from n8n!"
}
}
Formatted Messages
{
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "New Order!"
}
},
{
"type": "section",
"fields": [
{ "type": "mrkdwn", "text": "*Customer:*\nJohn Smith" },
{ "type": "mrkdwn", "text": "*Amount:*\n$149.00" }
]
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": { "type": "plain_text", "text": "View in Shop" },
"url": "https://shop.example.com/orders/123"
}
]
}
]
}
Method 2: Slack API (Full-Featured)
For all functions: sending, receiving, interactions.
n8n Slack Node
xoxb-...Send Message:
// Node: Slack
{
"operation": "send",
"channel": "#alerts",
"text": "Important notification!",
"attachments": [
{
"color": "#36a64f",
"title": "Server Status",
"text": "All systems running normally"
}
]
}
Method 3: Slash Commands
User types /command and your bot responds.
Set Up Slash Command
/statushttps://n8n.your-domain.com/webhook/slack-statusn8n Workflow
Webhook (POST /slack-status)
↓
Retrieve system status
↓
Return formatted response
Node: Webhook
// Slack sends:
{
"command": "/status",
"text": "", // Parameters after the command
"user_id": "U12345",
"user_name": "john.smith",
"channel_id": "C12345"
}
Node: Respond
// Response to Slack
{
"response_type": "in_channel", // Visible to everyone
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*System Status*\nAPI: Online\nDatabase: Online\nQueue: 5 Jobs"
}
}
]
}
Method 4: Interactive Buttons
User clicks button and your bot reacts.
Activate Interactivity
https://n8n.your-domain.com/webhook/slack-interactiveMessage with Buttons
{
"channel": "#approvals",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Vacation Request*\n\nJohn Smith wants to take vacation from Jan 15-20."
}
},
{
"type": "actions",
"block_id": "approval_buttons",
"elements": [
{
"type": "button",
"text": { "type": "plain_text", "text": "Approve" },
"style": "primary",
"action_id": "approve",
"value": "request_123"
},
{
"type": "button",
"text": { "type": "plain_text", "text": "Reject" },
"style": "danger",
"action_id": "reject",
"value": "request_123"
}
]
}
]
}
Process Button Click
// Node: Webhook - Slack sends on click:
{
"type": "block_actions",
"user": { "id": "U12345", "name": "manager" },
"actions": [
{
"action_id": "approve",
"value": "request_123"
}
],
"response_url": "https://hooks.slack.com/actions/..."
}
// Response: Update original message
{
"method": "POST",
"url": "{{ $json.response_url }}",
"body": {
"replace_original": true,
"text": "Vacation request approved by @manager"
}
}
Practical Examples
1. Server Monitoring Bot
Uptime Robot (Server Down)
↓
Slack #ops-alerts:
"Server XYZ is offline!"
[Open Dashboard] [Acknowledge]
2. Daily Standup Bot
Schedule (Mon-Fri 9:00 AM)
↓
Slack #team:
"Time for the daily standup!
What did you do yesterday?
What are you doing today?
Any blockers?"
↓
Collect replies (1h)
↓
Summary in Notion
3. Lead Notification Bot
Website form (new lead)
↓
Slack #sales:
"New Lead!
John Smith
Acme Inc.
john@acme.com
[Open in CRM] [Call]"
4. Expense Approval Bot
Employee submits expense
↓
Slack DM to manager:
"Expense for approval
Amount: $250
Category: Software
Description: Figma annual subscription
[Approve] [Reject] [Ask Question]"
Make.com: Slack Modules
Available Modules
| Module | Function |
|---|---|
| Watch Events | Trigger on messages |
| Send Message | Send message |
| Update Message | Edit message |
| Create Channel | Create channel |
| Invite User | Invite user |
| Upload File | Upload file |
Example Scenario
Slack (Watch Events)
↓
Filter: Contains "help"
↓
OpenAI: Generate response
↓
Slack: Send reply
Advanced: Event Subscriptions
For real-time events (not just commands).
Activate Events
https://n8n.your-domain.com/webhook/slack-events - message.channels (messages in channels)
- app_mention (bot was mentioned)
- member_joined_channel (user joins)
URL Verification
Slack sends a challenge request:
// Node: Code - Answer challenge
if ($json.type === 'url_verification') {
return {
json: { challenge: $json.challenge }
};
}
// Process normal events
return $json;
React to @Mention
// Event: app_mention
{
"type": "event_callback",
"event": {
"type": "app_mention",
"user": "U12345",
"text": "<@BOTID> What's the server status?",
"channel": "C12345"
}
}
Block Kit Builder
Slack offers a visual editor for messages:
app.slack.com/block-kit-builder
Components
| Block Type | Usage |
|---|---|
| Header | Headings |
| Section | Text + Fields |
| Divider | Separator line |
| Image | Images |
| Actions | Buttons, Selects |
| Context | Small additional info |
| Input | Form inputs |
Best Practices
1. Don't Spam
// Batch messages
const events = collectEvents(5 * 60 * 1000); // 5 min
if (events.length > 5) {
// Send digest instead of individual messages
sendDigest(events);
} else {
events.forEach(e => sendMessage(e));
}
2. Use Threads
{
"channel": "#alerts",
"text": "Incident: Server Down",
"thread_ts": "{{ $json.original_message_ts }}" // Reply in thread
}
3. Ephemeral Messages
Visible only to one user:
{
"channel": "C12345",
"user": "U12345",
"text": "Only you can see this message"
}
// With: chat.postEphemeral
4. Error Handling
try {
await slack.chat.postMessage({ channel, text });
} catch (error) {
if (error.data?.error === 'channel_not_found') {
// Bot not in channel
await slack.chat.postMessage({
channel: '#fallback',
text: `Could not post in ${channel}`
});
}
}
Costs
Conclusion
Slack bots are powerful tools for team automation:
- Notifications right in the work context
- Interactive approvals
- Slash commands for quick actions
- Event-based automation
Next Steps
A bot is most useful when it carries data from a system people do not open all day -- the HubSpot to Slack integration is the version of this we get asked for most. We support you with Slack automation - from setup to a productive bot. Contact us for a free consultation. For broader automation ideas, see our customer service automation guide.