Slack

Status: pronto para produção em DMs + canais via integrações de app Slack. O modo padrão é Socket Mode; o modo HTTP Events API também é suportado.

Configuração rápida

Socket Mode (padrão)

  ### Passo 1: Crie o app Slack e os tokens
    Nas configurações do app Slack:

    - ative o **Socket Mode**
    - crie o **App Token** (`xapp-...`) com `connections:write`
    - instale o app e copie o **Bot Token** (`xoxb-...`)


  ### Passo 2: Configure o OpenClaw
{
  channels: {
    slack: {
      enabled: true,
      mode: "socket",
      appToken: "xapp-...",
      botToken: "xoxb-...",
    },
  },
}
    Fallback por variável de ambiente (apenas conta padrão):
SLACK_APP_TOKEN=xapp-...
SLACK_BOT_TOKEN=xoxb-...
  ### Passo 3: Assine os eventos do app
    Assine os eventos do bot para:

    - `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`

    Ative também a aba **Messages Tab** no App Home para DMs.


  ### Passo 4: Inicie o gateway
openclaw gateway

Modo HTTP Events API

  ### Passo 1: Configure o app Slack para HTTP

    - defina o modo como HTTP (`channels.slack.mode="http"`)
    - copie o **Signing Secret** do Slack
    - defina a Request URL de Event Subscriptions + Interactivity + Slash command com o mesmo caminho de webhook (padrão `/slack/events`)



  ### Passo 2: Configure o OpenClaw em modo HTTP
{
  channels: {
    slack: {
      enabled: true,
      mode: "http",
      botToken: "xoxb-...",
      signingSecret: "your-signing-secret",
      webhookPath: "/slack/events",
    },
  },
}
  ### Passo 3: Use caminhos de webhook únicos para HTTP multiconta
    O modo HTTP por conta é suportado.

    Dê a cada conta um `webhookPath` distinto para que os registros não colidam.

Modelo de tokens

  • botToken + appToken são obrigatórios para Socket Mode.
  • O modo HTTP requer botToken + signingSecret.
  • Tokens de config sobrescrevem o fallback por variável de ambiente.
  • SLACK_BOT_TOKEN / SLACK_APP_TOKEN como fallback por env se aplicam apenas à conta padrão.
  • userToken (xoxp-...) é somente config (sem fallback por env) e tem comportamento padrão somente leitura (userTokenReadOnly: true).
  • Opcional: adicione chat:write.customize se quiser que mensagens de saída usem a identidade do agente ativo (nome de username e ícone customizados). icon_emoji usa a sintaxe :emoji_name:.

Dica: Para ações/leituras de diretório, o user token pode ser preferido quando configurado. Para escritas, o bot token permanece preferido; escritas com user-token são permitidas apenas quando userTokenReadOnly: false e o bot token não está disponível.

Controle de acesso e roteamento

Política de DM

`channels.slack.dmPolicy` controla o acesso a DMs (legado: `channels.slack.dm.policy`):

- `pairing` (padrão)
- `allowlist`
- `open` (requer que `channels.slack.allowFrom` inclua `"*"`; legado: `channels.slack.dm.allowFrom`)
- `disabled`

Flags de DM:

- `dm.enabled` (padrão true)
- `channels.slack.allowFrom` (preferido)
- `dm.allowFrom` (legado)
- `dm.groupEnabled` (group DMs padrão false)
- `dm.groupChannels` (lista de permitidos MPIM opcional)

Precedência multiconta:

- `channels.slack.accounts.default.allowFrom` se aplica apenas à conta `default`.
- Contas nomeadas herdam `channels.slack.allowFrom` quando seu próprio `allowFrom` não está definido.
- Contas nomeadas não herdam `channels.slack.accounts.default.allowFrom`.

Pareamento em DMs usa `openclaw pairing approve slack <code>`.

Política de canal

`channels.slack.groupPolicy` controla o tratamento de canais:

- `open`
- `allowlist`
- `disabled`

A lista de permitidos de canais fica em `channels.slack.channels` e deve usar IDs estáveis de canal.

Observação de runtime: se `channels.slack` estiver completamente ausente (configuração apenas por env), o runtime recorre a `groupPolicy="allowlist"` e registra um aviso (mesmo que `channels.defaults.groupPolicy` esteja definido).

Resolução de nome/ID:

- entradas de lista de permitidos de canal e DM são resolvidas na inicialização quando o acesso ao token permite
- entradas de nome de canal não resolvidas são mantidas como configuradas mas ignoradas para roteamento por padrão
- autorização de entrada e roteamento de canal são ID-first por padrão; correspondência direta por username/slug requer `channels.slack.dangerouslyAllowNameMatching: true`

Menções e usuários de canal

Mensagens de canal são filtradas por menção por padrão.

Fontes de menção:

- menção explícita do app (`<@botId>`)
- padrões regex de menção (`agents.list[].groupChat.mentionPatterns`, fallback `messages.groupChat.mentionPatterns`)
- comportamento implícito de resposta ao bot em thread

Controles por canal (`channels.slack.channels.<id>`; nomes apenas via resolução na inicialização ou `dangerouslyAllowNameMatching`):

- `requireMention`
- `users` (lista de permitidos)
- `allowBots`
- `skills`
- `systemPrompt`
- `tools`, `toolsBySender`
- Formato de chave `toolsBySender`: `id:`, `e164:`, `username:`, `name:` ou wildcard `"*"`
  (chaves legadas sem prefixo ainda mapeiam apenas para `id:`)

Comandos e comportamento slash

  • O modo automático de comando nativo é desativado para o Slack (commands.native: "auto" não ativa comandos nativos do Slack).
  • Ative handlers de comandos nativos do Slack com channels.slack.commands.native: true (ou global commands.native: true).
  • Quando comandos nativos estão ativados, registre comandos slash correspondentes no Slack (/<command> nomes), com uma exceção:
    • registre /agentstatus para o comando de status (o Slack reserva /status)
  • Se comandos nativos não estiverem ativados, você pode executar um único comando slash configurado via channels.slack.slashCommand.
  • Menus de argumentos nativos agora adaptam sua estratégia de renderização:
    • até 5 opções: blocos de botões
    • 6-100 opções: menu de seleção estático
    • mais de 100 opções: seleção externa com filtragem assíncrona de opções quando handlers de opções de interatividade estão disponíveis
    • se valores de opções codificados excedem os limites do Slack, o fluxo recorre a botões
  • Para payloads de opções longos, os menus de argumentos de comandos slash usam um diálogo de confirmação antes de despachar um valor selecionado.

Respostas interativas

O Slack pode renderizar controles de resposta interativos criados pelo agente, mas esse recurso é desativado por padrão.

Ative globalmente:

{
  channels: {
    slack: {
      capabilities: {
        interactiveReplies: true,
      },
    },
  },
}

Ou ative para uma conta Slack apenas:

{
  channels: {
    slack: {
      accounts: {
        ops: {
          capabilities: {
            interactiveReplies: true,
          },
        },
      },
    },
  },
}

Quando ativado, os agentes podem emitir diretivas de resposta exclusivas do Slack:

  • [[slack_buttons: Approve:approve, Reject:reject]]
  • [[slack_select: Choose a target | Canary:canary, Production:production]]

Essas diretivas são compiladas em Slack Block Kit e roteiam cliques ou seleções de volta pelo caminho existente de eventos de interação do Slack.

Observações:

  • Essa é uma UI específica do Slack. Outros canais não traduzem diretivas de Slack Block Kit para seus próprios sistemas de botões.
  • Os valores de callback interativos são tokens opacos gerados pelo OpenClaw, não valores brutos do agente.
  • Se blocos interativos gerados excedem os limites do Slack Block Kit, o OpenClaw recorre à resposta em texto original em vez de enviar um payload de blocos inválido.

Configurações padrão de comando slash:

  • enabled: false
  • name: "openclaw"
  • sessionPrefix: "slack:slash"
  • ephemeral: true

Sessões slash usam chaves isoladas:

  • agent:<agentId>:slack:slash:<userId>

e ainda roteiam a execução do comando contra a sessão de conversa alvo (CommandTargetSessionKey).

Threading, sessões e tags de resposta

  • DMs roteiam como direct; canais como channel; MPIMs como group.
  • Com o padrão session.dmScope=main, DMs do Slack se agrupam na sessão principal do agente.
  • Sessões de canal: agent:<agentId>:slack:channel:<channelId>.
  • Respostas em thread podem criar sufixos de sessão de thread (:thread:<threadTs>) quando aplicável.
  • channels.slack.thread.historyScope padrão é thread; thread.inheritParent padrão é false.
  • channels.slack.thread.initialHistoryLimit controla quantas mensagens existentes da thread são buscadas quando uma nova sessão de thread inicia (padrão 20; defina 0 para desativar).

Controles de threading de respostas:

  • channels.slack.replyToMode: off|first|all (padrão off)
  • channels.slack.replyToModeByChatType: por direct|group|channel
  • fallback legado para chats diretos: channels.slack.dm.replyToMode

Tags de resposta manuais são suportadas:

  • [[reply_to_current]]
  • [[reply_to:<id>]]

Observação: replyToMode="off" desativa todo o threading de resposta no Slack, incluindo tags explícitas [[reply_to_*]]. Isso difere do Telegram, onde tags explícitas são respeitadas mesmo no modo "off". A diferença reflete os modelos de threading das plataformas: threads do Slack escondem mensagens do canal, enquanto respostas do Telegram permanecem visíveis no fluxo principal do chat.

Mídia, fragmentação e entrega

Anexos de entrada
Anexos de arquivo do Slack são baixados de URLs privadas hospedadas pelo Slack (fluxo de requisição autenticado por token) e gravados no armazenamento de mídia quando o fetch é bem-sucedido e os limites de tamanho permitem.

O limite de tamanho de entrada em runtime tem padrão `20MB` a menos que sobrescrito por `channels.slack.mediaMaxMb`.
Texto e arquivos de saída
- chunks de texto usam `channels.slack.textChunkLimit` (padrão 4000)
- `channels.slack.chunkMode="newline"` ativa divisão priorizando parágrafos
- envio de arquivos usa APIs de upload do Slack e pode incluir respostas em thread (`thread_ts`)
- limite de mídia de saída segue `channels.slack.mediaMaxMb` quando configurado; caso contrário, envios pelo canal usam padrões por tipo MIME do pipeline de mídia
Alvos de entrega
Alvos explícitos preferidos:

- `user:<id>` para DMs
- `channel:<id>` para canais

DMs do Slack são abertas via APIs de conversa do Slack ao enviar para alvos de usuário.

Ações e gates

As ações do Slack são controladas por channels.slack.actions.*.

Grupos de ação disponíveis na ferramenta Slack atual:

GrupoPadrão
messagesativado
reactionsativado
pinsativado
memberInfoativado
emojiListativado

Eventos e comportamento operacional

  • Edições/exclusões/broadcasts de thread de mensagens são mapeados em eventos de sistema.
  • Eventos de adicionar/remover reação são mapeados em eventos de sistema.
  • Eventos de entrada/saída de membro, criação/renomeação de canal e adicionar/remover pin são mapeados em eventos de sistema.
  • Atualizações de status de thread do assistente (para indicadores “digitando…” em threads) usam assistant.threads.setStatus e requerem o escopo de bot assistant:write.
  • channel_id_changed pode migrar chaves de configuração de canal quando configWrites está ativado.
  • Metadados de tópico/propósito do canal são tratados como contexto não confiável e podem ser injetados no contexto de roteamento.
  • Block actions e interações modais emitem eventos de sistema estruturados Slack interaction: ... com campos de payload ricos:
    • block actions: valores selecionados, rótulos, valores de picker e metadados workflow_*
    • eventos modais view_submission e view_closed com metadados de canal roteado e inputs de formulário

Reações de confirmação

ackReaction envia um emoji de confirmação enquanto o OpenClaw processa uma mensagem de entrada.

Ordem de resolução:

  • channels.slack.accounts.<accountId>.ackReaction
  • channels.slack.ackReaction
  • messages.ackReaction
  • fallback do emoji de identidade do agente (agents.list[].identity.emoji, senão ”👀”)

Observações:

  • O Slack espera shortcodes (por exemplo "eyes").
  • Use "" para desativar a reação para a conta Slack ou globalmente.

Fallback de reação de digitação

typingReaction adiciona uma reação temporária à mensagem de entrada do Slack enquanto o OpenClaw processa uma resposta, e a remove quando a execução termina. Este é um fallback útil quando o indicador de digitação nativo do assistente Slack não está disponível, especialmente em DMs.

Ordem de resolução:

  • channels.slack.accounts.<accountId>.typingReaction
  • channels.slack.typingReaction

Observações:

  • O Slack espera shortcodes (por exemplo "hourglass_flowing_sand").
  • A reação é best-effort e a limpeza é tentada automaticamente após a resposta ou quando o caminho de falha é concluído.

Checklist de manifesto e escopos

Exemplo de manifesto de app Slack
{
  "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",
        "im:history",
        "im:read",
        "im:write",
        "mpim:history",
        "mpim:read",
        "mpim:write",
        "users:read",
        "app_mentions:read",
        "assistant:write",
        "reactions:read",
        "reactions:write",
        "pins:read",
        "pins:write",
        "emoji:read",
        "commands",
        "files:read",
        "files:write"
      ]
    }
  },
  "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"
      ]
    }
  }
}
Escopos opcionais de user-token (operações de leitura)
Se configurar `channels.slack.userToken`, escopos típicos de leitura são:

- `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` (se depender de buscas do Slack)

Solução de problemas

Sem respostas em canais
Verifique, na ordem:

- `groupPolicy`
- lista de permitidos de canal (`channels.slack.channels`)
- `requireMention`
- lista de permitidos `users` por canal

Comandos úteis:
openclaw channels status --probe
openclaw logs --follow
openclaw doctor
Mensagens de DM ignoradas
Verifique:

- `channels.slack.dm.enabled`
- `channels.slack.dmPolicy` (ou legado `channels.slack.dm.policy`)
- aprovações de pareamento / entradas na lista de permitidos
openclaw pairing list slack
Socket mode não conecta
Valide os tokens de bot + app e o Socket Mode ativado nas configurações do app Slack.
Modo HTTP não recebe eventos
Valide:

- signing secret
- caminho do webhook
- Request URLs do Slack (Events + Interactivity + Slash Commands)
- `webhookPath` único por conta HTTP
Comandos nativos/slash não disparam
Verifique se você pretendia:

- modo de comando nativo (`channels.slack.commands.native: true`) com comandos slash correspondentes registrados no Slack
- ou modo de comando slash único (`channels.slack.slashCommand.enabled: true`)

Verifique também `commands.useAccessGroups` e listas de permitidos de canal/usuário.

Streaming de texto

O OpenClaw suporta streaming de texto nativo do Slack via a API de Agents and AI Apps.

channels.slack.streaming controla o comportamento de preview ao vivo:

  • off: desativa o streaming de preview ao vivo.
  • partial (padrão): substitui o texto de preview com a saída parcial mais recente.
  • block: adiciona atualizações de preview em chunks.
  • progress: mostra texto de status de progresso enquanto gera, depois envia o texto final.

channels.slack.nativeStreaming controla a API de streaming nativa do Slack (chat.startStream / chat.appendStream / chat.stopStream) quando streaming é partial (padrão: true).

Desative o streaming nativo do Slack (mantenha o comportamento de preview de rascunho):

channels:
  slack:
    streaming: partial
    nativeStreaming: false

Chaves legadas:

  • channels.slack.streamMode (replace | status_final | append) é migrado automaticamente para channels.slack.streaming.
  • channels.slack.streaming booleano é migrado automaticamente para channels.slack.nativeStreaming.

Requisitos

  1. Ative Agents and AI Apps nas configurações do app Slack.
  2. Certifique-se de que o app tem o escopo assistant:write.
  3. Uma thread de resposta deve estar disponível para essa mensagem. A seleção de thread ainda segue replyToMode.

Comportamento

  • O primeiro chunk de texto inicia um stream (chat.startStream).
  • Chunks posteriores de texto são adicionados ao mesmo stream (chat.appendStream).
  • O fim da resposta finaliza o stream (chat.stopStream).
  • Mídia e payloads não textuais recorrem à entrega normal.
  • Se o streaming falhar no meio da resposta, o OpenClaw recorre à entrega normal para os payloads restantes.

Referência de configuração

Referência principal:

  • Referência de configuração - Slack

    Campos de alto impacto do Slack:

    • modo/autenticação: mode, botToken, appToken, signingSecret, webhookPath, accounts.*
    • acesso a DM: dm.enabled, dmPolicy, allowFrom (legado: dm.policy, dm.allowFrom), dm.groupEnabled, dm.groupChannels
    • toggle de compatibilidade: dangerouslyAllowNameMatching (emergencial; mantenha desativado a menos que necessário)
    • acesso a canal: groupPolicy, channels.*, channels.*.users, channels.*.requireMention
    • threading/histórico: replyToMode, replyToModeByChatType, thread.*, historyLimit, dmHistoryLimit, dms.*.historyLimit
    • entrega: textChunkLimit, chunkMode, mediaMaxMb, streaming, nativeStreaming
    • ops/recursos: configWrites, commands.native, slashCommand.*, actions.*, userToken, userTokenReadOnly

Relacionado