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 CaseDescription
AlertsServer monitoring, sales notifications
Status queries"/status" shows system status
ApprovalsVacation requests, expense approvals
Daily standupsAutomatic reminders + collection
OnboardingWelcome 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

  1. Go to api.slack.com/apps
  2. "Create New App" → "From scratch"
  3. App Name: e.g., "Automation Bot"
  4. Select Workspace

Step 2: Add Bot User

  1. "OAuth & Permissions" in the sidebar
  2. Under "Scopes" → "Bot Token Scopes":
    • chat:write (send messages)
    • commands (slash commands)
    • users:read (read user info)

Step 3: Install App

  1. Click "Install to Workspace"
  2. Confirm permissions
  3. Copy Bot User OAuth Token: xoxb-...

Step 4: Invite Bot to Channel

/invite @automation-bot

Method 1: Incoming Webhooks (Simplest)

For sending messages only - no interaction.

Set Up Webhook

  1. App Settings → "Incoming Webhooks"
  2. "Activate Incoming Webhooks" → On
  3. "Add New Webhook to Workspace"
  4. Select channel
  5. Copy Webhook URL

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"
        }
      ]
    }
  ]
}

For all functions: sending, receiving, interactions.

n8n Slack Node

  1. Credentials → Slack API
  2. Enter Access Token: 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

  1. App Settings → "Slash Commands"
  2. "Create New Command"
  3. Command: /status
  4. Request URL: https://n8n.your-domain.com/webhook/slack-status
  5. Description: "Shows system status"

n8n 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

  1. App Settings → "Interactivity & Shortcuts"
  2. "Interactivity" → On
  3. Request URL: https://n8n.your-domain.com/webhook/slack-interactive

Message 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

ModuleFunction
Watch EventsTrigger on messages
Send MessageSend message
Update MessageEdit message
Create ChannelCreate channel
Invite UserInvite user
Upload FileUpload 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

  1. App Settings → "Event Subscriptions"
  2. "Enable Events" → On
  3. Request URL: https://n8n.your-domain.com/webhook/slack-events
  4. Subscribe to 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 TypeUsage
HeaderHeadings
SectionText + Fields
DividerSeparator line
ImageImages
ActionsButtons, Selects
ContextSmall additional info
InputForm 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

ComponentCost
Slack BotFree
n8n CloudFrom $20/month
Make.comFrom $9/month

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

  1. Create Slack App at api.slack.com
  2. Set up webhook or API
  3. Send first notification
  4. Add interactivity (buttons, commands)

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.