Slack

Socket-Modus (Standard)

Schnelleinrichtung (Einsteiger)

  1. Erstelle eine Slack-App und aktiviere den Socket Mode.
  2. Erstelle einen App Token (xapp-...) und Bot Token (xoxb-...).
  3. Setze die Tokens für OpenClaw und starte das Gateway.

Minimale Konfiguration:

{
  channels: {
    slack: {
      enabled: true,
      appToken: "xapp-...",
      botToken: "xoxb-...",
    },
  },
}

Einrichtung

  1. Erstelle eine Slack-App (From scratch) unter https://api.slack.com/apps.
  2. Socket Mode → aktivieren. Dann gehe zu Basic InformationApp-Level TokensGenerate Token and Scopes mit Scope connections:write. Kopiere den App Token (xapp-...).
  3. OAuth & Permissions → füge Bot Token Scopes hinzu (nutze das Manifest unten). Klicke auf Install to Workspace. Kopiere den Bot User OAuth Token (xoxb-...).
  4. Optional: OAuth & Permissions → füge User Token Scopes hinzu (siehe Read-Only-Liste unten). Installiere die App neu und kopiere den User OAuth Token (xoxp-...).
  5. Event Subscriptions → aktiviere Events und abonniere:
    • message.* (beinhaltet Edits/Deletes/Thread-Broadcasts)
    • app_mention
    • reaction_added, reaction_removed
    • member_joined_channel, member_left_channel
    • channel_rename
    • pin_added, pin_removed
  6. Lade den Bot in die Channels ein, die er lesen soll.
  7. Slash Commands → erstelle /openclaw, wenn du channels.slack.slashCommand nutzt. Bei aktivierten nativen Commands füge einen Slash Command pro eingebautem Command hinzu (gleiche Namen wie in /help). Native ist standardmäßig für Slack deaktiviert, außer du setzt channels.slack.commands.native: true (global ist commands.native auf "auto", was Slack deaktiviert lässt).
  8. App Home → aktiviere den Messages Tab, damit Nutzer dem Bot DMs schicken können.

Nutze das Manifest unten, damit Scopes und Events synchron bleiben.

Multi-Account-Support: Verwende channels.slack.accounts mit Account-spezifischen Tokens und optionalem name. Siehe gateway/configuration für das gemeinsame Muster.

OpenClaw-Konfiguration (minimal)

Setze Tokens über Umgebungsvariablen (empfohlen):

  • SLACK_APP_TOKEN=xapp-...
  • SLACK_BOT_TOKEN=xoxb-...

Oder über die Konfiguration:

{
  channels: {
    slack: {
      enabled: true,
      appToken: "xapp-...",
      botToken: "xoxb-...",
    },
  },
}

User Token (optional)

OpenClaw kann einen Slack User Token (xoxp-...) für Leseoperationen nutzen (History, Pins, Reactions, Emoji, Member-Info). Standardmäßig bleibt dieser Read-Only: Leseoperationen bevorzugen den User Token, wenn vorhanden, und Schreiboperationen nutzen weiterhin den Bot Token, außer du aktivierst es explizit. Selbst mit userTokenReadOnly: false wird der Bot Token für Schreiboperationen bevorzugt, wenn er verfügbar ist.

User Tokens werden in der Konfigurationsdatei gesetzt (keine Umgebungsvariablen-Unterstützung). Für Multi-Account setze channels.slack.accounts.<id>.userToken.

Beispiel mit Bot + App + User Tokens:

{
  channels: {
    slack: {
      enabled: true,
      appToken: "xapp-...",
      botToken: "xoxb-...",
      userToken: "xoxp-...",
    },
  },
}

Beispiel mit explizit gesetztem userTokenReadOnly (User Token Writes erlauben):

{
  channels: {
    slack: {
      enabled: true,
      appToken: "xapp-...",
      botToken: "xoxb-...",
      userToken: "xoxp-...",
      userTokenReadOnly: false,
    },
  },
}

Token-Verwendung

  • Leseoperationen (History, Reactions-Liste, Pins-Liste, Emoji-Liste, Member-Info, Suche) bevorzugen den User Token, wenn konfiguriert, sonst den Bot Token.
  • Schreiboperationen (Nachrichten senden/bearbeiten/löschen, Reactions hinzufügen/entfernen, Pin/Unpin, Datei-Uploads) nutzen standardmäßig den Bot Token. Bei userTokenReadOnly: false und fehlendem Bot Token fällt OpenClaw auf den User Token zurück.

History Context

  • channels.slack.historyLimit (oder channels.slack.accounts.*.historyLimit) steuert, wie viele aktuelle Channel-/Gruppennachrichten in den Prompt eingebunden werden.
  • Fällt zurück auf messages.groupChat.historyLimit. Setze 0 zum Deaktivieren (Standard 50).

HTTP-Modus (Events API)

Nutze den HTTP-Webhook-Modus, wenn dein Gateway von Slack über HTTPS erreichbar ist (typisch für Server-Deployments). Der HTTP-Modus verwendet die Events API + Interactivity + Slash Commands mit einer gemeinsamen Request-URL.

Einrichtung

  1. Erstelle eine Slack-App und deaktiviere Socket Mode (optional, wenn du nur HTTP nutzt).
  2. Basic Information → kopiere das Signing Secret.
  3. OAuth & Permissions → installiere die App und kopiere den Bot User OAuth Token (xoxb-...).
  4. Event Subscriptions → aktiviere Events und setze die Request URL auf deinen Gateway-Webhook-Pfad (Standard /slack/events).
  5. Interactivity & Shortcuts → aktiviere und setze dieselbe Request URL.
  6. Slash Commands → setze dieselbe Request URL für deine Command(s).

Beispiel Request-URL: https://gateway-host/slack/events

OpenClaw-Konfiguration (minimal)

{
  channels: {
    slack: {
      enabled: true,
      mode: "http",
      botToken: "xoxb-...",
      signingSecret: "your-signing-secret",
      webhookPath: "/slack/events",
    },
  },
}

Multi-Account HTTP-Modus: Setze channels.slack.accounts.<id>.mode = "http" und gib einen eindeutigen webhookPath pro Account an, damit jede Slack-App auf ihre eigene URL zeigen kann.

Manifest (optional)

Nutze dieses Slack-App-Manifest, um die App schnell zu erstellen (passe Name/Command nach Bedarf an). Füge die User Scopes hinzu, wenn du einen User Token konfigurieren möchtest.

{
  "display_information": {
    "name": "OpenClaw",
    "description": "Slack connector for OpenClaw"
  },
  "features": {
    "bot_user": {
      "display_name": "OpenClaw",
      "always_online": false
    },
    "app_home": {
      "messages_tab_enabled": true,
      "messages_tab_read_only_enabled": false
    },
    "slash_commands": [
      {
        "command": "/openclaw",
        "description": "Send a message to OpenClaw",
        "should_escape": false
      }
    ]
  },
  "oauth_config": {
    "scopes": {
      "bot": [
        "chat:write",
        "channels:history",
        "channels:read",
        "groups:history",
        "groups:read",
        "groups:write",
        "im:history",
        "im:read",
        "im:write",
        "mpim:history",
        "mpim:read",
        "mpim:write",
        "users:read",
        "app_mentions:read",
        "reactions:read",
        "reactions:write",
        "pins:read",
        "pins:write",
        "emoji:read",
        "commands",
        "files:read",
        "files:write"
      ],
      "user": [
        "channels:history",
        "channels:read",
        "groups:history",
        "groups:read",
        "im:history",
        "im:read",
        "mpim:history",
        "mpim:read",
        "users:read",
        "reactions:read",
        "pins:read",
        "emoji:read",
        "search:read"
      ]
    }
  },
  "settings": {
    "socket_mode_enabled": true,
    "event_subscriptions": {
      "bot_events": [
        "app_mention",
        "message.channels",
        "message.groups",
        "message.im",
        "message.mpim",
        "reaction_added",
        "reaction_removed",
        "member_joined_channel",
        "member_left_channel",
        "channel_rename",
        "pin_added",
        "pin_removed"
      ]
    }
  }
}

Bei aktivierten nativen Commands füge einen slash_commands-Eintrag pro Command hinzu, den du bereitstellen möchtest (passend zur /help-Liste). Überschreibe mit channels.slack.commands.native.

Scopes (aktuell vs. optional)

Slacks Conversations API ist typ-spezifisch: Du brauchst nur die Scopes für die Konversationstypen, die du tatsächlich nutzt (channels, groups, im, mpim). Siehe https://docs.slack.dev/apis/web-api/using-the-conversations-api/ für die Übersicht.

Bot Token Scopes (erforderlich)

User Token Scopes (optional, standardmäßig Read-Only)

Füge diese unter User Token Scopes hinzu, wenn du channels.slack.userToken konfigurierst.

  • channels:history, groups:history, im:history, mpim:history
  • channels:read, groups:read, im:read, mpim:read
  • users:read
  • reactions:read
  • pins:read
  • emoji:read
  • search:read

Aktuell nicht benötigt (aber wahrscheinlich zukünftig)

Konfiguration

Slack nutzt nur Socket Mode (kein HTTP-Webhook-Server). Gib beide Tokens an:

{
  "slack": {
    "enabled": true,
    "botToken": "xoxb-...",
    "appToken": "xapp-...",
    "groupPolicy": "allowlist",
    "dm": {
      "enabled": true,
      "policy": "pairing",
      "allowFrom": ["U123", "U456", "*"],
      "groupEnabled": false,
      "groupChannels": ["G123"],
      "replyToMode": "all"
    },
    "channels": {
      "C123": { "allow": true, "requireMention": true },
      "#general": {
        "allow": true,
        "requireMention": true,
        "users": ["U123"],
        "skills": ["search", "docs"],
        "systemPrompt": "Keep answers short."
      }
    },
    "reactionNotifications": "own",
    "reactionAllowlist": ["U123"],
    "replyToMode": "off",
    "actions": {
      "reactions": true,
      "messages": true,
      "pins": true,
      "memberInfo": true,
      "emojiList": true
    },
    "slashCommand": {
      "enabled": true,
      "name": "openclaw",
      "sessionPrefix": "slack:slash",
      "ephemeral": true
    },
    "textChunkLimit": 4000,
    "mediaMaxMb": 20
  }
}

Tokens können auch über Umgebungsvariablen bereitgestellt werden:

  • SLACK_BOT_TOKEN
  • SLACK_APP_TOKEN

Ack-Reactions werden global über messages.ackReaction + messages.ackReactionScope gesteuert. Nutze messages.removeAckAfterReply, um die Ack-Reaction nach der Bot-Antwort zu entfernen.

Limits

  • Ausgehender Text wird auf channels.slack.textChunkLimit aufgeteilt (Standard 4000).
  • Optionales Newline-Chunking: Setze channels.slack.chunkMode="newline", um bei Leerzeilen (Absatzgrenzen) vor dem Längen-Chunking zu splitten.
  • Medien-Uploads sind auf channels.slack.mediaMaxMb begrenzt (Standard 20).

Reply Threading

Standardmäßig antwortet OpenClaw im Haupt-Channel. Nutze channels.slack.replyToMode, um automatisches Threading zu steuern:

ModusVerhalten
offStandard. Antwort im Haupt-Channel. Nur Thread, wenn die auslösende Nachricht bereits in einem Thread war.
firstErste Antwort geht in Thread (unter der auslösenden Nachricht), nachfolgende Antworten in den Haupt-Channel. Nützlich, um Kontext sichtbar zu halten und Thread-Clutter zu vermeiden.
allAlle Antworten gehen in Thread. Hält Konversationen zusammen, kann aber Sichtbarkeit reduzieren.

Der Modus gilt sowohl für Auto-Replies als auch für Agent Tool Calls (slack sendMessage).

Per-Chat-Type Threading

Du kannst unterschiedliches Threading-Verhalten pro Chat-Typ konfigurieren, indem du channels.slack.replyToModeByChatType setzt:

{
  channels: {
    slack: {
      replyToMode: "off", // Standard für Channels
      replyToModeByChatType: {
        direct: "all", // DMs immer im Thread
        group: "first", // Group-DMs/MPIM threaden erste Antwort
      },
    },
  },
}

Unterstützte Chat-Typen:

  • direct: 1:1-DMs (Slack im)
  • group: Group-DMs / MPIMs (Slack mpim)
  • channel: Standard-Channels (öffentlich/privat)

Priorität:

  1. replyToModeByChatType.<chatType>
  2. replyToMode
  3. Provider-Standard (off)

Legacy channels.slack.dm.replyToMode wird noch als Fallback für direct akzeptiert, wenn kein Chat-Type-Override gesetzt ist.

Beispiele:

Nur DMs im Thread:

{
  channels: {
    slack: {
      replyToMode: "off",
      replyToModeByChatType: { direct: "all" },
    },
  },
}

Group-DMs im Thread, aber Channels in der Root:

{
  channels: {
    slack: {
      replyToMode: "off",
      replyToModeByChatType: { group: "first" },
    },
  },
}

Channels im Thread, DMs in der Root:

{
  channels: {
    slack: {
      replyToMode: "first",
      replyToModeByChatType: { direct: "off", group: "off" },
    },
  },
}

Manuelle Threading-Tags

Für feinkörnige Kontrolle nutze diese Tags in Agent-Antworten:

  • [[reply_to_current]] — Antwort auf die auslösende Nachricht (Thread starten/fortsetzen).
  • [[reply_to:<id>]] — Antwort auf eine bestimmte Nachrichten-ID.

Sessions + Routing

  • DMs teilen sich die main-Session (wie WhatsApp/Telegram).
  • Channels werden auf agent:<agentId>:slack:channel:<channelId>-Sessions gemappt.
  • Slash Commands nutzen agent:<agentId>:slack:slash:<userId>-Sessions (Präfix konfigurierbar via channels.slack.slashCommand.sessionPrefix).
  • Wenn Slack keinen channel_type liefert, leitet OpenClaw ihn vom Channel-ID-Präfix ab (D, C, G) und nutzt standardmäßig channel, um Session-Keys stabil zu halten.
  • Native Command-Registrierung nutzt commands.native (globaler Standard "auto" → Slack aus) und kann pro Workspace mit channels.slack.commands.native überschrieben werden. Text-Commands benötigen eigenständige /...-Nachrichten und können mit commands.text: false deaktiviert werden. Slack Slash Commands werden in der Slack-App verwaltet und nicht automatisch entfernt. Nutze commands.useAccessGroups: false, um Access-Group-Checks für Commands zu umgehen.
  • Vollständige Command-Liste + Konfiguration: Slash Commands

DM-Sicherheit (Pairing)

  • Standard: channels.slack.dm.policy="pairing" — unbekannte DM-Absender erhalten einen Pairing-Code (läuft nach 1 Stunde ab).
  • Freigabe via: openclaw pairing approve slack <code>.
  • Um jeden zuzulassen: Setze channels.slack.dm.policy="open" und channels.slack.dm.allowFrom=["*"].
  • channels.slack.dm.allowFrom akzeptiert User-IDs, @handles oder E-Mails (beim Start aufgelöst, wenn Tokens es erlauben). Der Wizard akzeptiert Usernames und löst sie während des Setups zu IDs auf, wenn Tokens es erlauben.

Group Policy

  • channels.slack.groupPolicy steuert Channel-Handling (open|disabled|allowlist).
  • allowlist erfordert, dass Channels in channels.slack.channels aufgelistet sind.
  • Wenn du nur SLACK_BOT_TOKEN/SLACK_APP_TOKEN setzt und nie eine channels.slack-Sektion erstellst, setzt die Runtime groupPolicy standardmäßig auf open. Füge channels.slack.groupPolicy, channels.defaults.groupPolicy oder eine Channel-Allowlist hinzu, um es zu sperren.
  • Der Konfigurations-Wizard akzeptiert #channel-Namen und löst sie zu IDs auf, wenn möglich (öffentlich + privat); bei mehreren Treffern bevorzugt er den aktiven Channel.
  • Beim Start löst OpenClaw Channel-/User-Namen in Allowlists zu IDs auf (wenn Tokens es erlauben) und loggt das Mapping; nicht aufgelöste Einträge werden wie eingegeben behalten.
  • Um keine Channels zuzulassen, setze channels.slack.groupPolicy: "disabled" (oder behalte eine leere Allowlist).

Channel-Optionen (channels.slack.channels.<id> oder channels.slack.channels.<name>):

  • allow: Channel erlauben/verweigern, wenn groupPolicy="allowlist".
  • requireMention: Mention-Gating für den Channel.
  • tools: Optionale Channel-spezifische Tool-Policy-Overrides (allow/deny/alsoAllow).
  • toolsBySender: Optionale Sender-spezifische Tool-Policy-Overrides innerhalb des Channels (Keys sind Sender-IDs/@handles/E-Mails; "*"-Wildcard unterstützt).
  • allowBots: Bot-verfasste Nachrichten in diesem Channel erlauben (Standard: false).
  • users: Optionale Channel-spezifische User-Allowlist.
  • skills: Skill-Filter (weglassen = alle Skills, leer = keine).
  • systemPrompt: Extra System-Prompt für den Channel (kombiniert mit Topic/Purpose).
  • enabled: Setze false, um den Channel zu deaktivieren.

Delivery Targets

Nutze diese mit Cron/CLI-Sends:

  • user:<id> für DMs
  • channel:<id> für Channels

Tool Actions

Slack Tool Actions können mit channels.slack.actions.* gesteuert werden:

Action-GruppeStandardHinweise
reactionsaktiviertReact + Reactions auflisten
messagesaktiviertLesen/Senden/Bearbeiten/Löschen
pinsaktiviertPin/Unpin/Auflisten
memberInfoaktiviertMember-Info
emojiListaktiviertCustom-Emoji-Liste

Sicherheitshinweise

  • Schreiboperationen nutzen standardmäßig den Bot Token, damit zustandsändernde Aktionen auf die Bot-Berechtigungen und -Identität der App beschränkt bleiben.
  • Das Setzen von userTokenReadOnly: false erlaubt die Verwendung des User Tokens für Schreiboperationen, wenn kein Bot Token verfügbar ist, was bedeutet, dass Aktionen mit dem Zugriff des installierenden Users laufen. Behandle den User Token als hochprivilegiert und halte Action-Gates und Allowlists eng.
  • Wenn du User-Token-Writes aktivierst, stelle sicher, dass der User Token die erwarteten Write-Scopes enthält (chat:write, reactions:write, pins:write, files:write), sonst schlagen diese Operationen fehl.

Hinweise

  • Mention-Gating wird über channels.slack.channels gesteuert (setze requireMention auf true); agents.list[].groupChat.mentionPatterns (oder messages.groupChat.mentionPatterns) zählen ebenfalls als Mentions.
  • Multi-Agent-Override: Setze Agent-spezifische Patterns auf agents.list[].groupChat.mentionPatterns.
  • Reaction-Benachrichtigungen folgen channels.slack.reactionNotifications (nutze reactionAllowlist mit Modus allowlist).
  • Bot-verfasste Nachrichten werden standardmäßig ignoriert; aktiviere via channels.slack.allowBots oder channels.slack.channels.<id>.allowBots.
  • Warnung: Wenn du Antworten auf andere Bots erlaubst (channels.slack.allowBots=true oder channels.slack.channels.<id>.allowBots=true), verhindere Bot-zu-Bot-Reply-Loops mit requireMention, channels.slack.channels.<id>.users-Allowlists und/oder klaren Leitplanken in AGENTS.md und SOUL.md.
  • Für das Slack-Tool sind Reaction-Removal-Semantiken in /tools/reactions beschrieben.
  • Anhänge werden in den Media-Store heruntergeladen, wenn erlaubt und unter dem Größenlimit.