{ "name": "Comparador planilla", "nodes": [ { "parameters": { "numberInputs": 3 }, "type": "n8n-nodes-base.merge", "typeVersion": 3.2, "position": [ 1312, 256 ], "id": "307f53e3-ffbd-456f-8dec-ca8aee9e0bfc", "name": "Merge - Esperar los 3 insumos2" }, { "parameters": { "jsCode": "const sheetItems = $('Get row(s) in sheet').all();\nconst pdf1938Items = $('Primera planilla').all();\nconst pdf1967Items = $('Segunda planilla').all();\n\nfunction clean(value) {\n return String(value ?? '').trim();\n}\n\nfunction normalizeText(value) {\n return clean(value)\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .toLowerCase();\n}\n\nfunction compactId(value) {\n return clean(value)\n .toUpperCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^A-Z0-9]/g, '');\n}\n\nfunction compactName(value) {\n return clean(value)\n .toUpperCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^A-Z]/g, '');\n}\n\nfunction idVariants(value) {\n const compact = compactId(value);\n const noLeadingZeros = compact.replace(/^0+/, '');\n\n return [...new Set([compact, noLeadingZeros])]\n .filter(v => v && v.length >= 4);\n}\n\nfunction collectAllText(value) {\n if (value === null || value === undefined) return '';\n\n if (typeof value === 'string' || typeof value === 'number') {\n return String(value);\n }\n\n if (Array.isArray(value)) {\n return value.map(collectAllText).join('\\n');\n }\n\n if (typeof value === 'object') {\n return Object.values(value).map(collectAllText).join('\\n');\n }\n\n return '';\n}\n\nfunction pdfItemsToCompactText(items) {\n const fullText = items\n .map(item => collectAllText(item.json))\n .join('\\n');\n\n return fullText\n .toUpperCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^A-Z0-9]/g, '');\n}\n\nfunction pdfHasId(pdfCompactText, cedula) {\n return idVariants(cedula).some(id => pdfCompactText.includes(id));\n}\n\nfunction pdfHasName(pdfCompactText, nombre, apellido) {\n const n = compactName(nombre);\n const a = compactName(apellido);\n\n if (!n || !a) return false;\n if (n.length < 3 || a.length < 3) return false;\n\n const apellidoNombre = `${a}${n}`;\n const nombreApellido = `${n}${a}`;\n\n return (\n pdfCompactText.includes(apellidoNombre) ||\n pdfCompactText.includes(nombreApellido)\n );\n}\n\nfunction pdfHasEmployee(pdfCompactText, emp) {\n return (\n pdfHasId(pdfCompactText, emp.cedula) ||\n pdfHasName(pdfCompactText, emp.nombre, emp.apellido)\n );\n}\n\nfunction rowToArray(row) {\n const values = [];\n\n for (const [key, value] of Object.entries(row)) {\n if (key === 'row_number') continue;\n values.push(clean(value));\n }\n\n return values;\n}\n\nfunction looksLikeCedula(value) {\n const v = clean(value).toUpperCase();\n\n return (\n /^\\d{1,2}-\\d{1,4}-\\d{1,5}$/.test(v) ||\n /^E-\\d{1,2}-\\d{1,6}$/.test(v) ||\n /^[A-Z]{1,4}\\s?\\d{4,12}$/.test(v) ||\n /^\\d{5,12}$/.test(v)\n );\n}\n\nfunction extractEmpleadosFromBlockSheet(items) {\n const rows = items.map(item => rowToArray(item.json));\n const empleados = [];\n\n for (let i = 0; i < rows.length - 1; i++) {\n const row = rows[i].map(normalizeText);\n\n const seguroSocialIndex = row.findIndex(v => v === 'seguro social');\n\n const cedulaIndex = row.findIndex(v =>\n v === 'cedula' ||\n v === 'cedula/pasaporte' ||\n v === 'cedula / pasaporte' ||\n v === 'pasaporte'\n );\n\n const apellidoIndex = row.findIndex(v =>\n v === 'apellido' ||\n v === 'apellidos'\n );\n\n const nombreIndex = row.findIndex(v =>\n v === 'nombre' ||\n v === 'nombres'\n );\n\n if (cedulaIndex === -1) continue;\n\n const nextRow = rows[i + 1];\n\n const cedula = clean(nextRow[cedulaIndex]);\n const nombre = nombreIndex !== -1 ? clean(nextRow[nombreIndex]) : '';\n const apellido = apellidoIndex !== -1 ? clean(nextRow[apellidoIndex]) : '';\n const seguroSocial = seguroSocialIndex !== -1 ? clean(nextRow[seguroSocialIndex]) : '';\n\n if (!cedula || !looksLikeCedula(cedula)) continue;\n\n empleados.push({\n cedula,\n nombre,\n apellido,\n seguroSocial,\n filaGoogleSheet: items[i + 1]?.json?.row_number ?? i + 2,\n });\n }\n\n return empleados;\n}\n\nconst empleados = extractEmpleadosFromBlockSheet(sheetItems);\n\nif (empleados.length === 0) {\n return [{\n json: {\n Cedula: '',\n Nombre: '',\n Apellido: '',\n En_Planilla_1938: '',\n En_Planilla_1967: '',\n Estado: 'ERROR - No se encontraron cédulas en el Google Sheet. Revisa que el nodo Google Sheets esté leyendo la hoja correcta.',\n }\n }];\n}\n\nconst pdf1938CompactText = pdfItemsToCompactText(pdf1938Items);\nconst pdf1967CompactText = pdfItemsToCompactText(pdf1967Items);\n\nif (!pdf1938CompactText || !pdf1967CompactText) {\n return [{\n json: {\n Cedula: '',\n Nombre: '',\n Apellido: '',\n En_Planilla_1938: '',\n En_Planilla_1967: '',\n Estado: 'ERROR - Uno de los PDF no devolvió texto. Revisa los nodos Extract From File.',\n }\n }];\n}\n\nconst reporte = empleados.map(emp => {\n const en1938 = pdfHasEmployee(pdf1938CompactText, emp);\n const en1967 = pdfHasEmployee(pdf1967CompactText, emp);\n\n let estado = 'OK';\n\n if (!en1938 && !en1967) {\n estado = 'Falta en ambas planillas';\n } else if (!en1938) {\n estado = 'Falta en Planilla 1938';\n } else if (!en1967) {\n estado = 'Falta en Planilla 1967';\n }\n\n return {\n json: {\n Cedula: emp.cedula,\n Nombre: emp.nombre,\n Apellido: emp.apellido,\n En_Planilla_1938: en1938 ? 'Sí' : 'No',\n En_Planilla_1967: en1967 ? 'Sí' : 'No',\n Estado: estado,\n }\n };\n});\n\nconst faltantes = reporte.filter(item => item.json.Estado !== 'OK');\n\nif (faltantes.length === 0) {\n return [{\n json: {\n Cedula: '',\n Nombre: '',\n Apellido: '',\n En_Planilla_1938: 'Sí',\n En_Planilla_1967: 'Sí',\n Estado: 'OK - Todas las cédulas aparecen en ambas planillas',\n }\n }];\n}\n\nreturn faltantes;" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 1552, 272 ], "id": "de268977-eeb8-440d-a229-8aec8726cf32", "name": "Code - Comparar Cedulas2" }, { "parameters": { "jsCode": "return $('Code - Comparar Cedulas2').all();" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 1808, 272 ], "id": "a7c6984e-26be-4631-bd45-402687bed312", "name": "Code - Recuperar Reporte2" }, { "parameters": { "content": "## INICIO Y FUENTES DE DATOS\n\n**Webhook**: Trae las URLs insertada en el frontend.\n\n**Switch**: Si hay dos planillas, activará la ruta 0. Si hay una sola planilla, activará la ruta 1. ", "height": 304, "width": 432, "color": 4 }, "type": "n8n-nodes-base.stickyNote", "position": [ -144, 144 ], "typeVersion": 1, "id": "59d2207f-6a2c-40c3-8a2e-8d896afbbaae", "name": "Sticky Note" }, { "parameters": { "content": "## UNIFICAR INSUMOS\n\nEste nodo espera las 3 fuentes necesarias:\n\nInput 1: Google Sheet base.\nInput 2: Texto extraído del PDF primera planilla.\nInput 3: Texto extraído del PDF segunda planilla.\n\nModo: Append.", "height": 1104, "color": 7 }, "type": "n8n-nodes-base.stickyNote", "position": [ 1232, -16 ], "typeVersion": 1, "id": "f6f2a5ea-52ab-4501-a8b6-aa6c63813ed1", "name": "Sticky Note8" }, { "parameters": { "content": "## VALIDACIÓN PRINCIPAL\n\nEste nodo lee las cédulas desde el Google Sheet, normaliza los formatos y valida si cada cédula aparece en los dos PDF de nómina.\n\nDevuelve solo los empleados que faltan en una o ambas planillas.", "height": 1104, "width": 208 }, "type": "n8n-nodes-base.stickyNote", "position": [ 1504, -16 ], "typeVersion": 1, "id": "77fc241e-d934-454e-9f9b-86d0525202ae", "name": "Sticky Note9" }, { "parameters": { "content": "## REPORTE FINAL\n\nCode - Recuperar Reporte trae nuevamente los resultados.\n", "height": 960, "color": 5 }, "type": "n8n-nodes-base.stickyNote", "position": [ 1744, 128 ], "typeVersion": 1, "id": "69602e51-72ff-4125-bc8e-5530352a6d61", "name": "Sticky Note10" }, { "parameters": { "rules": { "values": [ { "conditions": { "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict", "version": 3 }, "conditions": [ { "leftValue": "={{ $json.body.planilla1 && $json.body.planilla2 }}", "rightValue": "", "operator": { "type": "string", "operation": "notEmpty", "singleValue": true }, "id": "15e876da-9674-4627-9dfe-c681aeaea7de" } ], "combinator": "and" } }, { "conditions": { "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict", "version": 3 }, "conditions": [ { "id": "2d722b7a-d31b-4e20-b219-1889f4246781", "leftValue": "={{ !$json.body.planilla1 || !$json.body.planilla2 ? 'vacio' : 'con_datos' }}", "rightValue": "vacio", "operator": { "type": "string", "operation": "equals" } } ], "combinator": "and" } } ] }, "options": {} }, "type": "n8n-nodes-base.switch", "typeVersion": 3.4, "position": [ 144, 288 ], "id": "b2a9bc1c-92e0-43e7-ac97-a29b5c2fcacf", "name": "Switch1" }, { "parameters": { "documentId": { "__rl": true, "value": "166MSfOI_d44RajTOaQtky_2WNIAhS9vdB5T73cZbyWw", "mode": "list", "cachedResultName": "TSS", "cachedResultUrl": "https://docs.google.com/spreadsheets/d/166MSfOI_d44RajTOaQtky_2WNIAhS9vdB5T73cZbyWw/edit?usp=drivesdk" }, "sheetName": { "__rl": true, "value": 1599580508, "mode": "list", "cachedResultName": "TSS", "cachedResultUrl": "https://docs.google.com/spreadsheets/d/166MSfOI_d44RajTOaQtky_2WNIAhS9vdB5T73cZbyWw/edit#gid=1599580508" }, "options": {} }, "type": "n8n-nodes-base.googleSheets", "typeVersion": 4.7, "position": [ 1024, 96 ], "id": "4d80bc10-2133-48ba-bed9-32501ebbe4a0", "name": "Get row(s) in sheet", "retryOnFail": true, "credentials": { "googleSheetsOAuth2Api": { "id": "8Pp0ek3NPsEkyXfY", "name": "Eidan - Google Sheets account" } } }, { "parameters": { "documentId": { "__rl": true, "value": "166MSfOI_d44RajTOaQtky_2WNIAhS9vdB5T73cZbyWw", "mode": "list", "cachedResultName": "TSS", "cachedResultUrl": "https://docs.google.com/spreadsheets/d/166MSfOI_d44RajTOaQtky_2WNIAhS9vdB5T73cZbyWw/edit?usp=drivesdk" }, "sheetName": { "__rl": true, "value": 1599580508, "mode": "list", "cachedResultName": "TSS", "cachedResultUrl": "https://docs.google.com/spreadsheets/d/166MSfOI_d44RajTOaQtky_2WNIAhS9vdB5T73cZbyWw/edit#gid=1599580508" }, "options": {} }, "type": "n8n-nodes-base.googleSheets", "typeVersion": 4.7, "position": [ 1024, 688 ], "id": "ab7c6cef-1be2-4804-92a1-849d6a2beb0b", "name": "Get row(s) in sheet3", "retryOnFail": true, "credentials": { "googleSheetsOAuth2Api": { "id": "8Pp0ek3NPsEkyXfY", "name": "Eidan - Google Sheets account" } } }, { "parameters": { "jsCode": "const sheetItems = $('Get row(s) in sheet3').all();\nconst quincena = $('Planilla').all();\n//const pdf1967Items = $('Segunda planilla').all();\n\nfunction clean(value) {\n return String(value ?? '').trim();\n}\n\nfunction normalizeText(value) {\n return clean(value)\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .toLowerCase();\n}\n\nfunction compactId(value) {\n return clean(value)\n .toUpperCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^A-Z0-9]/g, '');\n}\n\nfunction compactName(value) {\n return clean(value)\n .toUpperCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^A-Z]/g, '');\n}\n\nfunction idVariants(value) {\n const compact = compactId(value);\n const noLeadingZeros = compact.replace(/^0+/, '');\n\n return [...new Set([compact, noLeadingZeros])]\n .filter(v => v && v.length >= 4);\n}\n\nfunction collectAllText(value) {\n if (value === null || value === undefined) return '';\n\n if (typeof value === 'string' || typeof value === 'number') {\n return String(value);\n }\n\n if (Array.isArray(value)) {\n return value.map(collectAllText).join('\\n');\n }\n\n if (typeof value === 'object') {\n return Object.values(value).map(collectAllText).join('\\n');\n }\n\n return '';\n}\n\nfunction pdfItemsToCompactText(items) {\n const fullText = items\n .map(item => collectAllText(item.json))\n .join('\\n');\n\n return fullText\n .toUpperCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^A-Z0-9]/g, '');\n}\n\nfunction pdfHasId(pdfCompactText, cedula) {\n return idVariants(cedula).some(id => pdfCompactText.includes(id));\n}\n\nfunction pdfHasName(pdfCompactText, nombre, apellido) {\n const n = compactName(nombre);\n const a = compactName(apellido);\n\n if (!n || !a) return false;\n if (n.length < 3 || a.length < 3) return false;\n\n const apellidoNombre = `${a}${n}`;\n const nombreApellido = `${n}${a}`;\n\n return (\n pdfCompactText.includes(apellidoNombre) ||\n pdfCompactText.includes(nombreApellido)\n );\n}\n\nfunction pdfHasEmployee(pdfCompactText, emp) {\n return (\n pdfHasId(pdfCompactText, emp.cedula) ||\n pdfHasName(pdfCompactText, emp.nombre, emp.apellido)\n );\n}\n\nfunction rowToArray(row) {\n const values = [];\n\n for (const [key, value] of Object.entries(row)) {\n if (key === 'row_number') continue;\n values.push(clean(value));\n }\n\n return values;\n}\n\nfunction looksLikeCedula(value) {\n const v = clean(value).toUpperCase();\n\n return (\n /^\\d{1,2}-\\d{1,4}-\\d{1,5}$/.test(v) ||\n /^E-\\d{1,2}-\\d{1,6}$/.test(v) ||\n /^[A-Z]{1,4}\\s?\\d{4,12}$/.test(v) ||\n /^\\d{5,12}$/.test(v)\n );\n}\n\nfunction extractEmpleadosFromBlockSheet(items) {\n const rows = items.map(item => rowToArray(item.json));\n const empleados = [];\n\n for (let i = 0; i < rows.length - 1; i++) {\n const row = rows[i].map(normalizeText);\n\n const seguroSocialIndex = row.findIndex(v => v === 'seguro social');\n\n const cedulaIndex = row.findIndex(v =>\n v === 'cedula' ||\n v === 'cedula/pasaporte' ||\n v === 'cedula / pasaporte' ||\n v === 'pasaporte'\n );\n\n const apellidoIndex = row.findIndex(v =>\n v === 'apellido' ||\n v === 'apellidos'\n );\n\n const nombreIndex = row.findIndex(v =>\n v === 'nombre' ||\n v === 'nombres'\n );\n\n if (cedulaIndex === -1) continue;\n\n const nextRow = rows[i + 1];\n\n const cedula = clean(nextRow[cedulaIndex]);\n const nombre = nombreIndex !== -1 ? clean(nextRow[nombreIndex]) : '';\n const apellido = apellidoIndex !== -1 ? clean(nextRow[apellidoIndex]) : '';\n const seguroSocial = seguroSocialIndex !== -1 ? clean(nextRow[seguroSocialIndex]) : '';\n\n if (!cedula || !looksLikeCedula(cedula)) continue;\n\n empleados.push({\n cedula,\n nombre,\n apellido,\n seguroSocial,\n filaGoogleSheet: items[i + 1]?.json?.row_number ?? i + 2,\n });\n }\n\n return empleados;\n}\n\nconst empleados = extractEmpleadosFromBlockSheet(sheetItems);\n\nif (empleados.length === 0) {\n return [{\n json: {\n Cedula: '',\n Nombre: '',\n Apellido: '',\n En_Quincena: '',\n //En_Planilla_1967: '',\n Estado: 'ERROR - No se encontraron cédulas en el Google Sheet. Revisa que el nodo Google Sheets esté leyendo la hoja correcta.',\n }\n }];\n}\n\nconst pdf1938CompactText = pdfItemsToCompactText(quincena);\n//const pdf1967CompactText = pdfItemsToCompactText(pdf1967Items);\n\n//if (!pdf1938CompactText || !pdf1967CompactText) {\nif (!pdf1938CompactText) {\n return [{\n json: {\n Cedula: '',\n Nombre: '',\n Apellido: '',\n En_Quincena: '',\n //En_Planilla_1967: '',\n Estado: 'ERROR - Uno de los PDF no devolvió texto. Revisa los nodos Extract From File.',\n }\n }];\n}\n\nconst reporte = empleados.map(emp => {\n const en1938 = pdfHasEmployee(pdf1938CompactText, emp);\n //const en1967 = pdfHasEmployee(pdf1967CompactText, emp);\n\n let estado = 'OK';\n/*\n if (!en1938 && !en1967) {\n estado = 'Falta en ambas planillas';\n } else if (!en1938) {\n estado = 'Falta en Planilla 1938';\n } else if (!en1967) {\n estado = 'Falta en Planilla 1967';\n }\n*/\n if (!en1938) {\n estado = 'No está en la planilla'\n }\n\n return {\n json: {\n Cedula: emp.cedula,\n Nombre: emp.nombre,\n Apellido: emp.apellido,\n En_Quincena: en1938 ? 'Sí' : 'No',\n //En_Planilla_1967: en1967 ? 'Sí' : 'No',\n Estado: estado,\n }\n };\n});\n\nconst faltantes = reporte.filter(item => item.json.Estado !== 'OK');\n\nif (faltantes.length === 0) {\n return [{\n json: {\n Cedula: '',\n Nombre: '',\n Apellido: '',\n En_Quincena: 'Sí',\n //En_Planilla_1967: 'Sí',\n Estado: 'OK - Todas las cédulas aparecen en ambas planillas',\n }\n }];\n}\n\nreturn faltantes;" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 1552, 800 ], "id": "6c961178-84a0-4c86-bf3f-7e7f119504d3", "name": "Code - Comparar Cedulas3" }, { "parameters": { "jsCode": "return $('Code - Comparar Cedulas3').all();" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 1808, 800 ], "id": "349f6a47-a671-4c3e-86aa-135c4ba76474", "name": "Code - Recuperar Reporte3" }, { "parameters": { "jsCode": "return [\n {\n json: {\n data: $input.all().map(item => item.json)\n }\n }\n];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 2128, 544 ], "id": "31ef2d32-fe38-4949-b3fc-54effdf04800", "name": "Code in JavaScript7" }, { "parameters": { "httpMethod": "POST", "path": "nomina", "responseMode": "responseNode", "options": {} }, "type": "n8n-nodes-base.webhook", "typeVersion": 2.1, "position": [ -96, 288 ], "id": "0149f412-0f6e-441d-b165-d55d671e707c", "name": "Webhook", "webhookId": "b67eb939-9ebc-4769-97d4-e7e7365d3863" }, { "parameters": { "content": "## Procesar datos ", "height": 1120, "width": 768 }, "type": "n8n-nodes-base.stickyNote", "position": [ 400, -32 ], "typeVersion": 1, "id": "63f28c66-d400-48b5-a67c-1552ee359ca7", "name": "Sticky Note2" }, { "parameters": { "url": "=https://docs.google.com/spreadsheets/d/1GOD4drTGgXPZuMMnjzzE-QraxRc0ZrXPJBC7YD_vyaQ/export?format=csv", "authentication": "predefinedCredentialType", "nodeCredentialType": "googleDriveOAuth2Api", "options": { "response": { "response": { "responseFormat": "file" } } } }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ 656, 96 ], "id": "751589d7-2e31-4fe0-abbb-a45b79f55b1a", "name": "Descargar a CSV", "retryOnFail": true, "credentials": { "googleDriveOAuth2Api": { "id": "gL2ZTwJb6xojauac", "name": "Eidan - Google Drive account" } } }, { "parameters": { "name": "TSS", "driveId": { "__rl": true, "mode": "list", "value": "My Drive" }, "folderId": { "__rl": true, "value": "1c08rDipBOATxBEf6T1jmCaki3TW0cwUh", "mode": "list", "cachedResultName": "TSS", "cachedResultUrl": "https://drive.google.com/drive/folders/1c08rDipBOATxBEf6T1jmCaki3TW0cwUh" }, "options": {} }, "type": "n8n-nodes-base.googleDrive", "typeVersion": 3, "position": [ 832, 96 ], "id": "5a6da339-1b2d-42f6-89d2-0f22f266f2e6", "name": "Guardar archivo CSV", "retryOnFail": true, "credentials": { "googleDriveOAuth2Api": { "id": "gL2ZTwJb6xojauac", "name": "Eidan - Google Drive account" } } }, { "parameters": { "jsCode": "for (const item of $input.all()) {\n const url = $input.first().json.body.tssUrl;\n \n // Extraer el ID del Spreadsheet\n const spreadsheetRegex = /\\/d\\/([a-zA-Z0-9-_]+)/;\n const spreadsheetMatch = url.match(spreadsheetRegex);\n item.json.spreadsheetId = spreadsheetMatch ? spreadsheetMatch[1] : \"No encontrado\";\n\n // Extraer el ID de la Hoja (gid)\n const sheetRegex = /[#&]gid=([0-9]+)/;\n const sheetMatch = url.match(sheetRegex);\n \n // Como en tu URL no hay \"gid\", se asigna 0 por defecto\n item.json.sheetId = sheetMatch ? sheetMatch[1] : \"0\";\n}\n\nreturn $input.all();" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 480, 96 ], "id": "b898cd23-bb59-452e-bce2-aeb2dde795aa", "name": "ID del spreadsheet" }, { "parameters": { "options": {} }, "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.5, "position": [ 2352, 544 ], "id": "afc5931f-6a09-4b2f-8600-d59f2c0d532f", "name": "Respond to Webhook" }, { "parameters": { "jsCode": "for (const item of $input.all()) {\n const url = $input.first().json.body.planilla1;\n \n // Extraer el ID del archivo de Google Drive\n // Busca el patrón que sigue a \"/file/d/\" y termina antes de \"/view\"\n const fileIdRegex = /\\/file\\/d\\/([a-zA-Z0-9-_]+)/;\n const fileIdMatch = url.match(fileIdRegex);\n \n item.json.fileId = fileIdMatch ? fileIdMatch[1] : \"No encontrado\";\n\n // En archivos de Drive (PDF, etc.) no existe el \"sheetId\" o \"gid\", \n // por lo que eliminamos esa parte o la dejamos como nula.\n item.json.isDriveFile = true;\n}\n\nreturn $input.all();" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 480, 272 ], "id": "2cb03f47-fd7c-4430-ac1d-9682b98159d9", "name": "ID del PDF de la primera planilla" }, { "parameters": { "jsCode": "for (const item of $input.all()) {\n const url = $input.first().json.body.planilla2;\n \n // Extraer el ID del archivo de Google Drive\n // Busca el patrón que sigue a \"/file/d/\" y termina antes de \"/view\"\n const fileIdRegex = /\\/file\\/d\\/([a-zA-Z0-9-_]+)/;\n const fileIdMatch = url.match(fileIdRegex);\n \n item.json.fileId = fileIdMatch ? fileIdMatch[1] : \"No encontrado\";\n\n // En archivos de Drive (PDF, etc.) no existe el \"sheetId\" o \"gid\", \n // por lo que eliminamos esa parte o la dejamos como nula.\n item.json.isDriveFile = true;\n}\n\nreturn $input.all();" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 480, 448 ], "id": "0c60a069-b662-4920-96c5-c9b2d2bd46e2", "name": "ID del PDF de la segunda planilla" }, { "parameters": { "url": "=https://www.googleapis.com/drive/v3/files/{{ $json.fileId }}?alt=media", "authentication": "predefinedCredentialType", "nodeCredentialType": "googleDriveOAuth2Api", "options": { "response": { "response": { "responseFormat": "file" } } } }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ 656, 272 ], "id": "08b3517a-7b60-4eb6-b026-0e99263ffffa", "name": "Descargar primera planilla", "retryOnFail": true, "credentials": { "googleDriveOAuth2Api": { "id": "gL2ZTwJb6xojauac", "name": "Eidan - Google Drive account" } } }, { "parameters": { "url": "=https://www.googleapis.com/drive/v3/files/{{ $json.fileId }}?alt=media", "authentication": "predefinedCredentialType", "nodeCredentialType": "googleDriveOAuth2Api", "options": { "response": { "response": { "responseFormat": "file" } } } }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ 656, 448 ], "id": "3ed444be-b1c0-4793-88ac-6af6243f160b", "name": "Descargar segunda planilla", "retryOnFail": true, "credentials": { "googleDriveOAuth2Api": { "id": "gL2ZTwJb6xojauac", "name": "Eidan - Google Drive account" } } }, { "parameters": { "jsCode": "for (const item of $input.all()) {\n const url = $input.first().json.body.tssUrl;\n \n // Extraer el ID del Spreadsheet\n const spreadsheetRegex = /\\/d\\/([a-zA-Z0-9-_]+)/;\n const spreadsheetMatch = url.match(spreadsheetRegex);\n item.json.spreadsheetId = spreadsheetMatch ? spreadsheetMatch[1] : \"No encontrado\";\n\n // Extraer el ID de la Hoja (gid)\n const sheetRegex = /[#&]gid=([0-9]+)/;\n const sheetMatch = url.match(sheetRegex);\n \n // Como en tu URL no hay \"gid\", se asigna 0 por defecto\n item.json.sheetId = sheetMatch ? sheetMatch[1] : \"0\";\n}\n\nreturn $input.all();" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 480, 688 ], "id": "de247dce-c2e0-4b49-8ea8-0d3d188ff6a4", "name": "ID del spreadsheet1" }, { "parameters": { "jsCode": "for (const item of $input.all()) {\n const url = $input.first().json.body.planilla1 || $input.first().json.body.planilla2;\n \n // Extraer el ID del archivo de Google Drive\n // Busca el patrón que sigue a \"/file/d/\" y termina antes de \"/view\"\n const fileIdRegex = /\\/file\\/d\\/([a-zA-Z0-9-_]+)/;\n const fileIdMatch = url.match(fileIdRegex);\n \n item.json.fileId = fileIdMatch ? fileIdMatch[1] : \"No encontrado\";\n\n // En archivos de Drive (PDF, etc.) no existe el \"sheetId\" o \"gid\", \n // por lo que eliminamos esa parte o la dejamos como nula.\n item.json.isDriveFile = true;\n}\n\nreturn $input.all();" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 480, 896 ], "id": "75183ac3-e569-49a0-a3b3-a31275731f19", "name": "ID del PDF de la planilla" }, { "parameters": { "operation": "pdf", "options": {} }, "type": "n8n-nodes-base.extractFromFile", "typeVersion": 1.1, "position": [ 832, 272 ], "id": "89c9942c-003d-4c90-aca8-0e519ef09811", "name": "Primera planilla", "retryOnFail": true }, { "parameters": { "operation": "pdf", "options": {} }, "type": "n8n-nodes-base.extractFromFile", "typeVersion": 1.1, "position": [ 832, 448 ], "id": "c201147b-bb33-436e-a58a-f3a12d9bf3b1", "name": "Segunda planilla", "retryOnFail": true }, { "parameters": { "url": "=https://docs.google.com/spreadsheets/d/1GOD4drTGgXPZuMMnjzzE-QraxRc0ZrXPJBC7YD_vyaQ/export?format=csv", "authentication": "predefinedCredentialType", "nodeCredentialType": "googleDriveOAuth2Api", "options": { "response": { "response": { "responseFormat": "file" } } } }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ 656, 688 ], "id": "c3542086-79d8-4582-8452-2aa38f865fab", "name": "Descargar a CSV1", "retryOnFail": true, "credentials": { "googleDriveOAuth2Api": { "id": "gL2ZTwJb6xojauac", "name": "Eidan - Google Drive account" } } }, { "parameters": { "url": "=https://www.googleapis.com/drive/v3/files/{{ $json.fileId }}?alt=media", "authentication": "predefinedCredentialType", "nodeCredentialType": "googleDriveOAuth2Api", "options": { "response": { "response": { "responseFormat": "file" } } } }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ 656, 896 ], "id": "300d158c-5cd1-4dd0-bca6-23cbe800ea38", "name": "Descargar planilla", "retryOnFail": true, "credentials": { "googleDriveOAuth2Api": { "id": "gL2ZTwJb6xojauac", "name": "Eidan - Google Drive account" } } }, { "parameters": { "operation": "pdf", "options": {} }, "type": "n8n-nodes-base.extractFromFile", "typeVersion": 1.1, "position": [ 832, 896 ], "id": "396ac651-5784-422a-b829-8cbcbbc17090", "name": "Planilla", "retryOnFail": true }, { "parameters": {}, "type": "n8n-nodes-base.merge", "typeVersion": 3.2, "position": [ 1312, 800 ], "id": "a250c4a5-b883-41b3-a47e-b09128ac0e8e", "name": "Merge - Esperar los 2 insumos" }, { "parameters": { "content": " \n**Extraer el ID de la URL** ", "height": 1008, "width": 160, "color": 3 }, "type": "n8n-nodes-base.stickyNote", "position": [ 448, 32 ], "typeVersion": 1, "id": "afeb7ce3-9d95-4271-9626-b2f774afe4dc", "name": "Sticky Note1" }, { "parameters": { "content": " \n**Descargar archivo** ", "height": 1008, "width": 150, "color": 3 }, "type": "n8n-nodes-base.stickyNote", "position": [ 624, 32 ], "typeVersion": 1, "id": "a62279b8-8c7b-4c72-b18c-2d185a06a00f", "name": "Sticky Note3" }, { "parameters": { "content": " \n**Guardar archivo** ", "height": 192, "width": 150, "color": 3 }, "type": "n8n-nodes-base.stickyNote", "position": [ 800, 32 ], "typeVersion": 1, "id": "184b6ae9-4e89-4c7a-9807-d0deabb59003", "name": "Sticky Note4" }, { "parameters": { "content": " \n**Guardar archivo** ", "height": 192, "width": 150, "color": 3 }, "type": "n8n-nodes-base.stickyNote", "position": [ 800, 640 ], "typeVersion": 1, "id": "80084a9c-0d74-4b4a-9cbc-db0db238122c", "name": "Sticky Note5" }, { "parameters": { "content": " \n**Descargar binario** ", "height": 352, "width": 150, "color": 3 }, "type": "n8n-nodes-base.stickyNote", "position": [ 800, 240 ], "typeVersion": 1, "id": "31b4ced0-ca9e-4033-b3b6-e43355a8e617", "name": "Sticky Note6" }, { "parameters": { "content": " \n**Descargar binario** ", "height": 176, "width": 150, "color": 3 }, "type": "n8n-nodes-base.stickyNote", "position": [ 800, 864 ], "typeVersion": 1, "id": "7a2f4a1d-eec4-40e4-b6fe-996d37922db3", "name": "Sticky Note7" }, { "parameters": { "content": " \n**Extraer datos** ", "height": 192, "width": 150, "color": 3 }, "type": "n8n-nodes-base.stickyNote", "position": [ 992, 640 ], "typeVersion": 1, "id": "c13efed6-6ead-46fe-97be-38b10ce936b0", "name": "Sticky Note11" }, { "parameters": { "content": " \n**Extraer datos** ", "height": 192, "width": 150, "color": 3 }, "type": "n8n-nodes-base.stickyNote", "position": [ 992, 32 ], "typeVersion": 1, "id": "75edfe2e-a73c-486b-86d5-cb9d841ed5eb", "name": "Sticky Note12" }, { "parameters": { "operation": "deleteFile", "fileId": { "__rl": true, "value": "={{ $('Guardar archivo CSV').first().json.id }}", "mode": "id" }, "options": {} }, "type": "n8n-nodes-base.googleDrive", "typeVersion": 3, "position": [ 2112, 272 ], "id": "4ccdc650-d54a-439e-b052-1b68888ec678", "name": "Eliminar archivo TSS", "retryOnFail": true, "credentials": { "googleDriveOAuth2Api": { "id": "gL2ZTwJb6xojauac", "name": "Eidan - Google Drive account" } } }, { "parameters": { "name": "TSS", "driveId": { "__rl": true, "mode": "list", "value": "My Drive" }, "folderId": { "__rl": true, "value": "1c08rDipBOATxBEf6T1jmCaki3TW0cwUh", "mode": "list", "cachedResultName": "TSS", "cachedResultUrl": "https://drive.google.com/drive/folders/1c08rDipBOATxBEf6T1jmCaki3TW0cwUh" }, "options": {} }, "type": "n8n-nodes-base.googleDrive", "typeVersion": 3, "position": [ 832, 688 ], "id": "1f77d3c2-2eb4-4c9b-9a56-55e0abbc13d3", "name": "Guardar archivo CSV1", "retryOnFail": true, "credentials": { "googleDriveOAuth2Api": { "id": "gL2ZTwJb6xojauac", "name": "Eidan - Google Drive account" } } }, { "parameters": { "operation": "deleteFile", "fileId": { "__rl": true, "value": "={{ $('Guardar archivo CSV1').first().json.id }}", "mode": "id" }, "options": {} }, "type": "n8n-nodes-base.googleDrive", "typeVersion": 3, "position": [ 2128, 800 ], "id": "79cc470a-5acb-4c75-b44b-d9fa43865a80", "name": "Eliminar archivo TSS1", "retryOnFail": true, "credentials": { "googleDriveOAuth2Api": { "id": "gL2ZTwJb6xojauac", "name": "Eidan - Google Drive account" } } }, { "parameters": { "content": " \n**Eliminar archivo TSS** ", "height": 192, "width": 166, "color": 3 }, "type": "n8n-nodes-base.stickyNote", "position": [ 2080, 224 ], "typeVersion": 1, "id": "2067949e-101e-41e0-9762-cc8f7c3acec7", "name": "Sticky Note13" }, { "parameters": { "content": " \n**Eliminar archivo TSS** ", "height": 192, "width": 166, "color": 3 }, "type": "n8n-nodes-base.stickyNote", "position": [ 2096, 752 ], "typeVersion": 1, "id": "6f7709ad-e017-4964-8cfa-a58c8a47d2b0", "name": "Sticky Note14" }, { "parameters": { "content": " \n**Listar todos los items** ", "height": 192, "width": 182, "color": 3 }, "type": "n8n-nodes-base.stickyNote", "position": [ 2080, 496 ], "typeVersion": 1, "id": "2e52ed34-6182-4c63-b19c-689a95240ebe", "name": "Sticky Note15" } ], "pinData": {}, "connections": { "Merge - Esperar los 3 insumos2": { "main": [ [ { "node": "Code - Comparar Cedulas2", "type": "main", "index": 0 } ] ] }, "Code - Comparar Cedulas2": { "main": [ [ { "node": "Code - Recuperar Reporte2", "type": "main", "index": 0 } ] ] }, "Code - Recuperar Reporte2": { "main": [ [ { "node": "Code in JavaScript7", "type": "main", "index": 0 }, { "node": "Eliminar archivo TSS", "type": "main", "index": 0 } ] ] }, "Switch1": { "main": [ [ { "node": "ID del spreadsheet", "type": "main", "index": 0 }, { "node": "ID del PDF de la primera planilla", "type": "main", "index": 0 }, { "node": "ID del PDF de la segunda planilla", "type": "main", "index": 0 } ], [ { "node": "ID del spreadsheet1", "type": "main", "index": 0 }, { "node": "ID del PDF de la planilla", "type": "main", "index": 0 } ] ] }, "Get row(s) in sheet": { "main": [ [ { "node": "Merge - Esperar los 3 insumos2", "type": "main", "index": 0 } ] ] }, "Get row(s) in sheet3": { "main": [ [ { "node": "Merge - Esperar los 2 insumos", "type": "main", "index": 0 } ] ] }, "Code - Comparar Cedulas3": { "main": [ [ { "node": "Code - Recuperar Reporte3", "type": "main", "index": 0 } ] ] }, "Code - Recuperar Reporte3": { "main": [ [ { "node": "Code in JavaScript7", "type": "main", "index": 0 }, { "node": "Eliminar archivo TSS1", "type": "main", "index": 0 } ] ] }, "Code in JavaScript7": { "main": [ [ { "node": "Respond to Webhook", "type": "main", "index": 0 } ] ] }, "Webhook": { "main": [ [ { "node": "Switch1", "type": "main", "index": 0 } ] ] }, "Descargar a CSV": { "main": [ [ { "node": "Guardar archivo CSV", "type": "main", "index": 0 } ] ] }, "Guardar archivo CSV": { "main": [ [ { "node": "Get row(s) in sheet", "type": "main", "index": 0 } ] ] }, "ID del spreadsheet": { "main": [ [ { "node": "Descargar a CSV", "type": "main", "index": 0 } ] ] }, "ID del PDF de la primera planilla": { "main": [ [ { "node": "Descargar primera planilla", "type": "main", "index": 0 } ] ] }, "ID del PDF de la segunda planilla": { "main": [ [ { "node": "Descargar segunda planilla", "type": "main", "index": 0 } ] ] }, "Descargar primera planilla": { "main": [ [ { "node": "Primera planilla", "type": "main", "index": 0 } ] ] }, "Descargar segunda planilla": { "main": [ [ { "node": "Segunda planilla", "type": "main", "index": 0 } ] ] }, "ID del spreadsheet1": { "main": [ [ { "node": "Descargar a CSV1", "type": "main", "index": 0 } ] ] }, "ID del PDF de la planilla": { "main": [ [ { "node": "Descargar planilla", "type": "main", "index": 0 } ] ] }, "Primera planilla": { "main": [ [ { "node": "Merge - Esperar los 3 insumos2", "type": "main", "index": 1 } ] ] }, "Segunda planilla": { "main": [ [ { "node": "Merge - Esperar los 3 insumos2", "type": "main", "index": 2 } ] ] }, "Descargar a CSV1": { "main": [ [ { "node": "Guardar archivo CSV1", "type": "main", "index": 0 } ] ] }, "Descargar planilla": { "main": [ [ { "node": "Planilla", "type": "main", "index": 0 } ] ] }, "Planilla": { "main": [ [ { "node": "Merge - Esperar los 2 insumos", "type": "main", "index": 1 } ] ] }, "Merge - Esperar los 2 insumos": { "main": [ [ { "node": "Code - Comparar Cedulas3", "type": "main", "index": 0 } ] ] }, "Respond to Webhook": { "main": [ [] ] }, "Guardar archivo CSV1": { "main": [ [ { "node": "Get row(s) in sheet3", "type": "main", "index": 0 } ] ] } }, "active": true, "settings": { "executionOrder": "v1", "binaryMode": "separate", "timeSavedMode": "fixed", "errorWorkflow": "lX5ITf9s4TSQglsM", "timezone": "America/Santo_Domingo", "callerPolicy": "workflowsFromSameOwner", "availableInMCP": false }, "versionId": "20eb764f-b87d-472b-a330-9b237fdba431", "meta": { "templateCredsSetupCompleted": true, "instanceId": "b4b77b17af092830e794eef639ce2f6d7daccf7eddc075060b03b3b6545aac70" }, "id": "8Oz31iFlkxqEcW64", "tags": [] }