> ## Documentation Index
> Fetch the complete documentation index at: https://docs.duvo.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Slack bot identity

> Choose whether Duvo acts as itself or as you in Slack — and when each option matters.

When an agent sends a Slack message, the message can appear in two ways:

* **As Duvo** — a bot message from the Duvo app, clearly labelled with a "APP" badge.
* **As you** — a message posted on behalf of your authenticated Slack account, indistinguishable from something you typed yourself.

Which one you get depends on how you configure the agent's Slack steps. This guide explains the difference, when to use each, and how to set it up.

## How it works

Connecting Slack installs two tokens at once:

| Token type             | Visible as                  | Scope of access                            |
| ---------------------- | --------------------------- | ------------------------------------------ |
| **Bot token** (xoxb-)  | "Duvo" app with APP badge   | Channels and DMs the bot has been added to |
| **User token** (xoxp-) | Your personal Slack account | Every channel and DM you can access        |

Both tokens are stored securely when you connect Slack via **Connections**. Duvo selects the right token per action based on your configuration.

<Note>
  The bot token is workspace-wide. Every member of your Duvo team that connects
  to the same Slack workspace shares one bot identity. User tokens are personal
  — each Duvo user who connects gets their own xoxp- token.
</Note>

## Connect Slack

If you haven't connected Slack yet, open **Connections** in the Duvo dashboard and click **Add connection → Slack**. Complete the OAuth flow — Slack authorises both the bot and your personal account in one step.

You can connect multiple Slack workspaces by repeating the flow.

## Default behaviour: Duvo posts as the bot

Read operations (listing channels, fetching messages, searching) always use your user token — the bot can only see channels it has been added to, whereas your user account has full visibility.

Write operations (sending messages, reacting, uploading files) default to the **bot token**, so posts appear as Duvo:

```
Duvo  APP  10:42 AM
Your invoice report is ready. 3 new invoices require approval.
```

This is the right default for most automations — it makes automated messages easy to distinguish from human conversation.

## Post as yourself instead

Set `as_user: true` on any write step in the agent prompt or tool configuration:

```
Send a Slack message to @emma in #account-ops:
  message: "The Q2 close checklist is done."
  as_user: true
```

With `as_user: true`, the message appears under your name and avatar, with no APP badge. Use this when:

* You want a DM to feel like a personal follow-up.
* A downstream recipient only trusts messages from a known person, not a bot.
* Your Slack admin has restricted bot posting in certain channels.

<Warning>
  Messages sent `as_user` are indistinguishable from messages you typed
  manually. Make sure your team understands that some messages may be
  AI-generated if you use this mode broadly.
</Warning>

## Private channels and DMs

The bot token only works in channels it has been explicitly added to. If an agent needs to post to a private channel:

<Steps>
  <Step title="Invite the bot to the channel">
    In Slack, open the private channel and run `/invite @Duvo`. This adds the
    bot as a member so its token can read and post there.
  </Step>

  <Step title="Verify the connection">
    In the Duvo dashboard, open the agent and confirm the Slack connection
    selected for that step is the one whose bot was just invited.
  </Step>
</Steps>

For DMs, no invitation is needed — the bot can open direct messages with any workspace member once the app is installed.

If you prefer the DM to appear from you personally, use `as_user: true` as described above.

## Triggering agents from Slack

Agents can be started when a message is posted to a specific Slack channel. To set this up, go to the agent's **Triggers** tab and add a **Slack channel message** trigger.

Because the trigger listener uses the bot token, the bot must be a member of the channel you select. Private channels require the `/invite @Duvo` step above before the trigger will fire.

You can further narrow which messages fire the trigger:

| Match rule           | When it fires                                           |
| -------------------- | ------------------------------------------------------- |
| **All messages**     | Every message in the channel                            |
| **Contains keyword** | Only messages that include one of the specified phrases |

## Multiple Slack workspaces

If your agent needs to post to two different Slack workspaces, add a separate Slack connection for each workspace and reference the correct connection in each step of your agent prompt. Duvo resolves the token per connection, not per workspace automatically.

## Troubleshooting

<AccordionGroup>
  <Accordion title="Bot can't see the channel or the trigger isn't firing">
    The bot has not been invited to the channel. Run `/invite @Duvo` in Slack.
  </Accordion>

  <Accordion title="Messages are appearing under the wrong name">
    Check whether `as_user` is set for that step. If `as_user: true`, messages post as the user whose token was used at connect time. Re-connect Slack under a different user account to change this.
  </Accordion>

  <Accordion title="I connected Slack but the bot scopes are missing">
    You may have authorised user scopes only. Disconnect the connection and reconnect — make sure to click **Allow** on the Slack app installation screen (which grants bot scopes) as well as the personal authorisation prompt.
  </Accordion>

  <Accordion title="The agent can see channels but can't post">
    The bot requires the `channels:join` or `chat:write.public` scope for public channels and an explicit invite for private ones. Both scopes are included in the default Slack connection. If you installed a custom Slack app, verify both scopes are present in your app's OAuth & Permissions settings.
  </Accordion>
</AccordionGroup>
