Create backup: Sofía MVP - Gmail a Neo4j
This commit is contained in:
@@ -0,0 +1,736 @@
|
|||||||
|
{
|
||||||
|
"updatedAt": "2026-06-09T19:06:33.510Z",
|
||||||
|
"createdAt": "2026-06-09T18:15:50.646Z",
|
||||||
|
"id": "1ykpTM58gz0iOxvK",
|
||||||
|
"name": "Sofía MVP - Gmail a Neo4j",
|
||||||
|
"description": null,
|
||||||
|
"active": true,
|
||||||
|
"isArchived": false,
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"pollTimes": {
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"mode": "everyMinute"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"filters": {
|
||||||
|
"q": "subject:\"[MVP SOFIA]\"",
|
||||||
|
"sender": "iaracena@gomezleemarketing.com"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.gmailTrigger",
|
||||||
|
"typeVersion": 1.4,
|
||||||
|
"position": [
|
||||||
|
-112,
|
||||||
|
-80
|
||||||
|
],
|
||||||
|
"id": "bd0f5bc5-a7b2-461f-b316-ce76e907ae36",
|
||||||
|
"name": "Gmail Trigger",
|
||||||
|
"credentials": {
|
||||||
|
"gmailOAuth2": {
|
||||||
|
"id": "UDcO1FLJqA453V2D",
|
||||||
|
"name": "Gmail account 3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"conditions": {
|
||||||
|
"options": {
|
||||||
|
"caseSensitive": true,
|
||||||
|
"leftValue": "",
|
||||||
|
"typeValidation": "strict",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"id": "23cd3dcc-62ad-434d-accf-5e9d2ea7c558",
|
||||||
|
"leftValue": "={{ $json.subject }}",
|
||||||
|
"rightValue": "[MVP SOFIA]",
|
||||||
|
"operator": {
|
||||||
|
"type": "string",
|
||||||
|
"operation": "contains"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"combinator": "and"
|
||||||
|
},
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.if",
|
||||||
|
"typeVersion": 2.3,
|
||||||
|
"position": [
|
||||||
|
368,
|
||||||
|
-80
|
||||||
|
],
|
||||||
|
"id": "83330da0-3df5-4882-8432-3cde6e9c091b",
|
||||||
|
"name": "IF - Es correo MVP Sofía"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"jsCode": "const item = $input.first().json;\n\nconst subject =\n item.subject ||\n item.Subject ||\n item.headers?.subject ||\n '';\n\nconst from =\n item.from ||\n item.From ||\n item.headers?.from ||\n '';\n\nconst to =\n item.to ||\n item.To ||\n item.headers?.to ||\n '';\n\nconst text =\n item.textPlain ||\n item.text ||\n item.snippet ||\n item.body ||\n item.message ||\n '';\n\nconst html =\n item.textHtml ||\n item.html ||\n '';\n\nfunction limpiarHtml(valor) {\n return String(valor || '')\n .replace(/<style[\\s\\S]*?<\\/style>/gi, ' ')\n .replace(/<script[\\s\\S]*?<\\/script>/gi, ' ')\n .replace(/<[^>]+>/g, ' ')\n .replace(/ /g, ' ')\n .replace(/&/g, '&')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nconst body = String(text || '').trim() || limpiarHtml(html);\n\nreturn [\n {\n json: {\n source: 'gmail',\n subject: String(subject).trim(),\n from: String(from).trim(),\n to: String(to).trim(),\n body,\n received_at: new Date().toISOString(),\n raw: item,\n },\n },\n];"
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.code",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
128,
|
||||||
|
-80
|
||||||
|
],
|
||||||
|
"id": "15546536-4579-4015-9782-768095190afe",
|
||||||
|
"name": "Code - Normalizar correo MVP Sofía"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"method": "POST",
|
||||||
|
"url": "https://proyectosit-flowise.btv4al.easypanel.host/api/v1/prediction/1d68f530-9d5d-4229-9bd6-d5ea698832fc ",
|
||||||
|
"sendHeaders": true,
|
||||||
|
"headerParameters": {
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "Content-Type",
|
||||||
|
"value": "application/json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"sendBody": true,
|
||||||
|
"specifyBody": "json",
|
||||||
|
"jsonBody": "={\n \"question\": \"={{ $json.body }}\"\n}",
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.httpRequest",
|
||||||
|
"typeVersion": 4.4,
|
||||||
|
"position": [
|
||||||
|
752,
|
||||||
|
-96
|
||||||
|
],
|
||||||
|
"id": "50675419-4b0c-4d2e-878a-69cfb38682f8",
|
||||||
|
"name": "HTTP Request - Flowise extraer caso"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"jsCode": "const item = $input.first().json;\n\nlet respuesta =\n item.text ||\n item.answer ||\n item.response ||\n item.result ||\n item.data ||\n item;\n\nif (typeof respuesta !== 'string') {\n respuesta = JSON.stringify(respuesta);\n}\n\nrespuesta = respuesta\n .replace(/```json/gi, '')\n .replace(/```/g, '')\n .trim();\n\nlet data;\n\ntry {\n data = JSON.parse(respuesta);\n} catch (error) {\n throw new Error(\n 'Flowise no devolvió JSON válido. Respuesta recibida: ' + respuesta\n );\n}\n\nconst camposObligatorios = [\n 'responsable_nombre',\n 'responsable_email',\n 'cliente',\n 'titulo',\n 'problema',\n 'solucion',\n 'resultado',\n 'area',\n 'confidence',\n];\n\nfor (const campo of camposObligatorios) {\n if (!(campo in data)) {\n data[campo] = null;\n }\n}\n\nreturn [\n {\n json: {\n ...data,\n fuente: 'gmail_flowise_mvp',\n procesado_en: new Date().toISOString(),\n },\n },\n];"
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.code",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
960,
|
||||||
|
-96
|
||||||
|
],
|
||||||
|
"id": "cd88f8fb-d68b-4990-8ee1-a2bb0c85d9fe",
|
||||||
|
"name": "Code - Parsear JSON Flowise"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"conditions": {
|
||||||
|
"options": {
|
||||||
|
"caseSensitive": true,
|
||||||
|
"leftValue": "",
|
||||||
|
"typeValidation": "strict",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"id": "a73cb1f1-a67f-4023-8454-9b9e9dec51b4",
|
||||||
|
"leftValue": "={{ $json.confidence }}",
|
||||||
|
"rightValue": 0.6,
|
||||||
|
"operator": {
|
||||||
|
"type": "number",
|
||||||
|
"operation": "gte"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"combinator": "and"
|
||||||
|
},
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.if",
|
||||||
|
"typeVersion": 2.3,
|
||||||
|
"position": [
|
||||||
|
1168,
|
||||||
|
-96
|
||||||
|
],
|
||||||
|
"id": "020c0fcd-1aa9-4a64-be98-3cd9ee47f6be",
|
||||||
|
"name": "If"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"jsCode": "const data = $input.first().json;\n\nfunction texto(valor, fallback = '') {\n return String(valor ?? fallback).trim();\n}\n\nconst responsableEmail = texto(data.responsable_email || 'desconocido@gomezleemarketing.com').toLowerCase();\nconst responsableNombre = texto(data.responsable_nombre || 'Responsable no identificado');\nconst cliente = texto(data.cliente || 'Cliente no identificado');\nconst titulo = texto(data.titulo || 'Caso sin título');\nconst problema = texto(data.problema || 'Problema no identificado');\nconst solucion = texto(data.solucion || 'Solución no identificada');\nconst resultado = texto(data.resultado || 'Resultado no identificado');\nconst area = texto(data.area || 'Área no identificada');\nconst confidence = Number(data.confidence ?? 0);\nconst fuente = texto(data.fuente || 'gmail_flowise_mvp');\nconst procesadoEn = texto(data.procesado_en || new Date().toISOString());\n\nconst cypher = `\nMERGE (empleado:Empleado {email: $responsableEmail})\nSET empleado.nombre = $responsableNombre,\n empleado.area = $area,\n empleado.actualizado_en = datetime()\n\nMERGE (cliente:Cliente {nombre: $cliente})\nSET cliente.actualizado_en = datetime()\n\nCREATE (caso:CasoResuelto {\n id: randomUUID(),\n titulo: $titulo,\n problema: $problema,\n solucion: $solucion,\n resultado: $resultado,\n area: $area,\n confidence: $confidence,\n fuente: $fuente,\n procesado_en: datetime($procesadoEn),\n fecha_captura: datetime()\n})\n\nMERGE (empleado)-[:RESOLVIO]->(caso)\nMERGE (caso)-[:PERTENECE_A_CLIENTE]->(cliente)\n\nRETURN caso.id AS caso_id,\n caso.titulo AS titulo,\n empleado.nombre AS responsable,\n cliente.nombre AS cliente;\n`;\n\nreturn [\n {\n json: {\n cypher,\n parameters: {\n responsableEmail,\n responsableNombre,\n cliente,\n titulo,\n problema,\n solucion,\n resultado,\n area,\n confidence,\n fuente,\n procesadoEn,\n },\n },\n },\n];"
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.code",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
1648,
|
||||||
|
-128
|
||||||
|
],
|
||||||
|
"id": "792b2605-b658-4ac5-8cfd-f0148895bd80",
|
||||||
|
"name": "Code - Preparar Cypher Neo4j"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"method": "POST",
|
||||||
|
"url": "http://neo4j:7474/db/neo4j/tx/commit",
|
||||||
|
"authentication": "genericCredentialType",
|
||||||
|
"genericAuthType": "httpBasicAuth",
|
||||||
|
"sendHeaders": true,
|
||||||
|
"headerParameters": {
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "Content-Type",
|
||||||
|
"value": "application/json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Accept",
|
||||||
|
"value": " application/json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"sendBody": true,
|
||||||
|
"specifyBody": "json",
|
||||||
|
"jsonBody": "={{\n {\n statements: [\n {\n statement: $json.cypher,\n parameters: $json.parameters\n }\n ]\n }\n}}",
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.httpRequest",
|
||||||
|
"typeVersion": 4.4,
|
||||||
|
"position": [
|
||||||
|
1856,
|
||||||
|
-128
|
||||||
|
],
|
||||||
|
"id": "cc3b3878-dd68-499d-8f1f-f5e287bc5c11",
|
||||||
|
"name": "HTTP Request - Crear caso en Neo4j",
|
||||||
|
"credentials": {
|
||||||
|
"httpBasicAuth": {
|
||||||
|
"id": "nIxZ7elcHvuzsRKW",
|
||||||
|
"name": "Neo4j"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"content": "## Entrada controlada \n\nEste flujo solo procesa correos de prueba.\n\nGmail recibe el correo, n8n normaliza el asunto/cuerpo y el IF evita procesar correos que no pertenezcan al MVP.\n",
|
||||||
|
"height": 288,
|
||||||
|
"width": 768,
|
||||||
|
"color": 6
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.stickyNote",
|
||||||
|
"typeVersion": 1,
|
||||||
|
"position": [
|
||||||
|
-192,
|
||||||
|
-208
|
||||||
|
],
|
||||||
|
"id": "fe25ffcb-41c7-460e-9ded-c368cfd5ae45",
|
||||||
|
"name": "Sticky Note"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"content": "## Extracción inteligente con Flowise\n\nn8n envía el cuerpo del correo a Flowise.\n\nFlowise devuelve un JSON estructurado con responsable, cliente, título, problema, solución, resultado, área y confidence.\n\nSolo los casos con confidence suficiente continúan hacia Neo4j.\n",
|
||||||
|
"height": 384,
|
||||||
|
"width": 688
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.stickyNote",
|
||||||
|
"typeVersion": 1,
|
||||||
|
"position": [
|
||||||
|
688,
|
||||||
|
-272
|
||||||
|
],
|
||||||
|
"id": "8df77283-b1ad-4e19-b9a6-30f8034e7608",
|
||||||
|
"name": "Sticky Note1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"content": "## Registro en Neo4j y confirmación\n\nn8n convierte el JSON en una consulta Cypher y crea el caso en Neo4j.\n\nSe crean/actualizan nodos de Empleado, Cliente y CasoResuelto, con sus relaciones.\n\n",
|
||||||
|
"height": 384,
|
||||||
|
"width": 688,
|
||||||
|
"color": "#0E6808"
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.stickyNote",
|
||||||
|
"typeVersion": 1,
|
||||||
|
"position": [
|
||||||
|
1456,
|
||||||
|
-288
|
||||||
|
],
|
||||||
|
"id": "72c16df2-30a4-441e-9b38-e14e62c43040",
|
||||||
|
"name": "Sticky Note2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"connections": {
|
||||||
|
"Gmail Trigger": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Code - Normalizar correo MVP Sofía",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"IF - Es correo MVP Sofía": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "HTTP Request - Flowise extraer caso",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Code - Normalizar correo MVP Sofía": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "IF - Es correo MVP Sofía",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"HTTP Request - Flowise extraer caso": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Code - Parsear JSON Flowise",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Code - Parsear JSON Flowise": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "If",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"If": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Code - Preparar Cypher Neo4j",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Code - Preparar Cypher Neo4j": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "HTTP Request - Crear caso en Neo4j",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"HTTP Request - Crear caso en Neo4j": {
|
||||||
|
"main": [
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"executionOrder": "v1",
|
||||||
|
"binaryMode": "separate"
|
||||||
|
},
|
||||||
|
"staticData": {
|
||||||
|
"node:Gmail Trigger": {
|
||||||
|
"Gmail Trigger": {
|
||||||
|
"lastTimeChecked": 1781031641,
|
||||||
|
"possibleDuplicates": [
|
||||||
|
"19eadc22a5cb770f"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"meta": {
|
||||||
|
"templateCredsSetupCompleted": true
|
||||||
|
},
|
||||||
|
"versionId": "da03274d-aca0-4d78-be28-6543d5ecad92",
|
||||||
|
"activeVersionId": "da03274d-aca0-4d78-be28-6543d5ecad92",
|
||||||
|
"versionCounter": 124,
|
||||||
|
"triggerCount": 1,
|
||||||
|
"shared": [
|
||||||
|
{
|
||||||
|
"updatedAt": "2026-06-09T18:15:50.654Z",
|
||||||
|
"createdAt": "2026-06-09T18:15:50.654Z",
|
||||||
|
"role": "workflow:owner",
|
||||||
|
"workflowId": "1ykpTM58gz0iOxvK",
|
||||||
|
"projectId": "PJpTANzTXIFibWsW",
|
||||||
|
"project": {
|
||||||
|
"updatedAt": "2026-04-22T14:25:09.686Z",
|
||||||
|
"createdAt": "2026-04-22T14:22:54.790Z",
|
||||||
|
"id": "PJpTANzTXIFibWsW",
|
||||||
|
"name": "Isaac Aracena <iaracena@gomezleemarketing.com>",
|
||||||
|
"type": "personal",
|
||||||
|
"icon": null,
|
||||||
|
"description": null,
|
||||||
|
"creatorId": "0a88c0b1-928e-4412-896e-c5d1c99b2029"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [],
|
||||||
|
"activeVersion": {
|
||||||
|
"updatedAt": "2026-06-09T19:00:41.000Z",
|
||||||
|
"createdAt": "2026-06-09T18:56:18.699Z",
|
||||||
|
"versionId": "da03274d-aca0-4d78-be28-6543d5ecad92",
|
||||||
|
"workflowId": "1ykpTM58gz0iOxvK",
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"pollTimes": {
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"mode": "everyMinute"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"filters": {
|
||||||
|
"q": "subject:\"[MVP SOFIA]\"",
|
||||||
|
"sender": "iaracena@gomezleemarketing.com"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.gmailTrigger",
|
||||||
|
"typeVersion": 1.4,
|
||||||
|
"position": [
|
||||||
|
-112,
|
||||||
|
-80
|
||||||
|
],
|
||||||
|
"id": "bd0f5bc5-a7b2-461f-b316-ce76e907ae36",
|
||||||
|
"name": "Gmail Trigger",
|
||||||
|
"credentials": {
|
||||||
|
"gmailOAuth2": {
|
||||||
|
"id": "UDcO1FLJqA453V2D",
|
||||||
|
"name": "Gmail account 3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"conditions": {
|
||||||
|
"options": {
|
||||||
|
"caseSensitive": true,
|
||||||
|
"leftValue": "",
|
||||||
|
"typeValidation": "strict",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"id": "23cd3dcc-62ad-434d-accf-5e9d2ea7c558",
|
||||||
|
"leftValue": "={{ $json.subject }}",
|
||||||
|
"rightValue": "[MVP SOFIA]",
|
||||||
|
"operator": {
|
||||||
|
"type": "string",
|
||||||
|
"operation": "contains"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"combinator": "and"
|
||||||
|
},
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.if",
|
||||||
|
"typeVersion": 2.3,
|
||||||
|
"position": [
|
||||||
|
368,
|
||||||
|
-80
|
||||||
|
],
|
||||||
|
"id": "83330da0-3df5-4882-8432-3cde6e9c091b",
|
||||||
|
"name": "IF - Es correo MVP Sofía"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"jsCode": "const item = $input.first().json;\n\nconst subject =\n item.subject ||\n item.Subject ||\n item.headers?.subject ||\n '';\n\nconst from =\n item.from ||\n item.From ||\n item.headers?.from ||\n '';\n\nconst to =\n item.to ||\n item.To ||\n item.headers?.to ||\n '';\n\nconst text =\n item.textPlain ||\n item.text ||\n item.snippet ||\n item.body ||\n item.message ||\n '';\n\nconst html =\n item.textHtml ||\n item.html ||\n '';\n\nfunction limpiarHtml(valor) {\n return String(valor || '')\n .replace(/<style[\\s\\S]*?<\\/style>/gi, ' ')\n .replace(/<script[\\s\\S]*?<\\/script>/gi, ' ')\n .replace(/<[^>]+>/g, ' ')\n .replace(/ /g, ' ')\n .replace(/&/g, '&')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nconst body = String(text || '').trim() || limpiarHtml(html);\n\nreturn [\n {\n json: {\n source: 'gmail',\n subject: String(subject).trim(),\n from: String(from).trim(),\n to: String(to).trim(),\n body,\n received_at: new Date().toISOString(),\n raw: item,\n },\n },\n];"
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.code",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
128,
|
||||||
|
-80
|
||||||
|
],
|
||||||
|
"id": "15546536-4579-4015-9782-768095190afe",
|
||||||
|
"name": "Code - Normalizar correo MVP Sofía"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"method": "POST",
|
||||||
|
"url": "https://proyectosit-flowise.btv4al.easypanel.host/api/v1/prediction/1d68f530-9d5d-4229-9bd6-d5ea698832fc ",
|
||||||
|
"sendHeaders": true,
|
||||||
|
"headerParameters": {
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "Content-Type",
|
||||||
|
"value": "application/json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"sendBody": true,
|
||||||
|
"specifyBody": "json",
|
||||||
|
"jsonBody": "={\n \"question\": \"={{ $json.body }}\"\n}",
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.httpRequest",
|
||||||
|
"typeVersion": 4.4,
|
||||||
|
"position": [
|
||||||
|
752,
|
||||||
|
-96
|
||||||
|
],
|
||||||
|
"id": "50675419-4b0c-4d2e-878a-69cfb38682f8",
|
||||||
|
"name": "HTTP Request - Flowise extraer caso"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"jsCode": "const item = $input.first().json;\n\nlet respuesta =\n item.text ||\n item.answer ||\n item.response ||\n item.result ||\n item.data ||\n item;\n\nif (typeof respuesta !== 'string') {\n respuesta = JSON.stringify(respuesta);\n}\n\nrespuesta = respuesta\n .replace(/```json/gi, '')\n .replace(/```/g, '')\n .trim();\n\nlet data;\n\ntry {\n data = JSON.parse(respuesta);\n} catch (error) {\n throw new Error(\n 'Flowise no devolvió JSON válido. Respuesta recibida: ' + respuesta\n );\n}\n\nconst camposObligatorios = [\n 'responsable_nombre',\n 'responsable_email',\n 'cliente',\n 'titulo',\n 'problema',\n 'solucion',\n 'resultado',\n 'area',\n 'confidence',\n];\n\nfor (const campo of camposObligatorios) {\n if (!(campo in data)) {\n data[campo] = null;\n }\n}\n\nreturn [\n {\n json: {\n ...data,\n fuente: 'gmail_flowise_mvp',\n procesado_en: new Date().toISOString(),\n },\n },\n];"
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.code",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
960,
|
||||||
|
-96
|
||||||
|
],
|
||||||
|
"id": "cd88f8fb-d68b-4990-8ee1-a2bb0c85d9fe",
|
||||||
|
"name": "Code - Parsear JSON Flowise"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"conditions": {
|
||||||
|
"options": {
|
||||||
|
"caseSensitive": true,
|
||||||
|
"leftValue": "",
|
||||||
|
"typeValidation": "strict",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"id": "a73cb1f1-a67f-4023-8454-9b9e9dec51b4",
|
||||||
|
"leftValue": "={{ $json.confidence }}",
|
||||||
|
"rightValue": 0.6,
|
||||||
|
"operator": {
|
||||||
|
"type": "number",
|
||||||
|
"operation": "gte"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"combinator": "and"
|
||||||
|
},
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.if",
|
||||||
|
"typeVersion": 2.3,
|
||||||
|
"position": [
|
||||||
|
1168,
|
||||||
|
-96
|
||||||
|
],
|
||||||
|
"id": "020c0fcd-1aa9-4a64-be98-3cd9ee47f6be",
|
||||||
|
"name": "If"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"jsCode": "const data = $input.first().json;\n\nfunction texto(valor, fallback = '') {\n return String(valor ?? fallback).trim();\n}\n\nconst responsableEmail = texto(data.responsable_email || 'desconocido@gomezleemarketing.com').toLowerCase();\nconst responsableNombre = texto(data.responsable_nombre || 'Responsable no identificado');\nconst cliente = texto(data.cliente || 'Cliente no identificado');\nconst titulo = texto(data.titulo || 'Caso sin título');\nconst problema = texto(data.problema || 'Problema no identificado');\nconst solucion = texto(data.solucion || 'Solución no identificada');\nconst resultado = texto(data.resultado || 'Resultado no identificado');\nconst area = texto(data.area || 'Área no identificada');\nconst confidence = Number(data.confidence ?? 0);\nconst fuente = texto(data.fuente || 'gmail_flowise_mvp');\nconst procesadoEn = texto(data.procesado_en || new Date().toISOString());\n\nconst cypher = `\nMERGE (empleado:Empleado {email: $responsableEmail})\nSET empleado.nombre = $responsableNombre,\n empleado.area = $area,\n empleado.actualizado_en = datetime()\n\nMERGE (cliente:Cliente {nombre: $cliente})\nSET cliente.actualizado_en = datetime()\n\nCREATE (caso:CasoResuelto {\n id: randomUUID(),\n titulo: $titulo,\n problema: $problema,\n solucion: $solucion,\n resultado: $resultado,\n area: $area,\n confidence: $confidence,\n fuente: $fuente,\n procesado_en: datetime($procesadoEn),\n fecha_captura: datetime()\n})\n\nMERGE (empleado)-[:RESOLVIO]->(caso)\nMERGE (caso)-[:PERTENECE_A_CLIENTE]->(cliente)\n\nRETURN caso.id AS caso_id,\n caso.titulo AS titulo,\n empleado.nombre AS responsable,\n cliente.nombre AS cliente;\n`;\n\nreturn [\n {\n json: {\n cypher,\n parameters: {\n responsableEmail,\n responsableNombre,\n cliente,\n titulo,\n problema,\n solucion,\n resultado,\n area,\n confidence,\n fuente,\n procesadoEn,\n },\n },\n },\n];"
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.code",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
1648,
|
||||||
|
-128
|
||||||
|
],
|
||||||
|
"id": "792b2605-b658-4ac5-8cfd-f0148895bd80",
|
||||||
|
"name": "Code - Preparar Cypher Neo4j"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"method": "POST",
|
||||||
|
"url": "http://neo4j:7474/db/neo4j/tx/commit",
|
||||||
|
"authentication": "genericCredentialType",
|
||||||
|
"genericAuthType": "httpBasicAuth",
|
||||||
|
"sendHeaders": true,
|
||||||
|
"headerParameters": {
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "Content-Type",
|
||||||
|
"value": "application/json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Accept",
|
||||||
|
"value": " application/json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"sendBody": true,
|
||||||
|
"specifyBody": "json",
|
||||||
|
"jsonBody": "={{\n {\n statements: [\n {\n statement: $json.cypher,\n parameters: $json.parameters\n }\n ]\n }\n}}",
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.httpRequest",
|
||||||
|
"typeVersion": 4.4,
|
||||||
|
"position": [
|
||||||
|
1856,
|
||||||
|
-128
|
||||||
|
],
|
||||||
|
"id": "cc3b3878-dd68-499d-8f1f-f5e287bc5c11",
|
||||||
|
"name": "HTTP Request - Crear caso en Neo4j",
|
||||||
|
"credentials": {
|
||||||
|
"httpBasicAuth": {
|
||||||
|
"id": "nIxZ7elcHvuzsRKW",
|
||||||
|
"name": "Neo4j"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"content": "## Entrada controlada \n\nEste flujo solo procesa correos de prueba.\n\nGmail recibe el correo, n8n normaliza el asunto/cuerpo y el IF evita procesar correos que no pertenezcan al MVP.\n",
|
||||||
|
"height": 288,
|
||||||
|
"width": 768,
|
||||||
|
"color": 6
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.stickyNote",
|
||||||
|
"typeVersion": 1,
|
||||||
|
"position": [
|
||||||
|
-192,
|
||||||
|
-208
|
||||||
|
],
|
||||||
|
"id": "fe25ffcb-41c7-460e-9ded-c368cfd5ae45",
|
||||||
|
"name": "Sticky Note"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"content": "## Extracción inteligente con Flowise\n\nn8n envía el cuerpo del correo a Flowise.\n\nFlowise devuelve un JSON estructurado con responsable, cliente, título, problema, solución, resultado, área y confidence.\n\nSolo los casos con confidence suficiente continúan hacia Neo4j.\n",
|
||||||
|
"height": 384,
|
||||||
|
"width": 688
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.stickyNote",
|
||||||
|
"typeVersion": 1,
|
||||||
|
"position": [
|
||||||
|
688,
|
||||||
|
-272
|
||||||
|
],
|
||||||
|
"id": "8df77283-b1ad-4e19-b9a6-30f8034e7608",
|
||||||
|
"name": "Sticky Note1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"content": "## Registro en Neo4j y confirmación\n\nn8n convierte el JSON en una consulta Cypher y crea el caso en Neo4j.\n\nSe crean/actualizan nodos de Empleado, Cliente y CasoResuelto, con sus relaciones.\n\n",
|
||||||
|
"height": 384,
|
||||||
|
"width": 688,
|
||||||
|
"color": "#0E6808"
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.stickyNote",
|
||||||
|
"typeVersion": 1,
|
||||||
|
"position": [
|
||||||
|
1456,
|
||||||
|
-288
|
||||||
|
],
|
||||||
|
"id": "72c16df2-30a4-441e-9b38-e14e62c43040",
|
||||||
|
"name": "Sticky Note2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"connections": {
|
||||||
|
"Gmail Trigger": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Code - Normalizar correo MVP Sofía",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"IF - Es correo MVP Sofía": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "HTTP Request - Flowise extraer caso",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Code - Normalizar correo MVP Sofía": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "IF - Es correo MVP Sofía",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"HTTP Request - Flowise extraer caso": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Code - Parsear JSON Flowise",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Code - Parsear JSON Flowise": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "If",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"If": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Code - Preparar Cypher Neo4j",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Code - Preparar Cypher Neo4j": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "HTTP Request - Crear caso en Neo4j",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"HTTP Request - Crear caso en Neo4j": {
|
||||||
|
"main": [
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"authors": "Isaac Aracena",
|
||||||
|
"name": "Version da03274d",
|
||||||
|
"description": "",
|
||||||
|
"autosaved": true,
|
||||||
|
"workflowPublishHistory": [
|
||||||
|
{
|
||||||
|
"createdAt": "2026-06-09T19:00:41.252Z",
|
||||||
|
"id": 1273,
|
||||||
|
"workflowId": "1ykpTM58gz0iOxvK",
|
||||||
|
"versionId": "da03274d-aca0-4d78-be28-6543d5ecad92",
|
||||||
|
"event": "activated",
|
||||||
|
"userId": "0a88c0b1-928e-4412-896e-c5d1c99b2029"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user