Pular para o conteúdo principal

Chatwoot Messages

Este workflow processa mensagens do evento message_created do Chatwoot, filtrando apenas mensagens válidas de contatos (não de bots), e encaminha para processamento com IA. Resolve:

  • Evitar loops de bot respondendo bot
  • Processar apenas mensagens de texto ou com anexos
  • Garantir que apenas conversas sem atendente humano sejam processadas automaticamente
  • Armazenar histórico completo para análise

O Que Este Fluxo Faz

Fluxo Principal

  1. Recebe webhook message_created do Chatwoot
  2. Valida condições para processar a mensagem:
    • ✅ Sender é do tipo contact (não é bot)
    • ✅ Mensagem não está private (visível para o contato)
    • ✅ Conversa não está atribuída a um atendente humano
    • ✅ Conversa não está em um time específico
  3. Separa em dois fluxos baseado no tipo:

Fluxo A: Mensagens com Anexo

  • Condição: Possui attachments não vazio
  • Ações:
    1. Salva conversa no banco (tabela conversation)
    2. Executa Type Message Router (subflow):
      • Processa imagens → Extrai base64
      • Processa áudios → Transcreve com OpenAI
      • Processa arquivos, contatos, localizações → Extrai metadados
    3. Salva mensagem processada no banco (tabela message)
    4. Executa Process Messages para gerar resposta com IA

Fluxo B: Mensagens de Texto

  • Condição: Não possui anexos
  • Ações:
    1. Salva conversa no banco (tabela conversation)
    2. Salva mensagem no banco (tabela message)
    3. Executa Process Messages para gerar resposta com IA

Como a IA Processa as Mensagens

Após salvar a mensagem no banco, o workflow executa um fluxo complexo de processamento com IA usando OpenAI (ou LLM configurado). Veja o diagrama completo:

Detalhamento do Processamento

1. Busca do Agent (Get Agents)

O workflow busca o agent (configuração de IA) mais adequado baseado em prioridade:

SELECT a.* FROM agent a
LEFT JOIN agent_contact ac ON ac.agent_id = a.id
WHERE a.status = '1' AND a.inbox_id = '{inbox_id}'
AND (
a.assigned_contact_id = '{contact_id}' -- Prioridade 1
OR ac.contact_id IS NOT NULL -- Prioridade 2
OR a.assigned_contact_id IS NULL -- Prioridade 3 (genérico)
)
ORDER BY [prioridade] LIMIT 1

Tabela agent:

  • id: ID do agent
  • instructions: Prompt base (system prompt)
  • functions: JSON com lista de functions disponíveis
  • inbox_id: Inbox associada
  • assigned_contact_id: Se específico para um contato
  • team_id: Se vinculado a um time
  • testword: Palavra-chave para ativação (opcional)

2. Montagem do Contexto (Agent Settings)

O nó Agent Settings monta o payload completo para a OpenAI:

{
"input": [
{
"role": "system",
"content": [{
"type": "input_text",
"text": `${instructions}
## Dados da conversa
Data e Hora Atual: ${now}
Nome do usuário: ${nome}
Telefone: ${telefone}
E-mail: ${email}
User ID: ${platform_id || 'Não informado'}
Chat ID: ${conversation_id}
Account ID: ${account_id}
Inbox ID: ${inbox_id}
`
}]
},
// Histórico de mensagens (user, assistant, function_call, function_call_output)
],
"tools": [...], // Functions disponíveis
"model": "gpt-4.1-mini",
"temperature": 0.4,
"max_output_tokens": 2048
}

Tipos de mensagens no histórico:

  • user (text): Mensagem de texto do usuário
  • user (image): Imagem em base64
  • assistant: Resposta da IA
  • function_call: IA solicitou executar uma function
  • function_call_output: Resultado da execução da function

3. Resposta da OpenAI

A API retorna um dos dois tipos:

Tipo 1: Texto (output_text)

{
"id": "msg_abc123",
"output": [{
"content": [{
"type": "output_text",
"text": "Olá! Como posso ajudar?"
}]
}]
}

→ Salvo como role=assistant → Quebrado em blocos de 140 chars → Enviado ao Chatwoot

Tipo 2: Function Call

{
"id": "msg_abc123",
"type": "function_call",
"call_id": "call_xyz789",
"name": "search_knowledge_base",
"arguments": "{\"query\": \"como emitir certificado\"}"
}

→ Salvo como role=function_call → Executa workflow correspondente → Salva output como role=function_call_outputReinicia fluxo IA

4. Tree Tools (Mapeamento de Functions)

O nó Tree Tools mapeia cada function_name para seu workflow_id:

Function NameWorkflow IDDescrição
transfer_to_human0V2b41jDw9rbfIWdTransfere para atendente humano
search_knowledge_baseAAtFzeQnDevWVuJ4Busca na base de conhecimento (Dify)
end_conversationJZ5i8erPnHoViFNwFinaliza conversa
formulario_loginSGv14qbAvQCMNTGKColeta dados de login
get_matriculasYYZLerBm3hqdU4DqBusca matrículas do aluno
get_certificateuTYdQjEsQMbecm2zGera certificado
create_transactioncYI8xPDhp1VI4a8WCria transação de pagamento
...e mais 11 functions-Diversas integrações

5. Loop de Function Calling

Quando a IA retorna uma function_call:

  1. Salva a function call no banco (role=function_call)
  2. Executa o workflow correspondente
  3. Salva o resultado (role=function_call_output)
  4. Busca novamente todas as mensagens (incluindo a nova output)
  5. Reenvia para a OpenAI com contexto atualizado
  6. Repete até a IA retornar texto (não function_call)

Este loop permite que a IA:

  • Busque informações antes de responder
  • Execute múltiplas ações em sequência
  • Tome decisões baseadas nos resultados das functions

Estrutura do Banco de Dados

Tabela agent

- id: ID do agent (auto increment)
- instructions: Prompt base (system prompt) da IA
- functions: JSON com lista de functions disponíveis
- inbox_id: ID da inbox associada
- assigned_contact_id: Contact ID específico (NULL = genérico)
- team_id: Team ID vinculado (opcional)
- testword: Palavra-chave de ativação (opcional)
- status: 1 (ativo) ou 0 (inativo)
- created_at: Timestamp de criação

Tabela agent_contact

- id: ID do registro (auto increment)
- agent_id: Referência ao agent
- contact_id: Referência ao contato do Chatwoot
- created_at: Timestamp de associação

Tabela conversation

- external_id: ID da conversa no Chatwoot
- contact_id: ID do contato
- inbox_id: ID da inbox
- account_id: ID da conta Chatwoot
- status: 0 (pendente) ou 1 (processando)
- last_source_id: ID da última mensagem
- origin: Número de telefone do contato
- last_interaction_at: Última interação

Tabela message

- payload: JSON completo da mensagem
- content: Conteúdo (texto, base64, metadados ou JSON)
- source: "{conversation_id}_{contact_id}"
- processed: 0 (não processada) ou 1 (processada)
- account_id: ID da conta
- inbox_id: ID da inbox
- role: "user", "assistant", "function_call", "function_call_output"
- type: "text", "image", etc
- message_id: ID da mensagem no Chatwoot
- external_id: ID externo (da OpenAI)
- sub_external_id: call_id (para function calls)
- execution_id: ID da execução no N8N
- grouping: Agrupamento (opcional)
- created_at: Timestamp

Setup

1. Configurar Webhook no Chatwoot

  1. Acesse Chatwoot > Settings > Integrations > Webhooks
  2. Adicione um novo webhook:
    • URL: https://n8n-queue.incibrasil.com.br/webhook/incoming
    • Eventos: Marcar apenas message_created
  3. Salve e teste o webhook

2. Configurar Agent (IA)

Para criar um novo agent com IA personalizada:

  1. Insira um registro na tabela agent:
INSERT INTO agent (instructions, functions, inbox_id, status) VALUES (
'Você é um assistente virtual prestativo. Seu objetivo é...',
'[{"type": "function", "function": {"name": "search_knowledge_base", "description": "..."}}, ...]',
8, -- ID da inbox
1 -- Ativo
);
  1. (Opcional) Associe o agent a contatos específicos:
INSERT INTO agent_contact (agent_id, contact_id) VALUES (1, 12345);

3. Configurar Workflows Relacionados

Este workflow depende de outros workflows que devem estar ativos:

4. Adicionar Nova Conta Chatwoot

Este workflow está preparado para múltiplas contas. Se você precisar adicionar suporte para uma nova conta:

  1. Não é necessário alterar este workflow
  2. Configure apenas:

Observações Importantes

  • ✅ Este workflow processa apenas mensagens de contatos, não de bots
  • ✅ Ignora mensagens de conversas já atribuídas a atendentes humanos
  • ✅ Ignora mensagens privadas (anotações internas)
  • ⚠️ Mensagens com anexos passam por processamento extra (Type Message Router)
  • ⚠️ Se o banco estiver indisponível, mensagens são perdidas (sem retry)
  • ⚠️ Todas as mensagens são salvas com processed: 0 aguardando processamento posterior

Workflows Relacionados