#Slack - Multiple apps/bots with multiple Openclaw agents

1 messages · Page 1 of 1 (latest)

quick oreBOT
#

Short answer: yes — OpenClaw supports multiple Slack "accounts" (multiple Slack apps / bot tokens) and you can route them to different agents. Both Socket Mode and HTTP mode are supported (HTTP needs unique webhookPath per account). Your config shape is correct in principle.

Why you see everything go to the default agent

  • That behaviour means the incoming event is being handled as if it belonged to the default account (so ResolveAgentRoute is being called with the default accountId), or the agent binding doesn't match the inbound metadata. In practice the usual causes are:
    1. The gateway never started a monitor for the second account (invalid/missing tokens → only the default account is running).
    2. The token(s) you put for the second account actually belong to the same Slack app/bot as the default account (so events always go to the same app).
    3. The message is not addressed to the second bot user (wrong mention/DM), so the other app never sees it.
    4. A binding/accountId mismatch (accountId in your bindings must equal the config key after OpenClaw’s normalization — lowercase + allowed chars).

What I checked in the code (quick summary)

  • monitorSlackProvider uses the accountId you configure and starts a Bolt App per account (so multiple socket-mode apps in one gateway process are supported).
  • prepareSlackMessage calls resolveAgentRoute({ accountId: account.accountId, teamId: ctx.teamId, ... }), so routing will match on accountId (and teamId/peer) — it will only match a binding for accountId if the monitor handling the event is running for that account.
  • The gateway starts a monitor per configured account (channel manager calls plugin.gateway.startAccount for every channels.slack.accounts key).

How to debug / fix (step-by-step)

  1. Confirm both Slack account monitors are running
    • Run:
#
  • openclaw channels status
    • openclaw channels status --probe
    • You should see both account keys from channels.slack.accounts listed and marked running/connected. If the second account is missing or not running, that’s the problem.
  1. Check tokens belong to different Slack apps/bot users

    • For each bot token run (redact token when you paste results here):
    • Look at user_id, team_id and api_app_id. If both tokens return the same user_id or same api_app_id, you’re effectively using the same app twice.
  2. Verify the event is actually addressed to the second bot

    • For a channel message you must mention the bot’s user id (e.g. <@U12345>) for mention-gated channels. For a DM, make sure you are truly DMing the second bot user.
    • From the auth.test above you get the bot’s user_id; try sending a message that includes that exact mention text.
  3. Check binding/accountId normalization

    • The accountId in your binding must match the config key after normalization (OpenClaw lowercases and sanitizes ids). Prefer simple lowercase names (e.g. agent2) to avoid surprises.
    • Example: if your config key is channels.slack.accounts.agent2_bot then use accountId: "agent2_bot" in bindings (lowercased).
#
  1. Turn on verbose gateway logs and watch routing

    • Start the gateway with verbose logging:
      • openclaw gateway --verbose
    • Tail logs while sending a test message to the second bot:
      • openclaw logs --follow | rg -i slack
    • With verbose enabled you should see routing debug lines from resolveAgentRoute like:
      • [routing] resolveAgentRoute: channel=slack accountId=... bindings=...
      • [routing] match: matchedBy=... agentId=...
    • Those lines will show which accountId was used for routing and which binding matched.
  2. Quick isolation test

    • Temporarily remove the teamId from your binding (leave only channel + accountId) or create a binding that only matches accountId. That reduces the matching surface and helps verify accountId routing works in isolation.

If these checks still show the correct monitors running and the tokens are different, but messages still go to the default agent — please paste (redacting tokens):

  • Output of openclaw channels status --probe
  • The two auth.test JSONs (user_id, team_id, api_app_id)
  • A short log excerpt from openclaw logs (with --verbose) around the time you send a test message (look for the resolveAgentRoute debug lines)