EVOPE AI Agent
Documentação completa de integração do Agente de Insights EVOPE.
Integre análise de dados com IA diretamente no front-end da plataforma.
Endpoint de Produção:
https://webhook.digital-ai.tech/webhook/evope/chat
O que é
O agente recebe os dados já renderizados em tela (JSON do nightly job: Mapa de Processos, Burnout, Grupos), processa com IA, armazena a sessão e retorna um diagnóstico inicial provocativo. A partir daí, o usuário pode fazer perguntas livres sobre os dados analisados.
Casos de uso
| Página | Tipo de análise | Dados enviados |
|---|---|---|
| Mapa de Processos | Eficiência operacional, automação | Nodes (apps + horas) + Edges (caminhos) |
| Relatório de Burnout | Risco de burnout por colaborador | EmployeeList + BurnoutEmployeeList |
| Grupos | Aproveitamento e entretenimento por grupo | GruposDetalhes + Colaboradores |
Quick Start #
Integração básica em 4 passos:
UsuarioID-EmpresaID-GrupoIDoutput. Usar mesmo IDSessao para follow-ups// 1. Gerar sessão única por usuário/tela const sessionId = `${usuarioId}-${empresaId}-${grupoId}`; // 2. Montar payload com dados da tela const payload = { UsuarioNome: currentUser.nome, UsuarioEmail: currentUser.email, UsuarioID: currentUser.id, EmpresaID: currentCompany.id, GrupoID: currentGroup.id, Grupo: currentGroup.nome, DataInicio: "01/05/2026", DataFim: "31/05/2026", IDSessao: sessionId, PaginaOrigem: "Mapa", data: { Nodes: mapaFuncoesJson, // array já em memória Edges: mapaCaminhosJson // array já em memória } }; // 3. Chamar o webhook const res = await fetch("https://webhook.digital-ai.tech/webhook/evope/chat", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload) }); const { output } = await res.json(); // 4. "output" = diagnóstico inicial da IA showChatMessage(output);
Arquitetura #
Na 1ª mensagem (envio de dados), o n8n processa, analisa com IA e armazena a sessão. Nas mensagens seguintes (texto livre), recupera o histórico automaticamente via PostgreSQL.
Tempo de resposta estimado
| Tipo de requisição | Tempo típico |
|---|---|
| 1ª mensagem — análise de dados (Mapa/Burnout) | 20 – 45 segundos |
| Follow-up — pergunta de texto | 5 – 15 segundos |
Endpoint #
Headers obrigatórios
| Header | Valor | |
|---|---|---|
Content-Type | application/json | obrigatório |
O endpoint não requer autenticação por header — a sessão é controlada pelo IDSessao no body. Em produção, o acesso é restrito por IP/origin do servidor EVOPE.
Sessão — IDSessao #
O IDSessao é o identificador da conversa. Deve ser único por usuário + relatório.
Toda mensagem (análise inicial + follow-ups) deve usar o mesmo IDSessao para manter o contexto.
Formato recomendado
// Padrão recomendado: UsuarioID-EmpresaID-GrupoID const sessionId = `${usuarioId}-${empresaId}-${grupoId}`; // Exemplo: "711-80-22889" // Alternativa: UUID aleatório por sessão de navegação const sessionId = crypto.randomUUID(); // "sess_3ae8d061-7f0d-..."
Importante: Use o mesmo IDSessao em TODAS as mensagens da conversa. Se mudar o IDSessao, o agente perde o contexto e responde como se fosse uma nova sessão.
Ciclo de vida da sessão
| Evento | Ação no IDSessao |
|---|---|
| Usuário abre o chat pela 1ª vez | Gerar novo IDSessao |
| Usuário envia dados + perguntas | Manter o mesmo IDSessao |
| Usuário clica em "Nova análise" / "Recomeçar" | Gerar novo IDSessao |
| Usuário muda de relatório (Mapa → Burnout) | Gerar novo IDSessao ou manter (contexto diferente) |
Requisição de Análise (1ª mensagem) #
Enviada quando o usuário abre o chat e envia os dados da tela atual. O agente analisa os dados, gera o diagnóstico inicial e armazena a sessão.
Campos do payload (raiz)
| Campo | Tipo | Descrição | |
|---|---|---|---|
PaginaOrigem | string | "Mapa", "Burnout" ou "Grupos" | obrigatório |
IDSessao | string | Identificador único da sessão | obrigatório |
EmpresaID | number | ID da empresa no sistema EVOPE | obrigatório |
GrupoID | string | ID do grupo/filtro selecionado | obrigatório |
Grupo | string | Nome do grupo (ex: "Master > TI") | obrigatório |
DataInicio | string | Período início no formato "DD/MM/YYYY" | obrigatório |
DataFim | string | Período fim no formato "DD/MM/YYYY" | obrigatório |
UsuarioID | number | ID do usuário autenticado | opcional |
UsuarioNome | string | Nome do usuário | opcional |
UsuarioEmail | string | E-mail do usuário | opcional |
data | object | Dados da análise (ver seções abaixo) | obrigatório |
Requisição de Chat (follow-up) #
Enviada nas mensagens seguintes, quando o usuário faz perguntas livres. O agente recupera o histórico da sessão automaticamente.
Campos
| Campo | Tipo | Descrição | |
|---|---|---|---|
chatInput | string | Texto da mensagem do usuário | obrigatório |
IDSessao | string | Mesmo IDSessao da análise inicial | obrigatório |
fetch("https://webhook.digital-ai.tech/webhook/evope/chat", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ chatInput: "Qual é o app com maior risco de automação?", IDSessao: sessionId // mesmo IDSessao da análise inicial }) });
Resposta #
Formato
{
"output": "## DIAGNÓSTICO\n**Teams concentra 54% das 47.343h mapeadas**..."
}
Campos da resposta
| Campo | Tipo | Descrição |
|---|---|---|
output | string | Texto da resposta da IA em Markdown. Renderizar com marked.js ou similar. |
Status HTTP
O campo output contém Markdown com **negrito**, *itálico*, ## cabeçalhos e listas. Renderize com uma biblioteca Markdown ou aplique CSS básico para exibição correta.
Payload — Mapa de Processos #
Usado na página Mapa de Processos. Os dados já estão em memória no front (carregados na renderização da tela).
Estrutura do campo data
| Subcampo | Tipo | Descrição |
|---|---|---|
data.Nodes | array | Lista de aplicativos/funções mapeados (Funcoes.json) |
data.Edges | array | Lista de caminhos entre apps (Caminhos.json) |
Campos de cada item em Nodes
| Campo | Tipo | Descrição |
|---|---|---|
Aplicativo | string | Categoria do app ("Web", "Teams", "Excel") |
Funcionalidade | string | Sub-app ou página específica ("Gmail", "meet.google.com") |
Horas | string | Horas no período em formato "HH:MM" (ex: "477:53") |
Teclado | number | Total de teclas digitadas |
Mouse | number | Total de cliques de mouse |
Interacoes | number | Total de interações |
Colaboradores | string | Nº de colaboradores que usam este app (string) |
Copiar | number | Total de operações Ctrl+C |
Colar | number | Total de operações Ctrl+V |
Processo | number | Indicador de processo (0 ou 1) |
Campos de cada item em Edges (opcional)
| Campo | Tipo | Descrição |
|---|---|---|
Origem | string | App de origem do caminho |
Destino | string | App de destino do caminho |
Quantidade | number | Número de vezes que o caminho foi percorrido |
Payload completo — Mapa
{
"PaginaOrigem": "Mapa",
"UsuarioNome": "João Silva",
"UsuarioEmail": "joao@empresa.com.br",
"UsuarioID": 711,
"EmpresaID": 80,
"GrupoID": "22889",
"Grupo": "Master > CSC > HTR Latam",
"DataInicio": "01/05/2026",
"DataFim": "31/05/2026",
"IDSessao": "711-80-22889",
"data": {
"Nodes": [
{
"Aplicativo": "Web",
"Funcionalidade": "meet.google.com",
"Horas": "477:53",
"Teclado": 88505,
"Mouse": 64657,
"Interacoes": 26899,
"Colaboradores": "43",
"Copiar": 766,
"Colar": 1143,
"Processo": 0
}
// ... demais apps
],
"Edges": [
{
"Origem": "[Teams]-Chat",
"Destino": "[Web]-portal.evope.com.br",
"Quantidade": 320
}
]
}
}
Payload — Burnout #
Campos de cada item em EmployeeList
| Campo | Tipo | Descrição |
|---|---|---|
Colaborador | string | Nome do colaborador |
Grupo | string | Grupo ao qual pertence |
Aproveitamento | number | % de aproveitamento (pode ser > 100) |
Entretenimento | number | % de uso de apps de entretenimento |
TotalHoras | number | Total de horas ativas no período |
HorasPrevistas | number | Horas previstas/esperadas no período |
DiasPropensaoBurnout | number | Dias com risco de burnout calculado |
{
"PaginaOrigem": "Burnout",
"EmpresaID": 80,
"GrupoID": "22889",
"Grupo": "Master > CSC > Finanças",
"DataInicio": "01/05/2026",
"DataFim": "31/05/2026",
"IDSessao": "711-80-22889-burnout",
"data": {
"EmployeeList": [
{
"Colaborador": "Roberta Reis",
"Grupo": "Administrativo / Financeiro",
"Aproveitamento": 111.0,
"Entretenimento": 1.0,
"TotalHoras": 179.0,
"HorasPrevistas": 160.0,
"DiasPropensaoBurnout": 2
}
// ... demais colaboradores
],
"BurnoutEmployeeList": [
// subset de EmployeeList onde Aproveitamento >= 100 e Entretenimento < 7
]
}
}
Payload — Grupos #
{
"PaginaOrigem": "Grupos",
"EmpresaID": 80,
"GrupoID": "22889",
"Grupo": "Master",
"DataInicio": "01/05/2026",
"DataFim": "31/05/2026",
"IDSessao": "711-80-22889-grupos",
"data": {
"GruposDetalhes": [
// Array de grupos com métricas agregadas
],
"ColaboradoresBurnout": [
// Colaboradores com Aproveitamento alto + Entretenimento baixo
],
"ColaboradoresEntretenimento": [
// Colaboradores com Entretenimento > 15%
]
}
}
Integração — Embed (iframe) #
Use a interface pronta via iframe. Comunicação bidirecional via postMessage.
<!-- Embed do chat EVOPE AI --> <iframe id="evope-chat" src="https://reports.digital-ai.tech/evope/chat.html" width="420" height="680" style="border:none;border-radius:12px;box-shadow:0 8px 32px rgba(0,0,0,.4)" ></iframe>
const chatFrame = document.getElementById("evope-chat"); // Enviar análise para o iframe (dispara automaticamente) chatFrame.contentWindow.postMessage({ type: "evope:startAnalysis", payload: { sessionId: "711-80-22889", analysisData: { /* payload completo */ } } }, "https://reports.digital-ai.tech"); // Resetar sessão no iframe chatFrame.contentWindow.postMessage( { type: "evope:resetSession" }, "https://reports.digital-ai.tech" ); // Ouvir quando o iframe está pronto window.addEventListener("message", (event) => { if (event.data.type === "evope:chatReady") { console.log("Chat EVOPE pronto!"); } });
Integração — API Direta #
Para quem quer construir o próprio componente de chat usando apenas a API.
// Estado global da sessão const session = { id: null, initialized: false }; async function startAISession(pageData) { // Gerar sessão única session.id = `${pageData.usuarioId}-${pageData.empresaId}-${pageData.grupoId}`; showTypingDots(); try { const response = await fetch( "https://webhook.digital-ai.tech/webhook/evope/chat", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(buildPayload(pageData)), signal: AbortSignal.timeout(90000) // 90s timeout } ); if (!response.ok) throw new Error(`Erro ${response.status}`); const { output } = await response.json(); hideTypingDots(); session.initialized = true; renderAssistantMessage(output); } catch (err) { hideTypingDots(); showError(err.message); } } async function sendChatMessage(userText) { if (!session.id) return; renderUserMessage(userText); showTypingDots(); try { const response = await fetch( "https://webhook.digital-ai.tech/webhook/evope/chat", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ chatInput: userText, IDSessao: session.id }), signal: AbortSignal.timeout(60000) } ); const { output } = await response.json(); hideTypingDots(); renderAssistantMessage(output); } catch (err) { hideTypingDots(); renderAssistantMessage("⚠️ Falha na comunicação. Tente novamente."); } } function buildPayload(pageData) { return { PaginaOrigem: pageData.pagina, // "Mapa", "Burnout" ou "Grupos" UsuarioID: pageData.usuarioId, EmpresaID: pageData.empresaId, GrupoID: pageData.grupoId, Grupo: pageData.grupoNome, DataInicio: pageData.dataInicio, // "01/05/2026" DataFim: pageData.dataFim, IDSessao: session.id, data: pageData.data // { Nodes, Edges } ou { EmployeeList } }; } function resetSession() { session.id = null; session.initialized = false; clearChatMessages(); }
Tratamento de Erros #
| Cenário | Causa | Ação recomendada |
|---|---|---|
| HTTP 500 | Erro interno no n8n | Exibir mensagem de erro, botão "Tentar novamente" |
| Timeout (>90s) | IA demorou mais que o esperado | Usar AbortSignal.timeout(90000), retentar uma vez |
output vazio | Resposta sem conteúdo | Tratar como erro, exibir fallback |
| Sem memória do contexto | IDSessao diferente no follow-up | Garantir que o IDSessao é idêntico em todas as requisições |
| Análise sem dados | Array Nodes ou EmployeeList vazio | Validar no front antes de chamar a API |
async function callAgent(payload) { const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), 90000); try { const res = await fetch(ENDPOINT, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload), signal: controller.signal }); clearTimeout(timeout); if (!res.ok) { throw new Error(`Servidor retornou ${res.status}`); } let data; try { data = await res.json(); } catch { throw new Error("Resposta inválida do servidor"); } if (!data?.output) { throw new Error("Resposta vazia"); } return data.output; } catch (err) { clearTimeout(timeout); if (err.name === "AbortError") { return "⏱ Tempo limite excedido. Tente novamente."; } return `⚠️ ${err.message}. Tente novamente.`; } }
Exemplos Completos #
cURL — análise inicial
curl -s -X POST \
https://webhook.digital-ai.tech/webhook/evope/chat \
-H "Content-Type: application/json" \
-d '{
"PaginaOrigem": "Burnout",
"EmpresaID": 80,
"GrupoID": "22889",
"Grupo": "Master > CSC > Finanças",
"DataInicio": "01/05/2026",
"DataFim": "31/05/2026",
"IDSessao": "711-80-22889-burnout",
"data": {
"EmployeeList": [
{
"Colaborador": "Roberta Reis",
"Grupo": "Financeiro",
"Aproveitamento": 111.0,
"Entretenimento": 1.0,
"TotalHoras": 179.0,
"HorasPrevistas": 160.0,
"DiasPropensaoBurnout": 2
}
],
"BurnoutEmployeeList": []
}
}' | jq '.output'
cURL — follow-up
curl -s -X POST \
https://webhook.digital-ai.tech/webhook/evope/chat \
-H "Content-Type: application/json" \
-d '{
"chatInput": "Quais são os 3 maiores riscos identificados?",
"IDSessao": "711-80-22889-burnout"
}' | jq '.output'
Python — exemplo completo
import requests ENDPOINT = "https://webhook.digital-ai.tech/webhook/evope/chat" SESSION_ID = "711-80-22889" # 1. Análise inicial response = requests.post(ENDPOINT, json={ "PaginaOrigem": "Mapa", "EmpresaID": 80, "GrupoID": "22889", "Grupo": "Master > TI", "DataInicio": "01/05/2026", "DataFim": "31/05/2026", "IDSessao": SESSION_ID, "data": { "Nodes": nodes_data, # lista de apps "Edges": edges_data # lista de caminhos } }, timeout=90) print(response.json()["output"]) # 2. Follow-up followup = requests.post(ENDPOINT, json={ "chatInput": "Qual app tem mais horas?", "IDSessao": SESSION_ID }, timeout=60) print(followup.json()["output"])
Pronto para integrar!
Interface de demo disponível em reports.digital-ai.tech/evope/chat.html