BDS0.1

Slack — Workspace Token Cache

Deixa o token e o usuário do bot de cada workspace do Slack prontos para outros workflows, atualizados do Tooling a cada 5 min.

Revisado 2026-11-06Markdown
Plataforma
n8n · Abrir no n8n
Status
Ativo
ID do workflow
aqaoUgxhGVLTnKUR
Nós
18
Versão no n8n
565b640c-345d-4880-b4c7-4622c45b3d95
Último salvamento no n8n
2026-11-06T19:41:23.849Z

O Slack — Workspace Token Cache deixa o bot do Slack de cada workspace pronto para os workflows que postam no Slack. Ele lê as contas de bot do Tooling and Access, guarda uma linha por workspace do Slack numa Data Table do n8n por 15 minutos e responde aos outros workflows com o token e o usuário do bot do workspace pedido. Ele atualiza todos os workspaces a cada cinco minutos, então quem chama normalmente recebe a resposta sem chegar ao Airtable.

Ele não grava em nenhum sistema de negócio. A única saída dele é a Data Table slack_workspace_token_cache, que é armazenamento dentro do n8n, e a resposta que ele devolve ao workflow que o chamou. O maintainer do Tooling and Access cuida das contas de bot que ele lê.

Fluxo

Gerado da versão do n8n do quadro acima: cada caixa é um nó e cada seta é uma ligação no n8n. Pílulas rosa são gatilhos, hexágonos amarelos são nós If e Switch com as saídas nas setas, cilindros azuis leem (Airtable, Data Table, HTTP GET), cilindros verdes gravam, caixas roxas chamam outro workflow e setas tracejadas são saídas de erro.

Erros

Atualizar do Airtable

Responder do cache

Gatilhos

erro

erro

erro

erro

erro

erro

erro

sim

não

sim

não

sim

não

erro

Every 5 Minutes

Refresh Manually

Refresh All Workspaces

Token Request

Normalize Request

Refresh All?

Read Workspace Cache
get n8n Data Table slack_workspace_token_cache

Evaluate Cache

Refresh Needed?

Return Cached Result

Read Cache for Refresh
get n8n Data Table slack_workspace_token_cache

Read Bot Accounts
GET Tooling Tool Account

Build Cache Rows

Has Cache Rows?

Persist Workspace Tokens
upsert n8n Data Table slack_workspace_token_cache

Return Refreshed Result

Return Cache Error

Código Mermaid
flowchart TD
  subgraph g0["Gatilhos"]
    n2(["Every 5 Minutes"]):::trigger
    n11(["Refresh Manually"]):::trigger
    n9["Refresh All Workspaces"]:::logic
    n16(["Token Request"]):::trigger
    n4["Normalize Request"]:::logic
    n10{{"Refresh All?"}}:::decision
  end
  subgraph g1["Responder do cache"]
    n8[("Read Workspace Cache<br/><small>get n8n Data Table slack_workspace_token_cache</small>")]:::read
    n1["Evaluate Cache"]:::logic
    n12{{"Refresh Needed?"}}:::decision
    n14["Return Cached Result"]:::logic
  end
  subgraph g2["Atualizar do Airtable"]
    n7[("Read Cache for Refresh<br/><small>get n8n Data Table slack_workspace_token_cache</small>")]:::read
    n6[("Read Bot Accounts<br/><small>GET Tooling Tool Account</small>")]:::read
    n0["Build Cache Rows"]:::logic
    n3{{"Has Cache Rows?"}}:::decision
    n5[("Persist Workspace Tokens<br/><small>upsert n8n Data Table slack_workspace_token_cache</small>")]:::write
    n15["Return Refreshed Result"]:::logic
  end
  subgraph g3["Erros"]
    n13["Return Cache Error"]:::logic
  end
  n2 --> n9
  n9 --> n4
  n11 --> n9
  n16 --> n4
  n4 --> n10
  n4 -.->|erro| n13
  n8 --> n1
  n8 -.->|erro| n13
  n1 --> n12
  n1 -.->|erro| n13
  n7 --> n6
  n7 -.->|erro| n13
  n6 --> n0
  n6 -.->|erro| n13
  n0 --> n3
  n0 -.->|erro| n13
  n5 --> n15
  n5 -.->|erro| n13
  n10 -->|sim| n7
  n10 -->|não| n8
  n12 -->|sim| n7
  n12 -->|não| n14
  n3 -->|sim| n5
  n3 -->|não| n15
  n15 -.->|erro| n13
  classDef trigger fill:#fde7f3,stroke:#d6409f,color:#111
  classDef decision fill:#fff7e0,stroke:#c99a00,color:#111
  classDef read fill:#e8f1ff,stroke:#3b82f6,color:#111
  classDef write fill:#e7f8ee,stroke:#16a34a,color:#111
  classDef subflow fill:#f3e8ff,stroke:#9333ea,color:#111
  classDef wait fill:#f1f1f1,stroke:#888,color:#111
  classDef logic fill:#ffffff,stroke:#999,color:#111

Sistemas que ele toca

Sistema Tabela Lê Grava
Tooling and Access Tool Account Read Bot Accounts Nada
n8n (não é sistema de negócio) Data Table slack_workspace_token_cache Read Workspace Cache, Read Cache for Refresh Persist Workspace Tokens

O Read Bot Accounts é um nó HTTP Request com a credencial de token do Airtable “Airtable PAT (Fully Scoped)”. O filtro e os campos que ele lê usam IDs de campo, então renomear Kind, Access Token, External Identifier ou Workspace (External Identifier) no Tooling não o quebra. Veja os registros de Tool Account em Automações do Tooling and Access.

Dois workflows o chamam pelo Token Request e esperam a resposta, salvo onde indicado:

Workflow que chama Nó que chama Entradas enviadas
Daily Digest Get Cached Notification Bot workspaceId; cacheOnly, forceRefresh e refreshAll falsos
Reading Reply Get Cached Bot workspaceId; cacheOnly verdadeiro quando a rota da requisição do Slack é open, falso nos outros casos
Reading Reply Refresh Workspace in Background workspaceId; forceRefresh verdadeiro; não espera a resposta

Gatilhos

Gatilho Quando O que roda
Every 5 Minutes A cada cinco minutos Refresh All Workspaces, depois o caminho de atualização para todos os workspaces
Refresh Manually Alguém roda no editor O mesmo que Every 5 Minutes
Token Request Outro workflow o chama O caminho escolhido pelas entradas

O Normalize Request tira espaços do workspaceId e só considera cacheOnly, forceRefresh e refreshAll verdadeiros quando quem chama mandou o booleano true. Sem refreshAll, o ID do workspace precisa ter cara de ID de time do Slack (T seguido de letras maiúsculas e dígitos); senão ele lança INVALID_WORKSPACE e quem chama recebe a resposta de erro.

O Refresh All? manda refreshAll para o caminho de atualização e todo o resto para o caminho do cache.

Responder do cache

O Read Workspace Cache busca as linhas da Data Table cujo workspace_id é o workspace pedido. O Evaluate Cache só aceita a linha quando existe exatamente uma, ela tem access_token, não tem cache_error e o expires_at está a mais de cinco segundos.

Situação Resposta
Linha válida e sem forceRefresh ok verdadeiro, workspaceId, botSecret, botUserId, expiresAt, source cache. O Return Cached Result a devolve
Duas linhas para o workspace Erro CACHE_DUPLICATE
Nenhuma linha Erro CACHE_MISS
Linha com cache_error Esse código de erro
Linha perto de expirar, ou forceRefresh Erro CACHE_EXPIRED

Num erro, o Refresh Needed? vai para o caminho de atualização, a menos que quem chama tenha mandado cacheOnly: aí o Return Cached Result devolve o erro na hora, sem Airtable. A nota de contrato no canvas reserva cacheOnly para cliques interativos do Slack, que precisam de resposta rápida.

Atualizar do Airtable

  1. O Read Cache for Refresh lê todas as linhas da Data Table, mesmo quando só um workspace é atualizado.
  2. O Read Bot Accounts lê as linhas de Tool Account cujo Kind é bot, 100 por página, seguindo todas as páginas, uma vez por execução, com timeout de 15 segundos por requisição.
  3. O Build Cache Rows agrupa as contas de bot por cada valor de Workspace (External Identifier) que tem cara de ID de time do Slack. Para cada workspace a atualizar ele monta uma linha, ou um código de erro:
Código Quando
AMBIGUOUS_BOT Mais de uma conta de bot para o workspace
BOT_NOT_CONFIGURED Nenhuma conta de bot para o workspace
BOT_TOKEN_MISSING O Access Token não começa com o prefixo de token de bot do Slack
BOT_USER_MISSING O External Identifier não é um ID de usuário do Slack (U seguido de letras maiúsculas e dígitos)

Os workspaces a atualizar são o pedido ou, com refreshAll, todos os encontrados em Tool Account mais todos os que já estão na Data Table. Um workspace que só está na Data Table recebe BOT_NOT_CONFIGURED, o que apaga o token dele.

  1. O Has Cache Rows? pula a gravação quando não há nada a gravar (só acontece com refreshAll e nenhum workspace em lugar nenhum).
  2. O Persist Workspace Tokens faz upsert de cada linha por workspace_id.
  3. O Return Refreshed Result responde a quem chamou. Depois de refreshAll ele devolve contagens: workspaces, ready e invalid. Para um workspace ele devolve a mesma resposta de um acerto válido no cache com source refresh, ou o código de erro da linha, ou CACHE_EXPIRED.

Campos gravados

Campos de Tool Account lidos (Tooling and Access)

Campo Usado para
Kind Só linhas com bot são lidas
Workspace (External Identifier) Os IDs de workspace do Slack a que o bot pertence
Access Token O token do bot copiado para o cache
External Identifier O ID de usuário do bot no Slack

Colunas da Data Table gravadas (Persist Workspace Tokens)

Coluna Valor
workspace_id ID do workspace do Slack; a chave do upsert
access_token Token do bot, ou vazio quando há código de erro
bot_user_id ID de usuário do bot no Slack, ou vazio quando há código de erro
source_record_id ID do registro de Tool Account, ou vazio quando nenhum bateu
cache_error Vazio, ou um dos códigos de Atualizar do Airtable
expires_at Hora da gravação mais 15 minutos, em milissegundos; 0 quando há código de erro

Nós

O workflow tem 18 nós: 17 que executam e uma nota adesiva. Num nó If, a saída 0 é verdadeiro e a saída 1 é falso. Os nós configurados para seguir por uma saída de erro (Normalize Request, Read Workspace Cache, Evaluate Cache, Read Cache for Refresh, Read Bot Accounts, Build Cache Rows, Persist Workspace Tokens e Return Refreshed Result) mandam as falhas pela saída 1, desenhada com seta tracejada no fluxo.

Nó Tipo O que faz
Every 5 Minutes scheduleTrigger Gatilho agendado, a cada cinco minutos
Refresh Manually manualTrigger Gatilho manual no editor
Refresh All Workspaces set Define refreshAll = true para os dois gatilhos de atualização
Token Request executeWorkflowTrigger Chamado por outro workflow com workspaceId, cacheOnly, forceRefresh, refreshAll
Normalize Request code Valida o ID do workspace e normaliza as flags
Refresh All? if refreshAll ou um único workspace
Read Workspace Cache dataTable Linhas da Data Table do workspace
Evaluate Cache code Devolve o bot do cache quando válido; senão diz por quê
Refresh Needed? if Atualizar agora ou responder como está
Return Cached Result noOp Devolve a resposta ao chamador sem mudança
Read Cache for Refresh dataTable Todas as linhas da Data Table
Read Bot Accounts httpRequest Linhas de Tool Account com Kind bot, todas as páginas
Build Cache Rows code Uma linha de cache por workspace, ou um código de erro
Has Cache Rows? if Algo a gravar ou não
Persist Workspace Tokens dataTable Faz upsert das linhas por workspace_id
Return Refreshed Result code Responde ao chamador depois de uma atualização
Return Cache Error code Responde TOKEN_CACHE_UNAVAILABLE com a etapa
Cache Contract stickyNote Nota de contrato no canvas; não executa

Ligações

O Return Refreshed Result não tem ligação de saída na saída 0: o item dele é a resposta devolvida a quem chamou.

De Saída Para
Every 5 Minutes 0 Refresh All Workspaces
Refresh Manually 0 Refresh All Workspaces
Refresh All Workspaces 0 Normalize Request
Token Request 0 Normalize Request
Normalize Request 0 Refresh All?
Normalize Request 1 Return Cache Error
Refresh All? 0 Read Cache for Refresh
Refresh All? 1 Read Workspace Cache
Read Workspace Cache 0 Evaluate Cache
Read Workspace Cache 1 Return Cache Error
Evaluate Cache 0 Refresh Needed?
Evaluate Cache 1 Return Cache Error
Refresh Needed? 0 Read Cache for Refresh
Refresh Needed? 1 Return Cached Result
Read Cache for Refresh 0 Read Bot Accounts
Read Cache for Refresh 1 Return Cache Error
Read Bot Accounts 0 Build Cache Rows
Read Bot Accounts 1 Return Cache Error
Build Cache Rows 0 Has Cache Rows?
Build Cache Rows 1 Return Cache Error
Has Cache Rows? 0 Persist Workspace Tokens
Has Cache Rows? 1 Return Refreshed Result
Persist Workspace Tokens 0 Return Refreshed Result
Persist Workspace Tokens 1 Return Cache Error
Return Refreshed Result 1 Return Cache Error

Configurações e tratamento de erro

Configuração Valor
Ordem de execução v1
Fuso horário America/Recife
Timeout de execução 60 segundos
Salvar execuções com sucesso Não
Salvar execuções com falha Não
Salvar execuções manuais Não
Salvar progresso da execução Não
Workflow de erro Nenhum
Retry on fail Desligado em todos os nós
Caller policy Workflows do mesmo dono
Disponível no MCP Sim

Toda falha dentro do fluxo vai para o Return Cache Error, que responde ok falso, erro TOKEN_CACHE_UNAVAILABLE e stage: o nome do último nó que ele acha executado, conferido do fim do caminho de atualização para trás. As falhas nos nós com saída de erro viram essa resposta em vez de uma execução com falha; quem chama decide o que fazer com ela.

Lacunas conhecidas

Estas vêm da configuração dos nós. As execuções não são salvas, então o n8n não guarda histórico das rodadas para comparar.

Lacuna Efeito
A resposta leva o token do bot em botSecret Qualquer workflow do mesmo dono que o chama recebe o token nos próprios dados de execução
A Data Table guarda o token do bot em texto puro em access_token Quem abre a Data Table no n8n consegue ler todos os tokens em cache
Nenhuma execução é salva e os erros viram uma resposta normal Uma atualização agendada quebrada não deixa rastro no n8n; só aparece quando quem chama recebe CACHE_EXPIRED ou TOKEN_CACHE_UNAVAILABLE
O stage da resposta de erro é o último nó executado encontrado, não o nó que falhou Aponta a área certa, nem sempre o nó exato
Uma atualização de um workspace lê a Data Table inteira e todas as contas de bot Cada atualização forçada custa tantas chamadas ao Airtable quanto uma completa
Duas atualizações podem rodar ao mesmo tempo (agendamento e quem chama) As duas fazem upsert nas mesmas linhas; a última gravação vence, com os mesmos dados
O cache nunca pergunta ao Slack se o token ainda funciona Um token revogado no Slack continua sendo servido até alguém mudar o Access Token em Tool Account

Recuperar uma gravação parcial

A Data Table pode ser reconstruída a qualquer momento, então recuperar é atualizar.

O que aconteceu O que fazer
Quem chama recebe CACHE_EXPIRED ou CACHE_MISS para um workspace que tem bot Rode o Refresh Manually; se o erro continuar, confira a linha de Tool Account do workspace
Um workspace responde AMBIGUOUS_BOT Deixe uma única Tool Account com Kind bot para esse workspace e atualize
Um workspace responde BOT_TOKEN_MISSING ou BOT_USER_MISSING Corrija o Access Token ou o External Identifier da Tool Account dele e atualize
Uma atualização parou no meio Rode o Refresh Manually; o upsert substitui todas as linhas
Duas linhas para um workspace (CACHE_DUPLICATE) Apague uma linha na Data Table e atualize

Manter esta página em dia

O quadro no topo mostra a versão do n8n que esta página descreve. Abra o workflow no n8n: quando o último salvamento dele é mais novo que a data do quadro, esta página está desatualizada até a próxima revisão. Todos os nós e todas as ligações dessa versão estão em Nós e Ligações.