# Slack integration

Connect a customer-owned Slack app to a Salambo agent and troubleshoot webhook delivery.

Salambo connects Slack through customer-owned Slack apps. Each Slack bot belongs to one Salambo agent, has its own Slack app credentials, and is routed independently from other Slack bots in the same workspace.

> Slack messages authored by bots are ignored by default. This prevents
> bot-to-bot loops such as one Salambo bot replying to another Salambo bot until
> both keep triggering runs.

## What you will create

For each Slack bot, you create and own a Slack app in your Slack workspace, then paste its credentials into Salambo.

| Item                 | Owner               | Secret? | Salambo behavior                  |
| -------------------- | ------------------- | ------- | --------------------------------- |
| Slack App ID         | Slack               | No      | Saved with the connection         |
| Slack Client ID      | Slack               | No      | Saved with the connection         |
| Slack Client Secret  | Slack               | Yes     | Encrypted and never shown again   |
| Slack Signing Secret | Slack               | Yes     | Encrypted and never shown again   |
| Slack Bot Token      | Slack OAuth install | Yes     | Encrypted after the OAuth install |
| Agent mapping        | Salambo             | No      | Selects which agent answers       |

Salambo never shows stored Slack secrets back in the browser. To rotate credentials, paste fresh values from Slack.

## Architecture

```mermaid
flowchart LR
    Human[Slack user] --> Slack[Slack Events API]
    Slack --> Webhook[Salambo Slack webhook]
    Webhook --> Verify[Slack signature verification]
    Verify --> Route[Route by Slack App ID]
    Route --> Dedupe[Per-app state and dedupe]
    Dedupe --> Runtime[Salambo native run]
    Runtime --> Reply[Slack reply]

    Bot[Slack bot-authored message] --> Slack
    Route --> Ignore[Ignored for loop safety]
```

Important boundaries:

* Slack webhook delivery is transport-only.
* Slack tokens are not exposed to agent runtime tools.
* `ctx.external` contains provider metadata and IDs only.
* Salambo manages connection state, duplicate-event protection, conversation mapping, and encrypted credentials.
* The native run service owns execution, billing, files, and turn lifecycle.

## Setup

### 1. Open Slack integrations

In Salambo, open your workspace and go to:

```text
Settings → Integrations → Slack
```

Click **Add Slack bot**.

### 2. Choose the agent and bot name

Choose the Salambo agent that should answer Slack mentions and enter the Slack bot display name.

One Slack bot maps to one Salambo agent.

### 3. Create the Slack app from the manifest

Salambo generates a Slack app manifest. Copy it, then open:

```text
https://api.slack.com/apps
```

Choose **Create New App → From an app manifest** and paste the generated manifest.

The manifest configures:

| Slack setting       | Value                                                            |
| ------------------- | ---------------------------------------------------------------- |
| OAuth redirect URL  | `/api/integrations/slack/oauth/callback` on your Salambo app URL |
| Events request URL  | `/api/integrations/slack/events` on your Salambo app URL         |
| Event subscriptions | `app_mention`, `message.im`                                      |
| Socket Mode         | Disabled                                                         |
| Token rotation      | Disabled                                                         |

Default bot scopes:

```text
app_mentions:read
channels:history
chat:write
im:history
im:read
im:write
reactions:write
users:read
```

Existing Slack apps must add `reactions:write` and be reinstalled before they
can show accepted, completed, and failed lifecycle reactions.

### 4. Paste Slack app credentials

In Slack, open the app and go to:

```text
Basic Information → App Credentials
```

Copy and paste into Salambo:

* App ID
* Client ID
* Client Secret
* Signing Secret

Then click **Save credentials**.

### 5. Install the app to Slack

Click **Install to Slack** in Salambo and approve the OAuth install.

After install, Salambo encrypts the Slack bot token and marks the connection active.

### 6. Invite or mention the bot

In Slack:

* mention the bot in a channel, for example `@fabrice hello`; or
* send the bot a direct message.

The bot should create one Salambo run and reply once.

To adapt prompts or tools using Slack channel, thread, and sender metadata, continue with [external event context](/docs/integrations/external-context) and the [Slack recipes](/docs/integrations/channel-recipes#slack-thread-aware-instructions).

## Managing an existing Slack bot

### Rotate credentials

Use **Edit** on the Slack connection.

You can update:

* agent mapping;
* bot display name;
* Client ID;
* Client Secret;
* Signing Secret.

The App ID is read-only for an existing connection. Secret fields are intentionally blank and must be pasted fresh.

### Reinstall to Slack

Use **Reconnect** or **Install** when the OAuth install needs to be refreshed.

If Slack returns `bad_client_secret`, the Client Secret pasted into Salambo does not match the Slack app.

### Remove from Salambo

Use **Remove from Salambo** to stop routing events for that Slack app.

This deactivates the Salambo connection so future events are ignored. It does not delete or uninstall the Slack app inside Slack, and it does not revoke Slack-side access.

To fully remove Slack-side access, also uninstall or revoke the app in Slack under **Manage Apps** or the app's **OAuth & Permissions** settings.

## Loop safety

Salambo verifies the Slack signature first, then ignores Slack messages identified as bot-authored.

This means:

| Scenario                               | Result                |
| -------------------------------------- | --------------------- |
| Human mentions `@demo`                 | `demo` can answer     |
| Human mentions `@fabrice`              | `fabrice` can answer  |
| `demo` replies and mentions `@fabrice` | Ignored               |
| `fabrice` replies and mentions `@demo` | Ignored               |
| Slack retry delivers same event again  | Deduped per Slack app |

## Troubleshooting

| Symptom                                          | Likely cause                                                  | Fix                                                                                                |
| ------------------------------------------------ | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| Slack Event Subscriptions URL verification fails | Webhook URL or app route issue                                | Use the exact `/api/integrations/slack/events` URL from the manifest.                              |
| Slack event POST returns `401`                   | Wrong Signing Secret                                          | Paste the Signing Secret from the same Slack App ID under **Basic Information → App Credentials**. |
| OAuth install shows `bad_client_secret`          | Wrong Client Secret                                           | Paste the Client Secret from the same Slack App ID.                                                |
| Bot does not answer in a channel                 | Bot not invited, wrong app mentioned, or integration inactive | Invite the bot, mention the correct bot, and check the Salambo integration status.                 |
| One bot answers but another does not             | Credentials or App ID mismatch on the failing bot             | Verify that App ID, Client ID, Client Secret, and Signing Secret all come from the same Slack app. |
| Many Slack runs appear in a loop                 | Bot-authored messages are unexpectedly creating runs          | Preserve the affected run IDs, deactivate the connection, and contact Salambo support.             |

## Verify the connection

After setup or credential rotation, verify:

1. Slack Events API receives `200` responses.
2. A human mention creates one Salambo run.
3. The run completes and the bot replies once.
4. The run Activity view shows the channel-triggered turn.
5. A bot-authored message does not create a run.

If a check fails, use the connection status and the run's Activity and Diagnostics views. Those surfaces identify authentication, admission, provider, extension, and reply-delivery failures without requiring access to Salambo service logs.

## Production URLs

Use your deployed Salambo app origin. The production paths are:

```text
https://YOUR_SALAMBO_APP_URL/api/integrations/slack/events
https://YOUR_SALAMBO_APP_URL/api/integrations/slack/oauth/callback
```

Do not use localhost URLs in a Slack production app unless you are explicitly tunneling and testing locally.
