{ "name": "Portal de Verificación de Nómina - Reportar corrección BambooHR a RRHH - GT TT PA SV HN", "nodes": [ { "parameters": { "httpMethod": "POST", "path": "cruce-cuentas-bamboo-correccion", "responseMode": "responseNode", "options": {} }, "type": "n8n-nodes-base.webhook", "typeVersion": 2.1, "position": [ 768, 1984 ], "id": "e5de6fd4-03ff-4d15-b567-24209b9596cc", "name": "Webhook", "webhookId": "821fa25f-8b4c-417b-870c-73183194a709" }, { "parameters": { "jsCode": "const incoming = $input.first().json || {};\nconst rawBody = incoming.body ?? incoming;\n\nlet body = rawBody;\n\nif (rawBody && typeof rawBody === 'object' && typeof rawBody.payload === 'string') {\n try {\n body = JSON.parse(rawBody.payload);\n } catch (error) {\n throw new Error('El payload recibido no contiene JSON válido.');\n }\n}\n\nif (!body || typeof body !== 'object') {\n throw new Error('No se recibió una solicitud válida.');\n}\n\nconst accessToken = String(\n (rawBody && typeof rawBody === 'object' ? rawBody.access_token : '') ||\n body.access_token ||\n ''\n).trim();\n\nfunction clean(value) {\n return String(value ?? '').replace(/\\s+/g, ' ').trim();\n}\n\nfunction normalizeName(value) {\n return clean(value)\n .toLowerCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^a-z0-9 ]/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nconst country = clean(body.country).toUpperCase();\nif (!['GT', 'TT', 'PA', 'SV', 'HN'].includes(country)) {\n throw new Error('País no permitido para reportar correcciones BambooHR.');\n}\n\nif (!accessToken) {\n throw new Error('No se recibió una sesión autenticada de Supabase.');\n}\n\nif (body.confirmed_same_person !== true) {\n throw new Error('La revisión manual debe confirmar que se trata de la misma persona.');\n}\n\nconst sourceNames = Array.from(new Set([\n ...(Array.isArray(body.source_names) ? body.source_names : []),\n body.source_name,\n body.bank_name_file,\n body.bank_account_holder,\n]\n .map(clean)\n .filter(Boolean)\n .filter((value) => normalizeName(value))));\n\nif (!sourceNames.length) {\n throw new Error('No se recibió el nombre detectado en Banco sin BambooHR.');\n}\n\nconst bambooName = clean(body.bamboo_name);\nif (!bambooName) {\n throw new Error('Debes indicar el nombre correcto en BambooHR.');\n}\n\nreturn [{\n json: {\n accessToken,\n request: {\n country,\n countryName: ({ GT: 'Guatemala', TT: 'Trinidad y Tobago', PA: 'Panamá', SV: 'El Salvador', HN: 'Honduras' })[country],\n sourceName: clean(body.source_name) || sourceNames[0],\n sourceNames,\n bankNameFile: clean(body.bank_name_file),\n bankAccountHolder: clean(body.bank_account_holder),\n bankAccount: clean(body.bank_account),\n bankAmount: Number.isFinite(Number(body.bank_amount)) ? Number(body.bank_amount) : null,\n currency: clean(body.currency) || ({ GT: 'GTQ', TT: 'TTD', PA: 'USD', SV: 'USD', HN: 'HNL' })[country],\n bambooName,\n bambooEmployeeNumber: clean(body.bamboo_employee_number),\n reason: clean(body.reason) || 'Corrección de identidad en BambooHR',\n comment: clean(body.comment),\n executionId: clean(body.execution_id),\n reportUrl: clean(body.report_url),\n periodLabel: clean(body.period_label),\n periodStart: clean(body.period_start),\n periodEnd: clean(body.period_end),\n requestedByNameClaimed: clean(body.requested_by_name),\n requestedByEmailClaimed: clean(body.requested_by_email).toLowerCase(),\n },\n },\n}];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 1008, 1984 ], "id": "569fbf65-f297-416b-988a-c8ab108899bb", "name": "Preparar solicitud" }, { "parameters": { "method": "POST", "url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cruce_cuentas_mi_acceso", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "apikey", "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE" }, { "name": "Authorization", "value": "={{ 'Bearer ' + $('Preparar solicitud').first().json.accessToken }}" }, { "name": "Content-Type", "value": "application/json" } ] }, "sendBody": true, "specifyBody": "json", "jsonBody": {}, "options": { "timeout": 30000 } }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ 1248, 1984 ], "id": "4b3bd35e-8097-4b1b-a665-b482d887e8d7", "name": "Validar acceso Supabase", "retryOnFail": true, "maxTries": 2, "waitBetweenTries": 1000 }, { "parameters": { "jsCode": "const raw = $input.first().json || {};\nconst access = Array.isArray(raw) ? (raw[0] || {}) : raw;\nconst prepared = $('Preparar solicitud').first().json || {};\nconst request = prepared.request || {};\n\nconst email = String(access.email || '').trim().toLowerCase();\nconst countries = Array.isArray(access.paises)\n ? access.paises.map((value) => String(value || '').trim().toUpperCase()).filter(Boolean)\n : [];\n\nif (\n access.ok !== true ||\n access.autenticado !== true ||\n access.autorizado !== true ||\n access.activo !== true ||\n access.acceso_app !== true ||\n !email\n) {\n throw new Error(access.motivo || 'El usuario no tiene acceso autorizado al Cruce de Cuentas.');\n}\n\nif (countries.length && !countries.includes(request.country)) {\n throw new Error(`El usuario autenticado no tiene acceso al país ${request.country}.`);\n}\n\nreturn [{\n json: {\n ...request,\n requestedByName: String(access.nombre || request.requestedByNameClaimed || email).trim(),\n requestedByEmail: email,\n },\n}];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 1488, 1984 ], "id": "67e4c922-7c87-4567-a1d9-4d9b676684db", "name": "Validar usuario" }, { "parameters": { "method": "POST", "url": "https://glm.bamboohr.com/api/v1/reports/custom?format=JSON&onlyCurrent=false", "authentication": "genericCredentialType", "genericAuthType": "httpBasicAuth", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "Accept", "value": "application/json" } ] }, "sendBody": true, "specifyBody": "json", "jsonBody": { "title": "Validación manual - Corrección identidad Cruce de Cuentas", "fields": [ "firstName", "middleName", "lastName", "displayName", "location", "status", "employeeNumber", "country" ] }, "options": { "response": { "response": { "responseFormat": "json" } }, "timeout": 300000 } }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ 1728, 1984 ], "id": "9d9b8120-c80b-456c-8bbe-c945755c1507", "name": "Consultar empleado BambooHR", "retryOnFail": true, "maxTries": 3, "waitBetweenTries": 3000, "credentials": { "httpBasicAuth": { "id": "7VrpNZ2jBLmiJ35q", "name": "BambooHR GLM Full Access" } } }, { "parameters": { "jsCode": "const request = $('Validar usuario').first().json || {};\nconst raw = $input.first().json || {};\n\nfunction clean(value) {\n return String(value ?? '').replace(/\\s+/g, ' ').trim();\n}\n\nfunction normalizeName(value) {\n return clean(value)\n .toLowerCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^a-z0-9 ]/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nfunction normalizeIdentifier(value) {\n return clean(value).toUpperCase().replace(/[^A-Z0-9]/g, '');\n}\n\nfunction countryMatches(employee) {\n const location = normalizeName(\n employee.location ||\n employee.jobInformationLocation ||\n employee.jobLocation ||\n ''\n );\n const country = normalizeName(employee.country || '');\n const combined = `${location} ${country}`.trim();\n\n if (request.country === 'GT') {\n return combined.includes('guatemala');\n }\n\n if (request.country === 'PA') {\n return combined.includes('panama');\n }\n\n if (request.country === 'SV') {\n return combined.includes('el salvador') || combined.includes('salvador');\n }\n\n if (request.country === 'HN') {\n return combined.includes('honduras');\n }\n\n return combined.includes('trinidad') || combined.includes('tobago');\n}\n\nfunction employeeAliases(employee) {\n const first = clean(employee.firstName || employee.first_name);\n const middle = clean(employee.middleName || employee.middle_name);\n const last = clean(employee.lastName || employee.last_name);\n const display = clean(employee.displayName || employee.fullName || employee.full_name);\n\n return Array.from(new Set([\n display,\n [first, middle, last].filter(Boolean).join(' '),\n [first, last].filter(Boolean).join(' '),\n ].map(clean).filter(Boolean)));\n}\n\nconst employees = Array.isArray(raw.employees)\n ? raw.employees\n : Array.isArray(raw.data?.employees)\n ? raw.data.employees\n : [];\n\nif (!employees.length) {\n throw new Error('BambooHR no devolvió empleados para validar la corrección.');\n}\n\nconst candidates = employees.filter(countryMatches);\nif (!candidates.length) {\n throw new Error(`No se encontraron empleados de ${request.countryName} en BambooHR.`);\n}\n\nconst requestedNumber = normalizeIdentifier(request.bambooEmployeeNumber);\nlet matches = [];\nlet matchedBy = '';\n\nif (requestedNumber) {\n matches = candidates.filter((employee) =>\n normalizeIdentifier(employee.employeeNumber || employee.employee_number) === requestedNumber\n );\n matchedBy = 'employee_number';\n}\n\nif (!matches.length) {\n const targetName = normalizeName(request.bambooName);\n matches = candidates.filter((employee) =>\n employeeAliases(employee).some((alias) => normalizeName(alias) === targetName)\n );\n matchedBy = 'exact_bamboo_name';\n}\n\nif (matches.length !== 1) {\n if (matches.length > 1) {\n throw new Error('La identificación en BambooHR es ambigua. Indica el Employee Number para seleccionar una sola persona.');\n }\n\n throw new Error(\n 'No se encontró exactamente ese empleado en BambooHR para el país seleccionado. Revisa el nombre o indica el Employee Number.'\n );\n}\n\nconst employee = matches[0];\nconst aliases = employeeAliases(employee);\nconst actualName = clean(employee.displayName) || aliases[0] || request.bambooName;\nconst actualEmployeeNumber = clean(employee.employeeNumber || employee.employee_number);\nconst bambooId = clean(employee.employeeId || employee.id);\nconst now = new Date().toISOString();\n\nconst recipientsByCountry = {\n GT: ['haguirre@gomezleemarketing.com'],\n TT: ['lnicomejack@gomezleemarketing.com'],\n PA: ['dpenalba@gomezleemarketing.com'],\n SV: ['cmalta@gomezleemarketing.com'],\n HN: ['mchang@gomezleemarketing.com'],\n};\nconst recipients = recipientsByCountry[request.country] || [];\n\nconst aliasPayload = request.sourceNames.map((sourceName) => ({\n pais: request.country,\n nombre_origen: sourceName,\n nombre_origen_normalizado: normalizeName(sourceName),\n cuenta_bancaria: String(request.bankAccount || '').replace(/[^0-9A-Za-z]+/g, ''),\n bamboo_employee_number: actualEmployeeNumber || null,\n bamboo_employee_id: bambooId || null,\n bamboo_nombre: actualName,\n motivo: request.reason,\n comentario: request.comment || null,\n activo: true,\n validado_por_email: request.requestedByEmail,\n validado_por_nombre: request.requestedByName,\n last_reported_at: now,\n updated_at: now,\n}));\n\nreturn [{\n json: {\n request,\n matchedBy,\n employee: {\n bambooId,\n employeeNumber: actualEmployeeNumber,\n name: actualName,\n status: clean(employee.status),\n location: clean(employee.location),\n },\n recipients,\n aliasPayload,\n },\n}];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 1968, 1984 ], "id": "780c274d-995c-496f-bccf-70eee565bb00", "name": "Resolver empleado BambooHR" }, { "parameters": { "method": "POST", "url": "https://dbit.digitalcompass.agency/rest/v1/cruce_cuentas_bamboo_aliases?on_conflict=pais,nombre_origen_normalizado,cuenta_bancaria", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "apikey", "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" }, { "name": "Authorization", "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" }, { "name": "Content-Type", "value": "application/json" }, { "name": "Prefer", "value": "resolution=merge-duplicates,return=representation" } ] }, "sendBody": true, "specifyBody": "json", "jsonBody": "={{ $('Resolver empleado BambooHR').first().json.aliasPayload }}", "options": { "timeout": 30000 } }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ 2208, 1984 ], "id": "15016826-fa2c-4ca1-a103-a2dd00299c66", "name": "Guardar alias Supabase", "retryOnFail": true, "maxTries": 2, "waitBetweenTries": 1000 }, { "parameters": { "jsCode": "const resolved = $('Resolver empleado BambooHR').first().json || {};\nconst request = resolved.request || {};\nconst employee = resolved.employee || {};\nconst aliasResponseItems = $input.all().map((item) => item.json || {});\n\nfunction flattenRows(items) {\n const rows = [];\n for (const item of items) {\n if (Array.isArray(item)) rows.push(...item);\n else if (Array.isArray(item.data)) rows.push(...item.data);\n else rows.push(item);\n }\n return rows.filter((row) => row && typeof row === 'object');\n}\n\nconst aliasRows = flattenRows(aliasResponseItems);\nconst aliasIds = aliasRows\n .map((row) => row.id)\n .filter(Boolean);\n\nconst requestPayload = {\n pais: request.country,\n nombre_origen_principal: request.sourceName,\n nombres_origen: request.sourceNames,\n cuenta_bancaria: request.bankAccount || null,\n monto_banco: request.bankAmount,\n moneda: request.currency,\n bamboo_employee_number: employee.employeeNumber || null,\n bamboo_employee_id: employee.bambooId || null,\n bamboo_nombre: employee.name,\n motivo: request.reason,\n comentario: request.comment || null,\n execution_id: request.executionId || null,\n report_url: request.reportUrl || null,\n period_label: request.periodLabel || null,\n period_start: request.periodStart || null,\n period_end: request.periodEnd || null,\n solicitado_por_email: request.requestedByEmail,\n solicitado_por_nombre: request.requestedByName,\n destinatarios_rrhh: resolved.recipients || [],\n alias_ids: aliasIds,\n estado: 'pendiente_notificacion',\n correo_enviado: false,\n};\n\nreturn [{ json: { requestPayload, aliasIds } }];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 2448, 1984 ], "id": "51f90afa-04d0-4d8d-80c2-dbc8278b6ad7", "name": "Preparar auditoría" }, { "parameters": { "method": "POST", "url": "https://dbit.digitalcompass.agency/rest/v1/cruce_cuentas_bamboo_correcciones", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "apikey", "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" }, { "name": "Authorization", "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" }, { "name": "Content-Type", "value": "application/json" }, { "name": "Prefer", "value": "return=representation" } ] }, "sendBody": true, "specifyBody": "json", "jsonBody": "={{ $json.requestPayload }}", "options": { "timeout": 30000 } }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ 2688, 1984 ], "id": "e105a2df-aa71-4e0c-b895-87f2f6709d82", "name": "Guardar solicitud Supabase", "retryOnFail": true, "maxTries": 2, "waitBetweenTries": 1000 }, { "parameters": { "jsCode": "const resolved = $('Resolver empleado BambooHR').first().json || {};\nconst request = resolved.request || {};\nconst employee = resolved.employee || {};\nconst auditInput = $input.all().map((item) => item.json || {});\n\nfunction firstObject(value) {\n if (Array.isArray(value)) return value[0] || {};\n if (value?.data && Array.isArray(value.data)) return value.data[0] || {};\n return value || {};\n}\n\nconst auditRow = firstObject(auditInput[0]);\nconst requestId = String(auditRow.id || '');\nif (!requestId) {\n throw new Error('Supabase no devolvió el ID de la solicitud de corrección.');\n}\n\nfunction escapeHtml(value) {\n return String(value ?? '')\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\nconst logoUrl = 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/GLM_completo.png';\nconst flagUrl = request.country === 'TT'\n ? 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/Flag_of_Trinidad_and_Tobago.svg.webp'\n : request.country === 'PA'\n ? 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/Flag_of_Panama.svg'\n : request.country === 'SV'\n ? 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/Flag_of_El_Salvador.svg.webp'\n : request.country === 'HN'\n ? 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/Bandera%20de%20Honduras.webp'\n : 'https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/Flag_of_Guatemala.svg.webp';\n\nconst to = (resolved.recipients || []).join(',');\nconst subject = `Corrección requerida en BambooHR - ${request.countryName} - ${request.sourceName}`;\n\nconst reportButton = request.reportUrl\n ? `Abrir reporte de Cruce de Cuentas`\n : '';\n\nconst htmlBody = `\n\n\n\n\n
\n\n\n
 
\n\n\n\n
\"GomezLee\"Bandera
\n
\n
Corrección de identidad · BambooHR
\n

Revisión solicitada para ${escapeHtml(request.countryName)}

\n

Durante la revisión manual de Banco sin BambooHR se confirmó que el pago corresponde a una persona existente en BambooHR, pero su nombre no está permitiendo identificarla correctamente en el cruce.

\n\n\n\n\n\n\n\n\n
Nombre detectado${escapeHtml(request.sourceName)}
Empleado en BambooHR${escapeHtml(employee.name)}
Employee Number${escapeHtml(employee.employeeNumber || 'No disponible')}
Motivo${escapeHtml(request.reason)}
Período${escapeHtml(request.periodLabel || 'No especificado')}
Reportado por${escapeHtml(request.requestedByName)} · ${escapeHtml(request.requestedByEmail)}
\n\n${request.comment ? `
Comentario: ${escapeHtml(request.comment)}
` : ''}\n\n

Por favor, revisen y corrijan el nombre o la información correspondiente en BambooHR. La equivalencia validada ya quedó registrada en el Cruce de Cuentas para evitar que este mismo falso positivo se repita mientras se realiza la corrección.

\n\n${reportButton ? `
${reportButton}
` : ''}\n\n
\n
Notificación automática · Portal Cruce de Cuentas GLM · Uso interno
\n
\n
\n`;\n\nreturn [{\n json: {\n requestId,\n to,\n subject,\n htmlBody,\n country: request.country,\n countryName: request.countryName,\n aliasCount: Array.isArray(resolved.aliasPayload) ? resolved.aliasPayload.length : 0,\n },\n}];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 2928, 1984 ], "id": "8a6facdd-60ee-4713-bb2c-5121d8449fea", "name": "Preparar correo RRHH" }, { "parameters": { "sendTo": "={{$json.to}}", "subject": "={{$json.subject}}", "message": "={{$json.htmlBody}}", "options": { "appendAttribution": false } }, "type": "n8n-nodes-base.gmail", "typeVersion": 2.2, "position": [ 3168, 1984 ], "id": "8cbb778d-b36e-4ae9-b55e-79bf8dca9d28", "name": "Enviar correo RRHH", "retryOnFail": true, "maxTries": 3, "waitBetweenTries": 2000, "webhookId": "f1d0bb21-fe2a-4742-9dcf-6d6f5eb60fa3", "credentials": { "gmailOAuth2": { "id": "UDcO1FLJqA453V2D", "name": "Gmail account 3" } } }, { "parameters": { "method": "PATCH", "url": "={{ 'https://dbit.digitalcompass.agency/rest/v1/cruce_cuentas_bamboo_correcciones?id=eq.' + $('Preparar correo RRHH').first().json.requestId }}", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "apikey", "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" }, { "name": "Authorization", "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" }, { "name": "Content-Type", "value": "application/json" }, { "name": "Prefer", "value": "return=minimal" } ] }, "sendBody": true, "specifyBody": "json", "jsonBody": "={{ { correo_enviado: true, correo_enviado_at: new Date().toISOString(), estado: 'notificado_rrhh' } }}", "options": { "timeout": 30000 } }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ 3408, 1984 ], "id": "8dbc3f8e-0ec7-48b2-95a5-6c9905cb6580", "name": "Marcar correo enviado", "retryOnFail": true, "maxTries": 2, "waitBetweenTries": 1000 }, { "parameters": { "respondWith": "json", "responseBody": "={{ { ok: true, message: 'Caso validado, equivalencia registrada y correo enviado a RRHH.', country: $('Preparar correo RRHH').first().json.country, countryName: $('Preparar correo RRHH').first().json.countryName, aliasCount: $('Preparar correo RRHH').first().json.aliasCount, requestId: $('Preparar correo RRHH').first().json.requestId } }}", "options": { "responseCode": 200, "responseHeaders": { "entries": [ { "name": "Content-Type", "value": "application/json" } ] } } }, "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.5, "position": [ 3648, 1984 ], "id": "ad4e2147-041e-43d6-b952-303d991635ff", "name": "Respond to Webhook" } ], "pinData": {}, "connections": { "Webhook": { "main": [ [ { "node": "Preparar solicitud", "type": "main", "index": 0 } ] ] }, "Preparar solicitud": { "main": [ [ { "node": "Validar acceso Supabase", "type": "main", "index": 0 } ] ] }, "Validar acceso Supabase": { "main": [ [ { "node": "Validar usuario", "type": "main", "index": 0 } ] ] }, "Validar usuario": { "main": [ [ { "node": "Consultar empleado BambooHR", "type": "main", "index": 0 } ] ] }, "Consultar empleado BambooHR": { "main": [ [ { "node": "Resolver empleado BambooHR", "type": "main", "index": 0 } ] ] }, "Resolver empleado BambooHR": { "main": [ [ { "node": "Guardar alias Supabase", "type": "main", "index": 0 } ] ] }, "Guardar alias Supabase": { "main": [ [ { "node": "Preparar auditoría", "type": "main", "index": 0 } ] ] }, "Preparar auditoría": { "main": [ [ { "node": "Guardar solicitud Supabase", "type": "main", "index": 0 } ] ] }, "Guardar solicitud Supabase": { "main": [ [ { "node": "Preparar correo RRHH", "type": "main", "index": 0 } ] ] }, "Preparar correo RRHH": { "main": [ [ { "node": "Enviar correo RRHH", "type": "main", "index": 0 } ] ] }, "Enviar correo RRHH": { "main": [ [ { "node": "Marcar correo enviado", "type": "main", "index": 0 } ] ] }, "Marcar correo enviado": { "main": [ [ { "node": "Respond to Webhook", "type": "main", "index": 0 } ] ] } }, "active": false, "settings": { "executionOrder": "v1", "binaryMode": "separate" }, "versionId": "a6157be9-0bb2-4937-845f-1769af596051", "meta": { "instanceId": "b4b77b17af092830e794eef639ce2f6d7daccf7eddc075060b03b3b6545aac70" }, "tags": [] }