From b98a2dcdc62943b1e4b67a85c6e1ee2a6f856d1d Mon Sep 17 00:00:00 2001 From: EidanThen Date: Fri, 3 Jul 2026 15:45:28 +0000 Subject: [PATCH] Update glmway-workflow.json --- glmway-workflow.json | 2311 ++++++++++++++++++------------------------ 1 file changed, 994 insertions(+), 1317 deletions(-) diff --git a/glmway-workflow.json b/glmway-workflow.json index 1ae40bb..28e90ec 100644 --- a/glmway-workflow.json +++ b/glmway-workflow.json @@ -1,6 +1,6 @@ { "$json": { - "updatedAt": "2026-07-02T17:58:46.091Z", + "updatedAt": "2026-07-03T15:29:04.744Z", "createdAt": "2026-06-08T13:50:12.174Z", "id": "F1iPg8hktNAebZua", "name": "GLMWay", @@ -791,7 +791,7 @@ "type": "n8n-nodes-base.if", "typeVersion": 2.3, "position": [ - 912, + 2624, -240 ], "id": "8a2be7cc-85ad-4e44-92a7-fe3f94df703f", @@ -987,8 +987,8 @@ }, "type": "n8n-nodes-base.stickyNote", "position": [ - 1264, - -16 + 2768, + -464 ], "typeVersion": 1, "id": "719365c8-8099-4108-a910-83b651d81181", @@ -1033,7 +1033,7 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ - 1152, + 2816, -144 ], "id": "09ce1f03-3dfb-4108-9d25-6c05ac622a6f", @@ -1108,10 +1108,10 @@ }, { "parameters": { - "sendTo": "={{ $('Get an employee').item.json.workEmail }}", + "sendTo": "=eidan.then14@gmail.com", "subject": "Entrenamiento #TheGLMWay", "emailType": "text", - "message": "=Hola, GLMer!\n\nEste {{ $json.hora_convertida }} a las {{ $('Obtener sesiones español').item.json.hora_inicio }} tenemos entrenamiento, y queremos transmitirte nuestra cultura, nuestro ADN y por qué somos diferentes al resto.\n\nTe esperamos puntual y con todas las ganas de aprender.\n\nNos vemos en el enlace!\n\n{{ $('Obtener sesiones español').item.json.enlace_reunion }}", + "message": "=Hola, GLMer!\n\nEste {{ $('Convertir fecha a espanol').item.json.fechaFormateada }} a las {{ $json.hora_convertida }} tenemos entrenamiento, y queremos transmitirte nuestra cultura, nuestro ADN y por qué somos diferentes al resto.\n\nTe esperamos puntual y con todas las ganas de aprender.\n\nNos vemos en el enlace!\n\n{{ $('Obtener sesiones español').item.json.enlace_reunion }}", "options": { "appendAttribution": false } @@ -1119,8 +1119,8 @@ "type": "n8n-nodes-base.gmail", "typeVersion": 2.2, "position": [ - 2672, - -400 + 2080, + -336 ], "id": "e6c3acf5-d54b-4e00-b7a9-74038d27e387", "name": "Send a message espanol", @@ -1134,10 +1134,10 @@ }, { "parameters": { - "sendTo": "={{ $('Get an employee').item.json.workEmail }}", + "sendTo": "=eidan.then14@gmail.com", "subject": "#TheGLMWay Training", "emailType": "text", - "message": "=Hello, GLMer!\n\nThis {{ $json.hora_convertida }} at {{ $('Obtener sesiones ingles').item.json.hora_inicio }} we have training, and we want to share our culture, our DNA, and what makes us different from the rest.\n\nWe expect you to be punctual and eager to learn.\n\nSee you at the link!\n\n{{ $('Obtener sesiones ingles').item.json.enlace_reunion }}", + "message": "=Hello, GLMer!\n\nThis {{ $('Convertir fecha a ingles').item.json.fechaFormateada }} at {{ $json.hora_convertida }} we have training, and we want to share our culture, our DNA, and what makes us different from the rest.\n\nWe expect you to be punctual and eager to learn.\n\nSee you at the link!\n\n{{ $('Obtener sesiones ingles').item.json.enlace_reunion }}", "options": { "appendAttribution": false } @@ -1145,8 +1145,8 @@ "type": "n8n-nodes-base.gmail", "typeVersion": 2.2, "position": [ - 2672, - -224 + 2080, + -160 ], "id": "f173c8d1-9311-405c-a7ee-164726df32f1", "name": "Send a message ingles", @@ -1210,7 +1210,7 @@ "parameters": { "content": "## Notificacion inicial\n\nEnvia notificacion de sesion en el primer dia de trabajo del empleado", "height": 608, - "width": 3216, + "width": 3360, "color": 6 }, "type": "n8n-nodes-base.stickyNote", @@ -1289,7 +1289,7 @@ "parameters": { "content": "## Completar datos y enviar invitacion", "height": 544, - "width": 3696, + "width": 3920, "color": 6 }, "type": "n8n-nodes-base.stickyNote", @@ -1360,11 +1360,11 @@ "conditions": [ { "id": "9674fd7e-dd62-42d4-8931-6c67e59e3dd7", - "leftValue": "={{ !['Jamaica', 'Trinidad and Tobago', 'Barbados', 'Saint Thomas', 'St. Croix', 'Tobago', 'Guyana', 'Aruba'].includes($('Get an employee1').item.json.location) }}", + "leftValue": "={{ [\"Jamaica\", \"Trinidad and Tobago\", \"Barbados\", \"Saint Thomas\", \"St. Croix\", \"Tobago\", \"Guyana\", \"Aruba\"].includes($('Get an employee1').item.json.location) }}", "rightValue": "Jamaica", "operator": { "type": "boolean", - "operation": "true", + "operation": "false", "singleValue": true } } @@ -1469,7 +1469,7 @@ "type": "n8n-nodes-base.if", "typeVersion": 2.3, "position": [ - 3008, + 3056, 352 ], "id": "30b3a4dd-6d50-405d-9c77-27febcc50aa4", @@ -1514,7 +1514,7 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ - 3184, + 3232, 432 ], "id": "67928478-7604-45a4-9ab0-851079e1470c", @@ -1522,10 +1522,10 @@ }, { "parameters": { - "sendTo": "={{ $('Get an employee1').item.json.workEmail }}", + "sendTo": "=eidan.then14@gmail.com", "subject": "Entrenamiento #TheGLMWay", "emailType": "text", - "message": "=Hola, GLMer!\n\nEste {{ $json.hora_convertida }} a las {{ $('Obtener sesiones español1').item.json.hora_inicio }} tenemos entrenamiento, y queremos transmitirte nuestra cultura, nuestro ADN y por qué somos diferentes al resto.\n\nTe esperamos puntual y con todas las ganas de aprender.\n\nNos vemos en el enlace!\n\n{{ $('Obtener sesiones español1').item.json.enlace_reunion }}", + "message": "=Hola, GLMer!\n\nEste {{ $('Convertir fecha a espanol1').item.json.fechaFormateada }} a las {{ $json.hora_convertida }} tenemos entrenamiento, y queremos transmitirte nuestra cultura, nuestro ADN y por qué somos diferentes al resto.\n\nTe esperamos puntual y con todas las ganas de aprender.\n\nNos vemos en el enlace!\n\n{{ $('Obtener sesiones español1').item.json.enlace_reunion }}", "options": { "appendAttribution": false } @@ -1533,7 +1533,7 @@ "type": "n8n-nodes-base.gmail", "typeVersion": 2.2, "position": [ - 2656, + 2480, 272 ], "id": "32302b24-aa4c-4f9a-afc8-ef7e86cad56b", @@ -1548,10 +1548,10 @@ }, { "parameters": { - "sendTo": "={{ $('Get an employee1').item.json.workEmail }}", + "sendTo": "=eidan.then14@gmail.com", "subject": "#TheGLMWay Training", "emailType": "text", - "message": "=Hello, GLMer!\n\nThis {{ $json.hora_convertida }} at {{ $('Obtener sesiones ingles1').item.json.hora_inicio }} we have training, and we want to share our culture, our DNA, and what makes us different from the rest.\n\nWe expect you to be punctual and eager to learn.\n\nSee you at the link!\n\n{{ $('Obtener sesiones ingles1').item.json.enlace_reunion }}", + "message": "=Hello, GLMer!\n\nThis {{ $('Convertir fecha a ingles1').item.json.fechaFormateada }} at {{ $json.hora_convertida }} we have training, and we want to share our culture, our DNA, and what makes us different from the rest.\n\nWe expect you to be punctual and eager to learn.\n\nSee you at the link!\n\n{{ $('Obtener sesiones ingles1').item.json.enlace_reunion }}", "options": { "appendAttribution": false } @@ -1559,7 +1559,7 @@ "type": "n8n-nodes-base.gmail", "typeVersion": 2.2, "position": [ - 2656, + 2480, 448 ], "id": "db2cb6a3-1da8-472a-95eb-1a02de2a5fa4", @@ -1584,74 +1584,12 @@ "conditions": [ { "id": "9674fd7e-dd62-42d4-8931-6c67e59e3dd7", - "leftValue": "={{ $('Get an employee').item.json.location }}", + "leftValue": "={{ [\"Jamaica\", \"Trinidad and Tobago\", \"Barbados\", \"Saint Thomas\", \"St. Croix\", \"Tobago\", \"Guyana\", \"Aruba\"].includes($('Get an employee').item.json.location) }}", "rightValue": "Jamaica", "operator": { - "type": "string", - "operation": "equals" - } - }, - { - "id": "32931394-f4ea-4055-b866-906a81988173", - "leftValue": "={{ $('Get an employee').item.json.location }}", - "rightValue": "Trinidad and Tobago", - "operator": { - "type": "string", - "operation": "equals" - } - }, - { - "id": "ea2a8466-96c6-460f-b08f-d23c06b2d18c", - "leftValue": "={{ $('Get an employee').item.json.location }}", - "rightValue": "Barbados", - "operator": { - "type": "string", - "operation": "equals" - } - }, - { - "id": "28e49217-0c1a-4462-9642-676e54926d3e", - "leftValue": "={{ $('Get an employee').item.json.location }}", - "rightValue": "Saint Thomas", - "operator": { - "type": "string", - "operation": "equals" - } - }, - { - "id": "c6a6aea5-48f4-44dc-92ca-a9f9de9cacf9", - "leftValue": "={{ $('Get an employee').item.json.location }}", - "rightValue": "St. Croix", - "operator": { - "type": "string", - "operation": "equals" - } - }, - { - "id": "e6f52339-ea7c-462f-bdc2-8b7353160e4c", - "leftValue": "={{ $('Get an employee').item.json.location }}", - "rightValue": "Tobago", - "operator": { - "type": "string", - "operation": "equals" - } - }, - { - "id": "b308c2b6-53b4-4d49-b540-cdc03e36528b", - "leftValue": "={{ $('Get an employee').item.json.location }}", - "rightValue": "Guyana", - "operator": { - "type": "string", - "operation": "equals" - } - }, - { - "id": "35a50a33-a2b5-4116-9336-11300357569e", - "leftValue": "={{ $('Get an employee').item.json.location }}", - "rightValue": "Aruba", - "operator": { - "type": "string", - "operation": "equals" + "type": "boolean", + "operation": "false", + "singleValue": true } } ], @@ -1662,8 +1600,8 @@ "type": "n8n-nodes-base.if", "typeVersion": 2.2, "position": [ - 1152, - -320 + 752, + -256 ], "id": "b183c892-8822-4bc3-a92c-4410eac41a01", "name": "Pais?" @@ -1724,7 +1662,7 @@ "type": "n8n-nodes-base.wait", "typeVersion": 1.1, "position": [ - 3360, + 3408, 352 ], "id": "98185de1-e81a-440f-8951-f98bd78c707b", @@ -1749,7 +1687,7 @@ }, { "parameters": { - "sendTo": "={{ $('Loop Over Items1').item.json.email }}", + "sendTo": "=eidan.then14@gmail.com", "subject": "Entrenamiento #TheGLMWay", "emailType": "text", "message": "=¡Hola, GLMer!\n\nEste es un recordatorio de tu entrenamiento, donde te transmitiremos nuestra cultura, nuestro ADN y por qué somos diferentes al resto.\n\n¡Te esperamos puntual y con toda la energía para aprender!\n\nÚnete aquí:\n\n{{ $('Obtener sesion').item.json.enlace_reunion }}", @@ -1775,7 +1713,7 @@ }, { "parameters": { - "sendTo": "={{ $('Loop Over Items1').item.json.email }}", + "sendTo": "=eidan.then14@gmail.com", "subject": "#TheGLMWay Training", "emailType": "text", "message": "=Hello, GLMer!\n\nThis is a reminder about your training session, where we'll share our culture, our DNA, and what makes us different from the rest.\n\nWe're looking forward to seeing you on time and ready to learn!\n\nJoin here:\n\n{{ $('Obtener sesion').item.json.enlace_reunion }}", @@ -1879,7 +1817,7 @@ "type": "n8n-nodes-base.googleSheets", "typeVersion": 4.7, "position": [ - 752, + 2464, -240 ], "id": "d565bfde-93eb-4b39-afc8-4b294c7e9df7", @@ -1921,7 +1859,7 @@ "type": "n8n-nodes-base.googleSheets", "typeVersion": 4.7, "position": [ - 2848, + 2896, 352 ], "id": "3a6f198b-e136-49fb-a171-78164e10b600", @@ -2102,8 +2040,8 @@ "type": "n8n-nodes-base.set", "typeVersion": 3.4, "position": [ - 1376, - -400 + 976, + -336 ], "id": "e8a65f36-8e8e-4135-b7a2-a7ef4617de2f", "name": "Crear variable idioma ES" @@ -2125,8 +2063,8 @@ "type": "n8n-nodes-base.set", "typeVersion": 3.4, "position": [ - 1376, - -224 + 976, + -160 ], "id": "971ae719-5692-4f87-9a57-2287ee44783d", "name": "Crear variable idioma EN" @@ -2147,8 +2085,8 @@ "type": "n8n-nodes-base.supabase", "typeVersion": 1, "position": [ - 1568, - -400 + 1168, + -336 ], "id": "cb9e8a10-a1e7-40c7-8447-2379b0191a8f", "name": "Obtener sesiones español", @@ -2175,8 +2113,8 @@ "type": "n8n-nodes-base.supabase", "typeVersion": 1, "position": [ - 1568, - -224 + 1168, + -160 ], "id": "5ca790ee-4944-4868-98af-89837ac39422", "name": "Obtener sesiones ingles", @@ -2194,8 +2132,8 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 1760, - -400 + 1360, + -336 ], "id": "c2db5e62-7741-4ff2-ad31-71c108dd7386", "name": "Calcular sesion mas cercana" @@ -2207,8 +2145,8 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 1760, - -224 + 1360, + -160 ], "id": "bde8fba9-0d6c-4299-8971-dcd8e0e740b4", "name": "Calcular sesion mas cercana1" @@ -2325,6 +2263,18 @@ { "fieldId": "sesion_id", "fieldValue": "={{ $json.session.id }}" + }, + { + "fieldId": "division", + "fieldValue": "={{ $('Get an employee').item.json.division }}" + }, + { + "fieldId": "puesto", + "fieldValue": "={{ $('Get an employee').item.json.jobTitle }}" + }, + { + "fieldId": "pais", + "fieldValue": "={{ $('Get an employee').item.json.location }}" } ] } @@ -2332,8 +2282,8 @@ "type": "n8n-nodes-base.supabase", "typeVersion": 1, "position": [ - 1920, - -400 + 1520, + -336 ], "id": "dcdef9fc-9c61-45dd-9604-56037eac4c31", "name": "Guardar datos del empleado y sesion asignada", @@ -2384,6 +2334,18 @@ { "fieldId": "sesion_id", "fieldValue": "={{ $json.session.id }}" + }, + { + "fieldId": "division", + "fieldValue": "={{ $('Get an employee').item.json.division }}" + }, + { + "fieldId": "puesto", + "fieldValue": "={{ $('Get an employee').item.json.jobTitle }}" + }, + { + "fieldId": "pais", + "fieldValue": "={{ $('Get an employee').item.json.location }}" } ] } @@ -2391,8 +2353,8 @@ "type": "n8n-nodes-base.supabase", "typeVersion": 1, "position": [ - 1920, - -224 + 1520, + -160 ], "id": "7530270a-b32e-419e-8fc5-b29fa07dda39", "name": "Guardar datos del empleado y sesion asignada1", @@ -2473,131 +2435,6 @@ "name": "Wait2", "webhookId": "1211d7da-55b9-4a73-837d-55934076a799" }, - { - "parameters": { - "conditions": { - "options": { - "caseSensitive": true, - "leftValue": "", - "typeValidation": "strict", - "version": 3 - }, - "conditions": [ - { - "id": "d7d68505-8c34-44cd-b771-56bef28ada41", - "leftValue": "={{ $('Get an employee1').item.json.workEmail }}", - "rightValue": "", - "operator": { - "type": "string", - "operation": "notEmpty", - "singleValue": true - } - }, - { - "id": "a245c081-ef08-4ba2-8164-2d2c35bd1e17", - "leftValue": "={{ $('Get an employee1').item.json.location }}", - "rightValue": "", - "operator": { - "type": "string", - "operation": "notEmpty", - "singleValue": true - } - } - ], - "combinator": "and" - }, - "options": {} - }, - "type": "n8n-nodes-base.if", - "typeVersion": 2.3, - "position": [ - 752, - 352 - ], - "id": "a2a81e91-f617-490a-b1ce-5737944fa23b", - "name": "Tiene correo?" - }, - { - "parameters": { - "operation": "update", - "tableId": "inscritos_glmway", - "filters": { - "conditions": [ - { - "keyName": "empleado_id", - "condition": "eq", - "keyValue": "={{ $('Get an employee1').item.json.id }}" - } - ] - }, - "fieldsUi": { - "fieldValues": [ - { - "fieldId": "empleado_id", - "fieldValue": "={{ $('Informacion extra del empleado1').item.json.id }}" - }, - { - "fieldId": "nombre", - "fieldValue": "={{ $('Get an employee1').item.json.displayName }}" - }, - { - "fieldId": "email", - "fieldValue": "={{ $('Get an employee1').item.json.workEmail }}" - }, - { - "fieldId": "departamento", - "fieldValue": "={{ $('Get an employee1').item.json.department }}" - }, - { - "fieldId": "supervisor_id", - "fieldValue": "={{ $('Informacion extra del empleado1').item.json.supervisorEId }}" - }, - { - "fieldId": "fecha_ingreso", - "fieldValue": "={{ $('Informacion extra del empleado1').item.json.hireDate }}" - }, - { - "fieldId": "fecha_sesion_inscrito", - "fieldValue": "={{ $json.session.fecha_sesion }}" - }, - { - "fieldId": "estado", - "fieldValue": "notificado" - }, - { - "fieldId": "sesion_id", - "fieldValue": "={{ $json.session.id }}" - }, - { - "fieldId": "pais", - "fieldValue": "={{ $('Get an employee1').item.json.location }}" - }, - { - "fieldId": "division", - "fieldValue": "={{ $('Get an employee1').item.json.division }}" - }, - { - "fieldId": "puesto", - "fieldValue": "={{ $('Get an employee1').item.json.jobTitle }}" - } - ] - } - }, - "type": "n8n-nodes-base.supabase", - "typeVersion": 1, - "position": [ - 1904, - 272 - ], - "id": "16d364da-e6fc-4943-bd64-f83ccab66b9f", - "name": "Actualizar datos del empleado y sesion asignada2", - "credentials": { - "supabaseApi": { - "id": "2PlsR6rpK7rQTIEn", - "name": "Sofia test - Supabase account" - } - } - }, { "parameters": { "operation": "get", @@ -2940,131 +2777,6 @@ "id": "bbd0558c-3b3a-462b-957c-83b1975e5413", "name": "Calcular falta 24h o es el mismo dia" }, - { - "parameters": { - "operation": "update", - "tableId": "inscritos_glmway", - "filters": { - "conditions": [ - { - "keyName": "empleado_id", - "condition": "eq", - "keyValue": "={{ $('Get an employee1').item.json.id }}" - } - ] - }, - "fieldsUi": { - "fieldValues": [ - { - "fieldId": "empleado_id", - "fieldValue": "={{ $('Informacion extra del empleado1').item.json.id }}" - }, - { - "fieldId": "nombre", - "fieldValue": "={{ $('Get an employee1').item.json.displayName }}" - }, - { - "fieldId": "email", - "fieldValue": "={{ $('Get an employee1').item.json.workEmail }}" - }, - { - "fieldId": "departamento", - "fieldValue": "={{ $('Get an employee1').item.json.department }}" - }, - { - "fieldId": "supervisor_id", - "fieldValue": "={{ $('Informacion extra del empleado1').item.json.supervisorEId }}" - }, - { - "fieldId": "fecha_ingreso", - "fieldValue": "={{ $('Informacion extra del empleado1').item.json.hireDate }}" - }, - { - "fieldId": "fecha_sesion_inscrito", - "fieldValue": "={{ $json.session.fecha_sesion }}" - }, - { - "fieldId": "estado", - "fieldValue": "notificado" - }, - { - "fieldId": "sesion_id", - "fieldValue": "={{ $json.session.id }}" - }, - { - "fieldId": "pais", - "fieldValue": "={{ $('Get an employee1').item.json.location }}" - }, - { - "fieldId": "division", - "fieldValue": "={{ $('Get an employee1').item.json.division }}" - }, - { - "fieldId": "puesto", - "fieldValue": "={{ $('Get an employee1').item.json.jobTitle }}" - } - ] - } - }, - "type": "n8n-nodes-base.supabase", - "typeVersion": 1, - "position": [ - 1904, - 448 - ], - "id": "f2aca2bd-e72d-4457-9a6b-c4b0f8bcc558", - "name": "Actualizar datos del empleado y sesion asignada3", - "credentials": { - "supabaseApi": { - "id": "2PlsR6rpK7rQTIEn", - "name": "Sofia test - Supabase account" - } - } - }, - { - "parameters": { - "conditions": { - "options": { - "caseSensitive": true, - "leftValue": "", - "typeValidation": "strict", - "version": 3 - }, - "conditions": [ - { - "id": "d7d68505-8c34-44cd-b771-56bef28ada41", - "leftValue": "={{ $('Get an employee').item.json.workEmail }}", - "rightValue": "", - "operator": { - "type": "string", - "operation": "notEmpty", - "singleValue": true - } - }, - { - "id": "ec0276ab-208e-409b-8101-d06e535f541c", - "leftValue": "={{ $('Get an employee').item.json.location }}", - "rightValue": "", - "operator": { - "type": "string", - "operation": "notEmpty", - "singleValue": true - } - } - ], - "combinator": "and" - }, - "options": {} - }, - "type": "n8n-nodes-base.if", - "typeVersion": 2.3, - "position": [ - 336, - -144 - ], - "id": "a9fff247-d1b0-4314-ba8d-e7401086b771", - "name": "Tiene correo?1" - }, { "parameters": { "documentId": { @@ -3164,7 +2876,7 @@ "type": "n8n-nodes-base.scheduleTrigger", "typeVersion": 1.3, "position": [ - 2976, + 3056, -352 ], "id": "ca136518-b776-45ba-b1a2-ad5327dd4cca", @@ -3215,7 +2927,7 @@ "type": "n8n-nodes-base.googleSheets", "typeVersion": 4.7, "position": [ - 3872, + 3952, -352 ], "id": "7c321f7d-bce9-447c-b94c-35f6967a48e3", @@ -3233,7 +2945,7 @@ "type": "n8n-nodes-base.wait", "typeVersion": 1.1, "position": [ - 3696, + 3776, -352 ], "id": "27531838-5dc7-4169-a08a-f4da93899580", @@ -3263,7 +2975,7 @@ "type": "n8n-nodes-base.googleSheets", "typeVersion": 4.7, "position": [ - 3520, + 3600, -352 ], "id": "bd8cb535-6aa3-46df-9ca0-6efc0555f2e4", @@ -3284,7 +2996,7 @@ }, "type": "n8n-nodes-base.stickyNote", "position": [ - 2944, + 3024, -480 ], "typeVersion": 1, @@ -3437,8 +3149,8 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.1, "position": [ - 336, - 3568 + 448, + 3584 ], "credentials": { "googleOAuth2Api": { @@ -3455,8 +3167,8 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 64, - 3264 + 112, + 3488 ], "id": "602289b9-3c7d-4ced-b507-b27401ed9910", "name": "HTTP Request1" @@ -3473,7 +3185,7 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.1, "position": [ - 160, + 320, 2976 ], "credentials": { @@ -3495,8 +3207,8 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.1, "position": [ - 320, - 3296 + 304, + 3472 ], "credentials": { "googleOAuth2Api": { @@ -3582,7 +3294,7 @@ "type": "n8n-nodes-base.googleCalendar", "typeVersion": 1.3, "position": [ - 3168, + 3248, -352 ], "id": "b2b03ce6-6010-4e4f-be7a-d9040286e295", @@ -3601,7 +3313,7 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 3344, + 3424, -352 ], "id": "73c39af9-bc01-4d97-81ee-846aff70b3a6", @@ -3620,7 +3332,7 @@ "type": "n8n-nodes-base.scheduleTrigger", "typeVersion": 1.3, "position": [ - 2976, + 3056, -48 ], "id": "55a755d8-8b74-440f-93c6-8a1ecba4c666", @@ -3634,7 +3346,7 @@ }, "type": "n8n-nodes-base.stickyNote", "position": [ - 2944, + 3024, -160 ], "typeVersion": 1, @@ -3661,7 +3373,7 @@ "type": "n8n-nodes-base.googleCalendar", "typeVersion": 1.3, "position": [ - 4320, + 4400, -208 ], "id": "3c32f96e-cd34-4be4-8c24-b4be7a8f29d9", @@ -3694,7 +3406,7 @@ "type": "n8n-nodes-base.googleSheets", "typeVersion": 4.7, "position": [ - 3152, + 3232, -48 ], "id": "73089147-ba1f-4fb4-ac17-d5670b263fd8", @@ -3732,7 +3444,7 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 3488, + 3568, -48 ], "id": "231f396b-855a-4c50-8d6d-096018e6d2ac", @@ -3747,7 +3459,7 @@ "type": "n8n-nodes-base.aggregate", "typeVersion": 1, "position": [ - 3312, + 3392, -48 ], "id": "e51bd2d5-22b5-46cf-b346-c1ba16bb5c34", @@ -3778,7 +3490,7 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 5120, + 5200, -304 ], "id": "3f4a0807-5f29-49cb-a851-41100e04f5bf", @@ -3793,7 +3505,7 @@ "type": "n8n-nodes-base.aggregate", "typeVersion": 1, "position": [ - 4976, + 5056, -304 ], "id": "3ecbb0c7-f5f5-4644-9f42-8be9502e814d", @@ -3808,7 +3520,7 @@ "type": "n8n-nodes-base.set", "typeVersion": 3.4, "position": [ - 4832, + 4912, -304 ], "id": "a099259d-36e3-48b6-aa77-d8132f33f85e", @@ -3831,7 +3543,7 @@ "type": "n8n-nodes-base.merge", "typeVersion": 3.2, "position": [ - 4688, + 4768, -304 ], "id": "456bcbe4-cc98-48fc-bcd2-40f8961934ae", @@ -3845,7 +3557,7 @@ }, "type": "n8n-nodes-base.stickyNote", "position": [ - 4112, + 4192, -480 ], "typeVersion": 1, @@ -3869,7 +3581,7 @@ "type": "n8n-nodes-base.scheduleTrigger", "typeVersion": 1.3, "position": [ - 4160, + 4240, -288 ], "id": "6ef829bf-1d52-4093-bcc5-45d922393611", @@ -3896,7 +3608,7 @@ "type": "n8n-nodes-base.googleSheets", "typeVersion": 4.7, "position": [ - 4320, + 4400, -384 ], "id": "f1bf8c51-43cf-41d4-93c4-1a1d0a0dac7a", @@ -3916,7 +3628,7 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 4496, + 4576, -208 ], "id": "8f80d9ca-1e4b-4753-b482-df7b0fd24f61", @@ -4378,14 +4090,14 @@ }, "sendBody": true, "specifyBody": "json", - "jsonBody": "={\n \"p_sesion_id\": \"{{ $('Calcular sesion mas cercana').item.json.session.id }}\",\n \"p_pais\": \"{{ $json.pais }}\",\n \"p_empleados\": [\n {\n \"nombre\": \"{{ $json.nombre }}\",\n \"correo\": \"{{ $json.email }}\",\n \"departamento\": \"{{ $json.departamento }}\",\n \"division\": \"{{ $json.division }}\"\n }\n ]\n}", + "jsonBody": "={\n \"p_sesion_id\": \"{{ $('Calcular sesion mas cercana').item.json.session.id }}\",\n \"p_pais\": \"{{ $('Get an employee').item.json.location }}\",\n \"p_empleados\": [\n {\n \"nombre\": \"{{ $('Get an employee').item.json.displayName }}\",\n \"correo\": \"{{ $('Get an employee').item.json.workEmail }}\",\n \"departamento\": \"{{ $('Get an employee').item.json.department }}\",\n \"division\": \"{{ $('Get an employee').item.json.division }}\"\n }\n ]\n}", "options": {} }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 2096, - -400 + 2272, + -336 ], "id": "4ab5f973-c2e1-410e-9212-8ed3b9d372e3", "name": "Registrar empleado a la sesion" @@ -4409,14 +4121,14 @@ }, "sendBody": true, "specifyBody": "json", - "jsonBody": "={\n \"p_sesion_id\": \"{{ $('Calcular sesion mas cercana1').item.json.session.id }}\",\n \"p_pais\": \"{{ $json.pais }}\",\n \"p_empleados\": [\n {\n \"nombre\": \"{{ $json.nombre }}\",\n \"correo\": \"{{ $json.email }}\",\n \"departamento\": \"{{ $json.departamento }}\",\n \"division\": \"{{ $json.division }}\"\n }\n ]\n}", + "jsonBody": "={\n \"p_sesion_id\": \"{{ $('Calcular sesion mas cercana1').item.json.session.id }}\",\n \"p_pais\": \"{{ $('Get an employee').item.json.location }}\",\n \"p_empleados\": [\n {\n \"nombre\": \"{{ $('Get an employee').item.json.displayName }}\",\n \"correo\": \"{{ $('Get an employee').item.json.workEmail }}\",\n \"departamento\": \"{{ $('Get an employee').item.json.department }}\",\n \"division\": \"{{ $('Get an employee').item.json.division }}\"\n }\n ]\n}", "options": {} }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 2096, - -224 + 2272, + -160 ], "id": "5e69165f-16a2-4f7a-ad48-d24c70f3c88b", "name": "Registrar empleado a la sesion1" @@ -4446,7 +4158,7 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 2080, + 2688, 272 ], "id": "f3df197d-b557-45d7-94bb-76f3c300ae61", @@ -4477,7 +4189,7 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 2080, + 2688, 448 ], "id": "23ac8709-b0ac-4bb6-911a-1e7641be075d", @@ -4485,38 +4197,38 @@ }, { "parameters": { - "jsCode": "// Diccionario de meses inglés -> español\nconst meses = {\n january: 'Enero',\n february: 'Febrero',\n march: 'Marzo',\n april: 'Abril',\n may: 'Mayo',\n june: 'Junio',\n july: 'Julio',\n august: 'Agosto',\n september: 'Septiembre',\n october: 'Octubre',\n november: 'Noviembre',\n december: 'Diciembre'\n};\n\nfor (const item of $input.all()) {\n const fecha = $('Calcular sesion mas cercana').first().json.session.fecha_sesion; // Cambia \"fecha\" por el nombre real de tu campo\n const partes = fecha.trim().split(' '); // [\"8\", \"July\"]\n\n const dia = partes[0];\n const mesIngles = partes[1].toLowerCase();\n const mesEspanol = meses[mesIngles] || partes[1];\n\n item.json.fechaFormateada = `${mesEspanol} ${dia}`;\n}\n\nreturn $input.all();" + "jsCode": "// Diccionario de meses inglés -> español\nconst meses = {\n january: 'Enero',\n february: 'Febrero',\n march: 'Marzo',\n april: 'Abril',\n may: 'Mayo',\n june: 'Junio',\n july: 'Julio',\n august: 'Agosto',\n september: 'Septiembre',\n october: 'Octubre',\n november: 'Noviembre',\n december: 'Diciembre'\n};\n\nconst fecha = $('Calcular sesion mas cercana').first().json.session.fecha_sesion;\n\nconst partes = fecha.trim().split(' ');\nconst dia = partes[0];\nconst mesIngles = partes[1].toLowerCase();\nconst mesEspanol = meses[mesIngles] || partes[1];\n\nconst fechaFormateada = `${mesEspanol} ${dia}`;\n\nreturn [\n {\n json: {\n fechaFormateada\n }\n }\n];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 2288, - -400 + 1696, + -336 ], "id": "ad0bb609-e224-4956-bf20-0d624f4ef3ae", "name": "Convertir fecha a espanol" }, { "parameters": { - "jsCode": "function getOrdinalSuffix(dia) {\n const d = parseInt(dia, 10);\n if (d > 3 && d < 21) return `${d}th`; // 11th-13th excepción cubierta aquí\n switch (d % 10) {\n case 1: return `${d}st`;\n case 2: return `${d}nd`;\n case 3: return `${d}rd`;\n default: return `${d}th`;\n }\n}\n\nfor (const item of $input.all()) {\n const fecha = $('Calcular sesion mas cercana1').first().json.session.fecha_sesion; // Cambia \"fecha\" por el nombre real de tu campo\n const partes = fecha.trim().split(' '); // [\"8\", \"July\"]\n\n const dia = partes[0];\n const mes = partes[1];\n const diaConSufijo = getOrdinalSuffix(dia);\n\n item.json.fechaFormateada = `${mes} ${diaConSufijo}`;\n}\n\nreturn $input.all();" + "jsCode": "function getOrdinalSuffix(dia) {\n const d = parseInt(dia, 10);\n if (d > 3 && d < 21) return `${d}th`; // 11th-13th excepción cubierta aquí\n switch (d % 10) {\n case 1: return `${d}st`;\n case 2: return `${d}nd`;\n case 3: return `${d}rd`;\n default: return `${d}th`;\n }\n}\n\nconst fecha = $('Calcular sesion mas cercana1').first().json.session.fecha_sesion; // Cambia \"fecha\" por el nombre real de tu campo\nconst partes = fecha.trim().split(' '); // [\"8\", \"July\"]\n\nconst dia = partes[0];\nconst mes = partes[1];\nconst diaConSufijo = getOrdinalSuffix(dia);\n\nconst fechaFormateada = `${mes} ${diaConSufijo}`;\n\nreturn [\n {\n json: {\n fechaFormateada\n }\n }\n];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 2288, - -224 + 1696, + -160 ], "id": "a1ad0e55-59e3-405e-b75d-d092112e9151", "name": "Convertir fecha a ingles" }, { "parameters": { - "jsCode": "// Diccionario de meses inglés -> español\nconst meses = {\n january: 'Enero',\n february: 'Febrero',\n march: 'Marzo',\n april: 'Abril',\n may: 'Mayo',\n june: 'Junio',\n july: 'Julio',\n august: 'Agosto',\n september: 'Septiembre',\n october: 'Octubre',\n november: 'Noviembre',\n december: 'Diciembre'\n};\n\nfor (const item of $input.all()) {\n const fecha = $('Calcular sesion mas cercana2').first().json.session.fecha_sesion; // Cambia \"fecha\" por el nombre real de tu campo\n const partes = fecha.trim().split(' '); // [\"8\", \"July\"]\n\n const dia = partes[0];\n const mesIngles = partes[1].toLowerCase();\n const mesEspanol = meses[mesIngles] || partes[1];\n\n item.json.fechaFormateada = `${mesEspanol} ${dia}`;\n}\n\nreturn $input.all();" + "jsCode": "// Diccionario de meses inglés -> español\nconst meses = {\n january: 'Enero',\n february: 'Febrero',\n march: 'Marzo',\n april: 'Abril',\n may: 'Mayo',\n june: 'Junio',\n july: 'Julio',\n august: 'Agosto',\n september: 'Septiembre',\n october: 'Octubre',\n november: 'Noviembre',\n december: 'Diciembre'\n};\n\nconst fecha = $('Calcular sesion mas cercana3').first().json.session.fecha_sesion;\n\nconst partes = fecha.trim().split(' ');\nconst dia = partes[0];\nconst mesIngles = partes[1].toLowerCase();\nconst mesEspanol = meses[mesIngles] || partes[1];\n\nconst fechaFormateada = `${mesEspanol} ${dia}`;\n\nreturn [\n {\n json: {\n fechaFormateada\n }\n }\n];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 2272, + 2096, 272 ], "id": "0d7870a9-0d82-49fe-96de-05c20164cffa", @@ -4529,7 +4241,7 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 2272, + 2096, 448 ], "id": "4abc2638-3ae3-4aba-b45f-0b60e73e3267", @@ -4625,38 +4337,38 @@ }, { "parameters": { - "jsCode": "const TIMEZONES = {\n \"Argentina\": \"America/Argentina/Buenos_Aires\",\n \"Bolivia\": \"America/La_Paz\",\n \"Brasil\": \"America/Sao_Paulo\",\n \"Chile\": \"America/Santiago\",\n \"Colombia\": \"America/Bogota\",\n \"Costa Rica\": \"America/Costa_Rica\",\n \"Cuba\": \"America/Havana\",\n \"Ecuador\": \"America/Guayaquil\",\n \"El Salvador\": \"America/El_Salvador\",\n \"Guatemala\": \"America/Guatemala\",\n \"Honduras\": \"America/Tegucigalpa\",\n \"Mexico\": \"America/Mexico_City\",\n \"Nicaragua\": \"America/Managua\",\n \"Panama\": \"America/Panama\",\n \"Paraguay\": \"America/Asuncion\",\n \"Peru\": \"America/Lima\",\n \"Puerto Rico\": \"America/Puerto_Rico\",\n \"Republica Dominicana\": \"America/Santo_Domingo\",\n \"Uruguay\": \"America/Montevideo\",\n \"Venezuela\": \"America/Caracas\",\n \"Jamaica\": \"America/Jamaica\",\n \"Trinidad and Tobago\": \"America/Port_of_Spain\",\n \"Guyana\": \"America/Guyana\",\n \"Surinam\": \"America/Paramaribo\",\n \"Belice\": \"America/Belize\"\n};\n\n// ==============================\n// FUNCIONES\n// ==============================\n\nfunction normalizarPais(texto) {\n return texto\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .trim()\n .toLowerCase();\n}\n\nfunction obtenerOffsetMinutos(fecha, timeZone) {\n const dtf = new Intl.DateTimeFormat(\"en-US\", {\n timeZone,\n hour12: false,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\"\n });\n\n const partes = dtf.formatToParts(fecha).reduce((acc, p) => {\n acc[p.type] = p.value;\n return acc;\n }, {});\n\n const utcEquivalente = Date.UTC(\n Number(partes.year),\n Number(partes.month) - 1,\n Number(partes.day),\n Number(partes.hour),\n Number(partes.minute),\n Number(partes.second)\n );\n\n return (utcEquivalente - fecha.getTime()) / 60000;\n}\n\nfunction obtenerUTCDesdeHoraLocal(horaTexto, timeZone) {\n const [hora, minuto] = horaTexto.split(\":\").map(Number);\n\n const ahora = new Date();\n\n const y = ahora.getUTCFullYear();\n const m = ahora.getUTCMonth();\n const d = ahora.getUTCDate();\n\n let fechaUTC = new Date(Date.UTC(y, m, d, hora, minuto, 0));\n\n const offset = obtenerOffsetMinutos(fechaUTC, timeZone);\n\n fechaUTC = new Date(fechaUTC.getTime() - offset * 60000);\n\n return fechaUTC;\n}\n\nfunction formatearHora(fechaUTC, timeZone) {\n return new Intl.DateTimeFormat(\"es-DO\", {\n timeZone,\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: false\n }).format(fechaUTC);\n}\n\nfunction convertirHoraDesdeSantoDomingo(horaTexto) {\n\n const fechaUTC = obtenerUTCDesdeHoraLocal(\n horaTexto,\n TIMEZONES[\"Republica Dominicana\"]\n );\n\n const resultado = {};\n\n for (const [pais, tz] of Object.entries(TIMEZONES)) {\n resultado[pais] = formatearHora(fechaUTC, tz);\n }\n\n return resultado;\n}\n\n// ==============================\n// EJECUCIÓN\n// ==============================\n\nconst horaEntrada = $('Calcular sesion mas cercana')\n .first()\n .json\n .session\n .hora_inicio;\n\nif (!horaEntrada || !/^\\d{1,2}:\\d{2}$/.test(horaEntrada)) {\n throw new Error(\n `Formato de hora inválido: \"${horaEntrada}\". Usa HH:mm, por ejemplo 19:00`\n );\n}\n\nconst conversiones = convertirHoraDesdeSantoDomingo(horaEntrada);\n\nreturn items.map(item => {\n\n const paisEntrada = item.json.pais;\n\n if (!paisEntrada) {\n throw new Error('Cada item debe contener el campo \"pais\".');\n }\n\n // Buscar el país ignorando mayúsculas y acentos\n const paisEncontrado = Object.keys(TIMEZONES).find(\n pais => normalizarPais(pais) === normalizarPais(paisEntrada)\n );\n\n if (!paisEncontrado) {\n throw new Error(\n `País no reconocido: \"${paisEntrada}\". Países válidos: ${Object.keys(TIMEZONES).join(\", \")}`\n );\n }\n\n return {\n json: {\n hora_base: horaEntrada,\n pais_base: \"Republica Dominicana\",\n hora_convertida: conversiones[paisEncontrado],\n conversiones\n }\n };\n});" + "jsCode": "const TIMEZONES = {\n \"Argentina\": \"America/Argentina/Buenos_Aires\",\n \"Bolivia\": \"America/La_Paz\",\n \"Brasil\": \"America/Sao_Paulo\",\n \"Chile\": \"America/Santiago\",\n \"Colombia\": \"America/Bogota\",\n \"Costa Rica\": \"America/Costa_Rica\",\n \"Cuba\": \"America/Havana\",\n \"Ecuador\": \"America/Guayaquil\",\n \"El Salvador\": \"America/El_Salvador\",\n \"Guatemala\": \"America/Guatemala\",\n \"Honduras\": \"America/Tegucigalpa\",\n \"Mexico\": \"America/Mexico_City\",\n \"Nicaragua\": \"America/Managua\",\n \"Panama\": \"America/Panama\",\n \"Paraguay\": \"America/Asuncion\",\n \"Peru\": \"America/Lima\",\n \"Puerto Rico\": \"America/Puerto_Rico\",\n \"Republica Dominicana\": \"America/Santo_Domingo\",\n \"Uruguay\": \"America/Montevideo\",\n \"Venezuela\": \"America/Caracas\",\n \"Jamaica\": \"America/Jamaica\",\n \"Trinidad and Tobago\": \"America/Port_of_Spain\",\n \"Guyana\": \"America/Guyana\",\n \"Surinam\": \"America/Paramaribo\",\n \"Belice\": \"America/Belize\"\n};\n\n// ==============================\n// FUNCIONES\n// ==============================\n\nfunction normalizarPais(texto) {\n return texto\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .trim()\n .toLowerCase();\n}\n\nfunction obtenerOffsetMinutos(fecha, timeZone) {\n const dtf = new Intl.DateTimeFormat(\"en-US\", {\n timeZone,\n hour12: false,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\"\n });\n\n const partes = dtf.formatToParts(fecha).reduce((acc, p) => {\n acc[p.type] = p.value;\n return acc;\n }, {});\n\n const utcEquivalente = Date.UTC(\n Number(partes.year),\n Number(partes.month) - 1,\n Number(partes.day),\n Number(partes.hour),\n Number(partes.minute),\n Number(partes.second)\n );\n\n return (utcEquivalente - fecha.getTime()) / 60000;\n}\n\nfunction obtenerUTCDesdeHoraLocal(horaTexto, timeZone) {\n const [hora, minuto] = horaTexto.split(\":\").map(Number);\n\n const ahora = new Date();\n\n const y = ahora.getUTCFullYear();\n const m = ahora.getUTCMonth();\n const d = ahora.getUTCDate();\n\n let fechaUTC = new Date(Date.UTC(y, m, d, hora, minuto, 0));\n\n const offset = obtenerOffsetMinutos(fechaUTC, timeZone);\n\n fechaUTC = new Date(fechaUTC.getTime() - offset * 60000);\n\n return fechaUTC;\n}\n\nfunction formatearHora(fechaUTC, timeZone) {\n return new Intl.DateTimeFormat(\"es-DO\", {\n timeZone,\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: false\n }).format(fechaUTC);\n}\n\nfunction convertirHoraDesdeSantoDomingo(horaTexto) {\n\n const fechaUTC = obtenerUTCDesdeHoraLocal(\n horaTexto,\n TIMEZONES[\"Republica Dominicana\"]\n );\n\n const resultado = {};\n\n for (const [pais, tz] of Object.entries(TIMEZONES)) {\n resultado[pais] = formatearHora(fechaUTC, tz);\n }\n\n return resultado;\n}\n\n// ==============================\n// EJECUCIÓN\n// ==============================\n\nconst horaEntrada = $('Calcular sesion mas cercana')\n .first()\n .json\n .session\n .hora_inicio;\n\nif (!horaEntrada || !/^\\d{1,2}:\\d{2}$/.test(horaEntrada)) {\n throw new Error(\n `Formato de hora inválido: \"${horaEntrada}\". Usa HH:mm, por ejemplo 19:00`\n );\n}\n\nconst conversiones = convertirHoraDesdeSantoDomingo(horaEntrada);\n\nreturn items.map(item => {\n\n const paisEntrada = $('Guardar datos del empleado y sesion asignada').first().json.pais;\n\n if (!paisEntrada) {\n throw new Error('Cada item debe contener el campo \"pais\".');\n }\n\n // Buscar el país ignorando mayúsculas y acentos\n const paisEncontrado = Object.keys(TIMEZONES).find(\n pais => normalizarPais(pais) === normalizarPais(paisEntrada)\n );\n\n if (!paisEncontrado) {\n throw new Error(\n `País no reconocido: \"${paisEntrada}\". Países válidos: ${Object.keys(TIMEZONES).join(\", \")}`\n );\n }\n\n return {\n json: {\n hora_base: horaEntrada,\n pais_base: \"Republica Dominicana\",\n hora_convertida: conversiones[paisEncontrado],\n conversiones\n }\n };\n});" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 2480, - -400 + 1888, + -336 ], "id": "740373c9-0145-41f4-a4b6-9dbb84ffbdaa", "name": "Cambiar zona horaria" }, { "parameters": { - "jsCode": "const TIMEZONES = {\n \"Argentina\": \"America/Argentina/Buenos_Aires\",\n \"Bolivia\": \"America/La_Paz\",\n \"Brasil\": \"America/Sao_Paulo\",\n \"Chile\": \"America/Santiago\",\n \"Colombia\": \"America/Bogota\",\n \"Costa Rica\": \"America/Costa_Rica\",\n \"Cuba\": \"America/Havana\",\n \"Ecuador\": \"America/Guayaquil\",\n \"El Salvador\": \"America/El_Salvador\",\n \"Guatemala\": \"America/Guatemala\",\n \"Honduras\": \"America/Tegucigalpa\",\n \"Mexico\": \"America/Mexico_City\",\n \"Nicaragua\": \"America/Managua\",\n \"Panama\": \"America/Panama\",\n \"Paraguay\": \"America/Asuncion\",\n \"Peru\": \"America/Lima\",\n \"Puerto Rico\": \"America/Puerto_Rico\",\n \"Republica Dominicana\": \"America/Santo_Domingo\",\n \"Uruguay\": \"America/Montevideo\",\n \"Venezuela\": \"America/Caracas\",\n \"Jamaica\": \"America/Jamaica\",\n \"Trinidad and Tobago\": \"America/Port_of_Spain\",\n \"Guyana\": \"America/Guyana\",\n \"Surinam\": \"America/Paramaribo\",\n \"Belice\": \"America/Belize\"\n};\n\n// ==============================\n// FUNCIONES\n// ==============================\n\nfunction normalizarPais(texto) {\n return texto\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .trim()\n .toLowerCase();\n}\n\nfunction obtenerOffsetMinutos(fecha, timeZone) {\n const dtf = new Intl.DateTimeFormat(\"en-US\", {\n timeZone,\n hour12: false,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\"\n });\n\n const partes = dtf.formatToParts(fecha).reduce((acc, p) => {\n acc[p.type] = p.value;\n return acc;\n }, {});\n\n const utcEquivalente = Date.UTC(\n Number(partes.year),\n Number(partes.month) - 1,\n Number(partes.day),\n Number(partes.hour),\n Number(partes.minute),\n Number(partes.second)\n );\n\n return (utcEquivalente - fecha.getTime()) / 60000;\n}\n\nfunction obtenerUTCDesdeHoraLocal(horaTexto, timeZone) {\n const [hora, minuto] = horaTexto.split(\":\").map(Number);\n\n const ahora = new Date();\n\n const y = ahora.getUTCFullYear();\n const m = ahora.getUTCMonth();\n const d = ahora.getUTCDate();\n\n let fechaUTC = new Date(Date.UTC(y, m, d, hora, minuto, 0));\n\n const offset = obtenerOffsetMinutos(fechaUTC, timeZone);\n\n fechaUTC = new Date(fechaUTC.getTime() - offset * 60000);\n\n return fechaUTC;\n}\n\nfunction formatearHora(fechaUTC, timeZone) {\n return new Intl.DateTimeFormat(\"es-DO\", {\n timeZone,\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: false\n }).format(fechaUTC);\n}\n\nfunction convertirHoraDesdeSantoDomingo(horaTexto) {\n\n const fechaUTC = obtenerUTCDesdeHoraLocal(\n horaTexto,\n TIMEZONES[\"Republica Dominicana\"]\n );\n\n const resultado = {};\n\n for (const [pais, tz] of Object.entries(TIMEZONES)) {\n resultado[pais] = formatearHora(fechaUTC, tz);\n }\n\n return resultado;\n}\n\n// ==============================\n// EJECUCIÓN\n// ==============================\n\nconst horaEntrada = $('Calcular sesion mas cercana1')\n .first()\n .json\n .session\n .hora_inicio;\n\nif (!horaEntrada || !/^\\d{1,2}:\\d{2}$/.test(horaEntrada)) {\n throw new Error(\n `Formato de hora inválido: \"${horaEntrada}\". Usa HH:mm, por ejemplo 19:00`\n );\n}\n\nconst conversiones = convertirHoraDesdeSantoDomingo(horaEntrada);\n\nreturn items.map(item => {\n\n const paisEntrada = item.json.pais;\n\n if (!paisEntrada) {\n throw new Error('Cada item debe contener el campo \"pais\".');\n }\n\n // Buscar el país ignorando mayúsculas y acentos\n const paisEncontrado = Object.keys(TIMEZONES).find(\n pais => normalizarPais(pais) === normalizarPais(paisEntrada)\n );\n\n if (!paisEncontrado) {\n throw new Error(\n `País no reconocido: \"${paisEntrada}\". Países válidos: ${Object.keys(TIMEZONES).join(\", \")}`\n );\n }\n\n return {\n json: {\n hora_base: horaEntrada,\n pais_base: \"Republica Dominicana\",\n hora_convertida: conversiones[paisEncontrado],\n conversiones\n }\n };\n});" + "jsCode": "const TIMEZONES = {\n \"Argentina\": \"America/Argentina/Buenos_Aires\",\n \"Bolivia\": \"America/La_Paz\",\n \"Brasil\": \"America/Sao_Paulo\",\n \"Chile\": \"America/Santiago\",\n \"Colombia\": \"America/Bogota\",\n \"Costa Rica\": \"America/Costa_Rica\",\n \"Cuba\": \"America/Havana\",\n \"Ecuador\": \"America/Guayaquil\",\n \"El Salvador\": \"America/El_Salvador\",\n \"Guatemala\": \"America/Guatemala\",\n \"Honduras\": \"America/Tegucigalpa\",\n \"Mexico\": \"America/Mexico_City\",\n \"Nicaragua\": \"America/Managua\",\n \"Panama\": \"America/Panama\",\n \"Paraguay\": \"America/Asuncion\",\n \"Peru\": \"America/Lima\",\n \"Puerto Rico\": \"America/Puerto_Rico\",\n \"Republica Dominicana\": \"America/Santo_Domingo\",\n \"Uruguay\": \"America/Montevideo\",\n \"Venezuela\": \"America/Caracas\",\n \"Jamaica\": \"America/Jamaica\",\n \"Trinidad and Tobago\": \"America/Port_of_Spain\",\n \"Guyana\": \"America/Guyana\",\n \"Surinam\": \"America/Paramaribo\",\n \"Belice\": \"America/Belize\"\n};\n\n// ==============================\n// FUNCIONES\n// ==============================\n\nfunction normalizarPais(texto) {\n return texto\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .trim()\n .toLowerCase();\n}\n\nfunction obtenerOffsetMinutos(fecha, timeZone) {\n const dtf = new Intl.DateTimeFormat(\"en-US\", {\n timeZone,\n hour12: false,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\"\n });\n\n const partes = dtf.formatToParts(fecha).reduce((acc, p) => {\n acc[p.type] = p.value;\n return acc;\n }, {});\n\n const utcEquivalente = Date.UTC(\n Number(partes.year),\n Number(partes.month) - 1,\n Number(partes.day),\n Number(partes.hour),\n Number(partes.minute),\n Number(partes.second)\n );\n\n return (utcEquivalente - fecha.getTime()) / 60000;\n}\n\nfunction obtenerUTCDesdeHoraLocal(horaTexto, timeZone) {\n const [hora, minuto] = horaTexto.split(\":\").map(Number);\n\n const ahora = new Date();\n\n const y = ahora.getUTCFullYear();\n const m = ahora.getUTCMonth();\n const d = ahora.getUTCDate();\n\n let fechaUTC = new Date(Date.UTC(y, m, d, hora, minuto, 0));\n\n const offset = obtenerOffsetMinutos(fechaUTC, timeZone);\n\n fechaUTC = new Date(fechaUTC.getTime() - offset * 60000);\n\n return fechaUTC;\n}\n\nfunction formatearHora(fechaUTC, timeZone) {\n return new Intl.DateTimeFormat(\"es-DO\", {\n timeZone,\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: false\n }).format(fechaUTC);\n}\n\nfunction convertirHoraDesdeSantoDomingo(horaTexto) {\n\n const fechaUTC = obtenerUTCDesdeHoraLocal(\n horaTexto,\n TIMEZONES[\"Republica Dominicana\"]\n );\n\n const resultado = {};\n\n for (const [pais, tz] of Object.entries(TIMEZONES)) {\n resultado[pais] = formatearHora(fechaUTC, tz);\n }\n\n return resultado;\n}\n\n// ==============================\n// EJECUCIÓN\n// ==============================\n\nconst horaEntrada = $('Calcular sesion mas cercana1')\n .first()\n .json\n .session\n .hora_inicio;\n\nif (!horaEntrada || !/^\\d{1,2}:\\d{2}$/.test(horaEntrada)) {\n throw new Error(\n `Formato de hora inválido: \"${horaEntrada}\". Usa HH:mm, por ejemplo 19:00`\n );\n}\n\nconst conversiones = convertirHoraDesdeSantoDomingo(horaEntrada);\n\nreturn items.map(item => {\n\n const paisEntrada = $('Guardar datos del empleado y sesion asignada1').first().json.pais;\n\n if (!paisEntrada) {\n throw new Error('Cada item debe contener el campo \"pais\".');\n }\n\n // Buscar el país ignorando mayúsculas y acentos\n const paisEncontrado = Object.keys(TIMEZONES).find(\n pais => normalizarPais(pais) === normalizarPais(paisEntrada)\n );\n\n if (!paisEncontrado) {\n throw new Error(\n `País no reconocido: \"${paisEntrada}\". Países válidos: ${Object.keys(TIMEZONES).join(\", \")}`\n );\n }\n\n return {\n json: {\n hora_base: horaEntrada,\n pais_base: \"Republica Dominicana\",\n hora_convertida: conversiones[paisEncontrado],\n conversiones\n }\n };\n});" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 2480, - -224 + 1888, + -160 ], "id": "77da2dc7-546b-4ab7-a7c7-fa621196b2d0", "name": "Cambiar zona horaria1" }, { "parameters": { - "jsCode": "const TIMEZONES = {\n \"Argentina\": \"America/Argentina/Buenos_Aires\",\n \"Bolivia\": \"America/La_Paz\",\n \"Brasil\": \"America/Sao_Paulo\",\n \"Chile\": \"America/Santiago\",\n \"Colombia\": \"America/Bogota\",\n \"Costa Rica\": \"America/Costa_Rica\",\n \"Cuba\": \"America/Havana\",\n \"Ecuador\": \"America/Guayaquil\",\n \"El Salvador\": \"America/El_Salvador\",\n \"Guatemala\": \"America/Guatemala\",\n \"Honduras\": \"America/Tegucigalpa\",\n \"Mexico\": \"America/Mexico_City\",\n \"Nicaragua\": \"America/Managua\",\n \"Panama\": \"America/Panama\",\n \"Paraguay\": \"America/Asuncion\",\n \"Peru\": \"America/Lima\",\n \"Puerto Rico\": \"America/Puerto_Rico\",\n \"Republica Dominicana\": \"America/Santo_Domingo\",\n \"Uruguay\": \"America/Montevideo\",\n \"Venezuela\": \"America/Caracas\",\n \"Jamaica\": \"America/Jamaica\",\n \"Trinidad and Tobago\": \"America/Port_of_Spain\",\n \"Guyana\": \"America/Guyana\",\n \"Surinam\": \"America/Paramaribo\",\n \"Belice\": \"America/Belize\"\n};\n\n// ==============================\n// FUNCIONES\n// ==============================\n\nfunction normalizarPais(texto) {\n return texto\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .trim()\n .toLowerCase();\n}\n\nfunction obtenerOffsetMinutos(fecha, timeZone) {\n const dtf = new Intl.DateTimeFormat(\"en-US\", {\n timeZone,\n hour12: false,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\"\n });\n\n const partes = dtf.formatToParts(fecha).reduce((acc, p) => {\n acc[p.type] = p.value;\n return acc;\n }, {});\n\n const utcEquivalente = Date.UTC(\n Number(partes.year),\n Number(partes.month) - 1,\n Number(partes.day),\n Number(partes.hour),\n Number(partes.minute),\n Number(partes.second)\n );\n\n return (utcEquivalente - fecha.getTime()) / 60000;\n}\n\nfunction obtenerUTCDesdeHoraLocal(horaTexto, timeZone) {\n const [hora, minuto] = horaTexto.split(\":\").map(Number);\n\n const ahora = new Date();\n\n const y = ahora.getUTCFullYear();\n const m = ahora.getUTCMonth();\n const d = ahora.getUTCDate();\n\n let fechaUTC = new Date(Date.UTC(y, m, d, hora, minuto, 0));\n\n const offset = obtenerOffsetMinutos(fechaUTC, timeZone);\n\n fechaUTC = new Date(fechaUTC.getTime() - offset * 60000);\n\n return fechaUTC;\n}\n\nfunction formatearHora(fechaUTC, timeZone) {\n return new Intl.DateTimeFormat(\"es-DO\", {\n timeZone,\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: false\n }).format(fechaUTC);\n}\n\nfunction convertirHoraDesdeSantoDomingo(horaTexto) {\n\n const fechaUTC = obtenerUTCDesdeHoraLocal(\n horaTexto,\n TIMEZONES[\"Republica Dominicana\"]\n );\n\n const resultado = {};\n\n for (const [pais, tz] of Object.entries(TIMEZONES)) {\n resultado[pais] = formatearHora(fechaUTC, tz);\n }\n\n return resultado;\n}\n\n// ==============================\n// EJECUCIÓN\n// ==============================\n\nconst horaEntrada = $('Calcular sesion mas cercana2')\n .first()\n .json\n .session\n .hora_inicio;\n\nif (!horaEntrada || !/^\\d{1,2}:\\d{2}$/.test(horaEntrada)) {\n throw new Error(\n `Formato de hora inválido: \"${horaEntrada}\". Usa HH:mm, por ejemplo 19:00`\n );\n}\n\nconst conversiones = convertirHoraDesdeSantoDomingo(horaEntrada);\n\nreturn items.map(item => {\n\n const paisEntrada = item.json.pais;\n\n if (!paisEntrada) {\n throw new Error('Cada item debe contener el campo \"pais\".');\n }\n\n // Buscar el país ignorando mayúsculas y acentos\n const paisEncontrado = Object.keys(TIMEZONES).find(\n pais => normalizarPais(pais) === normalizarPais(paisEntrada)\n );\n\n if (!paisEncontrado) {\n throw new Error(\n `País no reconocido: \"${paisEntrada}\". Países válidos: ${Object.keys(TIMEZONES).join(\", \")}`\n );\n }\n\n return {\n json: {\n hora_base: horaEntrada,\n pais_base: \"Republica Dominicana\",\n hora_convertida: conversiones[paisEncontrado],\n conversiones\n }\n };\n});" + "jsCode": "const TIMEZONES = {\n \"Argentina\": \"America/Argentina/Buenos_Aires\",\n \"Bolivia\": \"America/La_Paz\",\n \"Brasil\": \"America/Sao_Paulo\",\n \"Chile\": \"America/Santiago\",\n \"Colombia\": \"America/Bogota\",\n \"Costa Rica\": \"America/Costa_Rica\",\n \"Cuba\": \"America/Havana\",\n \"Ecuador\": \"America/Guayaquil\",\n \"El Salvador\": \"America/El_Salvador\",\n \"Guatemala\": \"America/Guatemala\",\n \"Honduras\": \"America/Tegucigalpa\",\n \"Mexico\": \"America/Mexico_City\",\n \"Nicaragua\": \"America/Managua\",\n \"Panama\": \"America/Panama\",\n \"Paraguay\": \"America/Asuncion\",\n \"Peru\": \"America/Lima\",\n \"Puerto Rico\": \"America/Puerto_Rico\",\n \"Republica Dominicana\": \"America/Santo_Domingo\",\n \"Uruguay\": \"America/Montevideo\",\n \"Venezuela\": \"America/Caracas\",\n \"Jamaica\": \"America/Jamaica\",\n \"Trinidad and Tobago\": \"America/Port_of_Spain\",\n \"Guyana\": \"America/Guyana\",\n \"Surinam\": \"America/Paramaribo\",\n \"Belice\": \"America/Belize\"\n};\n\n// ==============================\n// FUNCIONES\n// ==============================\n\nfunction normalizarPais(texto) {\n return texto\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .trim()\n .toLowerCase();\n}\n\nfunction obtenerOffsetMinutos(fecha, timeZone) {\n const dtf = new Intl.DateTimeFormat(\"en-US\", {\n timeZone,\n hour12: false,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\"\n });\n\n const partes = dtf.formatToParts(fecha).reduce((acc, p) => {\n acc[p.type] = p.value;\n return acc;\n }, {});\n\n const utcEquivalente = Date.UTC(\n Number(partes.year),\n Number(partes.month) - 1,\n Number(partes.day),\n Number(partes.hour),\n Number(partes.minute),\n Number(partes.second)\n );\n\n return (utcEquivalente - fecha.getTime()) / 60000;\n}\n\nfunction obtenerUTCDesdeHoraLocal(horaTexto, timeZone) {\n const [hora, minuto] = horaTexto.split(\":\").map(Number);\n\n const ahora = new Date();\n\n const y = ahora.getUTCFullYear();\n const m = ahora.getUTCMonth();\n const d = ahora.getUTCDate();\n\n let fechaUTC = new Date(Date.UTC(y, m, d, hora, minuto, 0));\n\n const offset = obtenerOffsetMinutos(fechaUTC, timeZone);\n\n fechaUTC = new Date(fechaUTC.getTime() - offset * 60000);\n\n return fechaUTC;\n}\n\nfunction formatearHora(fechaUTC, timeZone) {\n return new Intl.DateTimeFormat(\"es-DO\", {\n timeZone,\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: false\n }).format(fechaUTC);\n}\n\nfunction convertirHoraDesdeSantoDomingo(horaTexto) {\n\n const fechaUTC = obtenerUTCDesdeHoraLocal(\n horaTexto,\n TIMEZONES[\"Republica Dominicana\"]\n );\n\n const resultado = {};\n\n for (const [pais, tz] of Object.entries(TIMEZONES)) {\n resultado[pais] = formatearHora(fechaUTC, tz);\n }\n\n return resultado;\n}\n\n// ==============================\n// EJECUCIÓN\n// ==============================\n\nconst horaEntrada = $('Calcular sesion mas cercana2')\n .first()\n .json\n .session\n .hora_inicio;\n\nif (!horaEntrada || !/^\\d{1,2}:\\d{2}$/.test(horaEntrada)) {\n throw new Error(\n `Formato de hora inválido: \"${horaEntrada}\". Usa HH:mm, por ejemplo 19:00`\n );\n}\n\nconst conversiones = convertirHoraDesdeSantoDomingo(horaEntrada);\n\nreturn items.map(item => {\n\n const paisEntrada = $('Actualizar datos del empleado y sesion asignada').first().json.pais;\n\n if (!paisEntrada) {\n throw new Error('Cada item debe contener el campo \"pais\".');\n }\n\n // Buscar el país ignorando mayúsculas y acentos\n const paisEncontrado = Object.keys(TIMEZONES).find(\n pais => normalizarPais(pais) === normalizarPais(paisEntrada)\n );\n\n if (!paisEncontrado) {\n throw new Error(\n `País no reconocido: \"${paisEntrada}\". Países válidos: ${Object.keys(TIMEZONES).join(\", \")}`\n );\n }\n\n return {\n json: {\n hora_base: horaEntrada,\n pais_base: \"Republica Dominicana\",\n hora_convertida: conversiones[paisEncontrado],\n conversiones\n }\n };\n});" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 2464, + 2288, 272 ], "id": "bbd8c7de-64eb-4262-a77b-b7307ab9c0c6", @@ -4664,12 +4376,12 @@ }, { "parameters": { - "jsCode": "const TIMEZONES = {\n \"Argentina\": \"America/Argentina/Buenos_Aires\",\n \"Bolivia\": \"America/La_Paz\",\n \"Brasil\": \"America/Sao_Paulo\",\n \"Chile\": \"America/Santiago\",\n \"Colombia\": \"America/Bogota\",\n \"Costa Rica\": \"America/Costa_Rica\",\n \"Cuba\": \"America/Havana\",\n \"Ecuador\": \"America/Guayaquil\",\n \"El Salvador\": \"America/El_Salvador\",\n \"Guatemala\": \"America/Guatemala\",\n \"Honduras\": \"America/Tegucigalpa\",\n \"Mexico\": \"America/Mexico_City\",\n \"Nicaragua\": \"America/Managua\",\n \"Panama\": \"America/Panama\",\n \"Paraguay\": \"America/Asuncion\",\n \"Peru\": \"America/Lima\",\n \"Puerto Rico\": \"America/Puerto_Rico\",\n \"Republica Dominicana\": \"America/Santo_Domingo\",\n \"Uruguay\": \"America/Montevideo\",\n \"Venezuela\": \"America/Caracas\",\n \"Jamaica\": \"America/Jamaica\",\n \"Trinidad and Tobago\": \"America/Port_of_Spain\",\n \"Guyana\": \"America/Guyana\",\n \"Surinam\": \"America/Paramaribo\",\n \"Belice\": \"America/Belize\"\n};\n\n// ==============================\n// FUNCIONES\n// ==============================\n\nfunction normalizarPais(texto) {\n return texto\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .trim()\n .toLowerCase();\n}\n\nfunction obtenerOffsetMinutos(fecha, timeZone) {\n const dtf = new Intl.DateTimeFormat(\"en-US\", {\n timeZone,\n hour12: false,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\"\n });\n\n const partes = dtf.formatToParts(fecha).reduce((acc, p) => {\n acc[p.type] = p.value;\n return acc;\n }, {});\n\n const utcEquivalente = Date.UTC(\n Number(partes.year),\n Number(partes.month) - 1,\n Number(partes.day),\n Number(partes.hour),\n Number(partes.minute),\n Number(partes.second)\n );\n\n return (utcEquivalente - fecha.getTime()) / 60000;\n}\n\nfunction obtenerUTCDesdeHoraLocal(horaTexto, timeZone) {\n const [hora, minuto] = horaTexto.split(\":\").map(Number);\n\n const ahora = new Date();\n\n const y = ahora.getUTCFullYear();\n const m = ahora.getUTCMonth();\n const d = ahora.getUTCDate();\n\n let fechaUTC = new Date(Date.UTC(y, m, d, hora, minuto, 0));\n\n const offset = obtenerOffsetMinutos(fechaUTC, timeZone);\n\n fechaUTC = new Date(fechaUTC.getTime() - offset * 60000);\n\n return fechaUTC;\n}\n\nfunction formatearHora(fechaUTC, timeZone) {\n return new Intl.DateTimeFormat(\"es-DO\", {\n timeZone,\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: false\n }).format(fechaUTC);\n}\n\nfunction convertirHoraDesdeSantoDomingo(horaTexto) {\n\n const fechaUTC = obtenerUTCDesdeHoraLocal(\n horaTexto,\n TIMEZONES[\"Republica Dominicana\"]\n );\n\n const resultado = {};\n\n for (const [pais, tz] of Object.entries(TIMEZONES)) {\n resultado[pais] = formatearHora(fechaUTC, tz);\n }\n\n return resultado;\n}\n\n// ==============================\n// EJECUCIÓN\n// ==============================\n\nconst horaEntrada = $('Calcular sesion mas cercana3')\n .first()\n .json\n .session\n .hora_inicio;\n\nif (!horaEntrada || !/^\\d{1,2}:\\d{2}$/.test(horaEntrada)) {\n throw new Error(\n `Formato de hora inválido: \"${horaEntrada}\". Usa HH:mm, por ejemplo 19:00`\n );\n}\n\nconst conversiones = convertirHoraDesdeSantoDomingo(horaEntrada);\n\nreturn items.map(item => {\n\n const paisEntrada = item.json.pais;\n\n if (!paisEntrada) {\n throw new Error('Cada item debe contener el campo \"pais\".');\n }\n\n // Buscar el país ignorando mayúsculas y acentos\n const paisEncontrado = Object.keys(TIMEZONES).find(\n pais => normalizarPais(pais) === normalizarPais(paisEntrada)\n );\n\n if (!paisEncontrado) {\n throw new Error(\n `País no reconocido: \"${paisEntrada}\". Países válidos: ${Object.keys(TIMEZONES).join(\", \")}`\n );\n }\n\n return {\n json: {\n hora_base: horaEntrada,\n pais_base: \"Republica Dominicana\",\n hora_convertida: conversiones[paisEncontrado],\n conversiones\n }\n };\n});" + "jsCode": "const TIMEZONES = {\n \"Argentina\": \"America/Argentina/Buenos_Aires\",\n \"Bolivia\": \"America/La_Paz\",\n \"Brasil\": \"America/Sao_Paulo\",\n \"Chile\": \"America/Santiago\",\n \"Colombia\": \"America/Bogota\",\n \"Costa Rica\": \"America/Costa_Rica\",\n \"Cuba\": \"America/Havana\",\n \"Ecuador\": \"America/Guayaquil\",\n \"El Salvador\": \"America/El_Salvador\",\n \"Guatemala\": \"America/Guatemala\",\n \"Honduras\": \"America/Tegucigalpa\",\n \"Mexico\": \"America/Mexico_City\",\n \"Nicaragua\": \"America/Managua\",\n \"Panama\": \"America/Panama\",\n \"Paraguay\": \"America/Asuncion\",\n \"Peru\": \"America/Lima\",\n \"Puerto Rico\": \"America/Puerto_Rico\",\n \"Republica Dominicana\": \"America/Santo_Domingo\",\n \"Uruguay\": \"America/Montevideo\",\n \"Venezuela\": \"America/Caracas\",\n \"Jamaica\": \"America/Jamaica\",\n \"Trinidad and Tobago\": \"America/Port_of_Spain\",\n \"Guyana\": \"America/Guyana\",\n \"Surinam\": \"America/Paramaribo\",\n \"Belice\": \"America/Belize\"\n};\n\n// ==============================\n// FUNCIONES\n// ==============================\n\nfunction normalizarPais(texto) {\n return texto\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .trim()\n .toLowerCase();\n}\n\nfunction obtenerOffsetMinutos(fecha, timeZone) {\n const dtf = new Intl.DateTimeFormat(\"en-US\", {\n timeZone,\n hour12: false,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\"\n });\n\n const partes = dtf.formatToParts(fecha).reduce((acc, p) => {\n acc[p.type] = p.value;\n return acc;\n }, {});\n\n const utcEquivalente = Date.UTC(\n Number(partes.year),\n Number(partes.month) - 1,\n Number(partes.day),\n Number(partes.hour),\n Number(partes.minute),\n Number(partes.second)\n );\n\n return (utcEquivalente - fecha.getTime()) / 60000;\n}\n\nfunction obtenerUTCDesdeHoraLocal(horaTexto, timeZone) {\n const [hora, minuto] = horaTexto.split(\":\").map(Number);\n\n const ahora = new Date();\n\n const y = ahora.getUTCFullYear();\n const m = ahora.getUTCMonth();\n const d = ahora.getUTCDate();\n\n let fechaUTC = new Date(Date.UTC(y, m, d, hora, minuto, 0));\n\n const offset = obtenerOffsetMinutos(fechaUTC, timeZone);\n\n fechaUTC = new Date(fechaUTC.getTime() - offset * 60000);\n\n return fechaUTC;\n}\n\nfunction formatearHora(fechaUTC, timeZone) {\n return new Intl.DateTimeFormat(\"es-DO\", {\n timeZone,\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: false\n }).format(fechaUTC);\n}\n\nfunction convertirHoraDesdeSantoDomingo(horaTexto) {\n\n const fechaUTC = obtenerUTCDesdeHoraLocal(\n horaTexto,\n TIMEZONES[\"Republica Dominicana\"]\n );\n\n const resultado = {};\n\n for (const [pais, tz] of Object.entries(TIMEZONES)) {\n resultado[pais] = formatearHora(fechaUTC, tz);\n }\n\n return resultado;\n}\n\n// ==============================\n// EJECUCIÓN\n// ==============================\n\nconst horaEntrada = $('Calcular sesion mas cercana3')\n .first()\n .json\n .session\n .hora_inicio;\n\nif (!horaEntrada || !/^\\d{1,2}:\\d{2}$/.test(horaEntrada)) {\n throw new Error(\n `Formato de hora inválido: \"${horaEntrada}\". Usa HH:mm, por ejemplo 19:00`\n );\n}\n\nconst conversiones = convertirHoraDesdeSantoDomingo(horaEntrada);\n\nreturn items.map(item => {\n\n const paisEntrada = $('Actualizar datos del empleado y sesion asignada1').first().json.pais;\n\n if (!paisEntrada) {\n throw new Error('Cada item debe contener el campo \"pais\".');\n }\n\n // Buscar el país ignorando mayúsculas y acentos\n const paisEncontrado = Object.keys(TIMEZONES).find(\n pais => normalizarPais(pais) === normalizarPais(paisEntrada)\n );\n\n if (!paisEncontrado) {\n throw new Error(\n `País no reconocido: \"${paisEntrada}\". Países válidos: ${Object.keys(TIMEZONES).join(\", \")}`\n );\n }\n\n return {\n json: {\n hora_base: horaEntrada,\n pais_base: \"Republica Dominicana\",\n hora_convertida: conversiones[paisEncontrado],\n conversiones\n }\n };\n});" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 2464, + 2288, 448 ], "id": "677acc91-b856-482e-aa2c-9b329221918a", @@ -4752,6 +4464,271 @@ "name": "Sofia test - Supabase account" } } + }, + { + "parameters": { + "resource": "meeting", + "operation": "addToLiveMeeting", + "additionalFields": {} + }, + "type": "@firefliesai/n8n-nodes-fireflies.fireflies", + "typeVersion": 1, + "position": [ + -336, + 3440 + ], + "id": "6852b24e-9982-487d-a926-942f6d2bb7b3", + "name": "Add fred to a live meeting" + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict", + "version": 3 + }, + "conditions": [ + { + "id": "d7d68505-8c34-44cd-b771-56bef28ada41", + "leftValue": "={{ $('Get an employee').item.json.workEmail }}", + "rightValue": "", + "operator": { + "type": "string", + "operation": "notEmpty", + "singleValue": true + } + }, + { + "id": "ec0276ab-208e-409b-8101-d06e535f541c", + "leftValue": "={{ $('Get an employee').item.json.location }}", + "rightValue": "", + "operator": { + "type": "string", + "operation": "notEmpty", + "singleValue": true + } + } + ], + "combinator": "and" + }, + "options": {} + }, + "type": "n8n-nodes-base.if", + "typeVersion": 2.3, + "position": [ + 352, + -144 + ], + "id": "a9fff247-d1b0-4314-ba8d-e7401086b771", + "name": "Tiene correo y pais?" + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict", + "version": 3 + }, + "conditions": [ + { + "id": "d7d68505-8c34-44cd-b771-56bef28ada41", + "leftValue": "={{ $('Get an employee1').item.json.workEmail }}", + "rightValue": "", + "operator": { + "type": "string", + "operation": "notEmpty", + "singleValue": true + } + }, + { + "id": "a245c081-ef08-4ba2-8164-2d2c35bd1e17", + "leftValue": "={{ $('Get an employee1').item.json.location }}", + "rightValue": "", + "operator": { + "type": "string", + "operation": "notEmpty", + "singleValue": true + } + } + ], + "combinator": "and" + }, + "options": {} + }, + "type": "n8n-nodes-base.if", + "typeVersion": 2.3, + "position": [ + 752, + 352 + ], + "id": "a2a81e91-f617-490a-b1ce-5737944fa23b", + "name": "Tiene correo y pais?1" + }, + { + "parameters": { + "operation": "update", + "tableId": "inscritos_glmway", + "filters": { + "conditions": [ + { + "keyName": "empleado_id", + "condition": "eq", + "keyValue": "={{ $('Get an employee1').item.json.id }}" + } + ] + }, + "fieldsUi": { + "fieldValues": [ + { + "fieldId": "empleado_id", + "fieldValue": "={{ $('Informacion extra del empleado1').item.json.id }}" + }, + { + "fieldId": "nombre", + "fieldValue": "={{ $('Get an employee1').item.json.displayName }}" + }, + { + "fieldId": "email", + "fieldValue": "={{ $('Get an employee1').item.json.workEmail }}" + }, + { + "fieldId": "departamento", + "fieldValue": "={{ $('Get an employee1').item.json.department }}" + }, + { + "fieldId": "supervisor_id", + "fieldValue": "={{ $('Informacion extra del empleado1').item.json.supervisorEId }}" + }, + { + "fieldId": "fecha_ingreso", + "fieldValue": "={{ $('Informacion extra del empleado1').item.json.hireDate }}" + }, + { + "fieldId": "fecha_sesion_inscrito", + "fieldValue": "={{ $json.session.fecha_sesion }}" + }, + { + "fieldId": "estado", + "fieldValue": "notificado" + }, + { + "fieldId": "sesion_id", + "fieldValue": "={{ $json.session.id }}" + }, + { + "fieldId": "pais", + "fieldValue": "={{ $('Get an employee1').item.json.location }}" + }, + { + "fieldId": "division", + "fieldValue": "={{ $('Get an employee1').item.json.division }}" + }, + { + "fieldId": "puesto", + "fieldValue": "={{ $('Get an employee1').item.json.jobTitle }}" + } + ] + } + }, + "type": "n8n-nodes-base.supabase", + "typeVersion": 1, + "position": [ + 1904, + 272 + ], + "id": "16d364da-e6fc-4943-bd64-f83ccab66b9f", + "name": "Actualizar datos del empleado y sesion asignada", + "credentials": { + "supabaseApi": { + "id": "2PlsR6rpK7rQTIEn", + "name": "Sofia test - Supabase account" + } + } + }, + { + "parameters": { + "operation": "update", + "tableId": "inscritos_glmway", + "filters": { + "conditions": [ + { + "keyName": "empleado_id", + "condition": "eq", + "keyValue": "={{ $('Get an employee1').item.json.id }}" + } + ] + }, + "fieldsUi": { + "fieldValues": [ + { + "fieldId": "empleado_id", + "fieldValue": "={{ $('Informacion extra del empleado1').item.json.id }}" + }, + { + "fieldId": "nombre", + "fieldValue": "={{ $('Get an employee1').item.json.displayName }}" + }, + { + "fieldId": "email", + "fieldValue": "={{ $('Get an employee1').item.json.workEmail }}" + }, + { + "fieldId": "departamento", + "fieldValue": "={{ $('Get an employee1').item.json.department }}" + }, + { + "fieldId": "supervisor_id", + "fieldValue": "={{ $('Informacion extra del empleado1').item.json.supervisorEId }}" + }, + { + "fieldId": "fecha_ingreso", + "fieldValue": "={{ $('Informacion extra del empleado1').item.json.hireDate }}" + }, + { + "fieldId": "fecha_sesion_inscrito", + "fieldValue": "={{ $json.session.fecha_sesion }}" + }, + { + "fieldId": "estado", + "fieldValue": "notificado" + }, + { + "fieldId": "sesion_id", + "fieldValue": "={{ $json.session.id }}" + }, + { + "fieldId": "pais", + "fieldValue": "={{ $('Get an employee1').item.json.location }}" + }, + { + "fieldId": "division", + "fieldValue": "={{ $('Get an employee1').item.json.division }}" + }, + { + "fieldId": "puesto", + "fieldValue": "={{ $('Get an employee1').item.json.jobTitle }}" + } + ] + } + }, + "type": "n8n-nodes-base.supabase", + "typeVersion": 1, + "position": [ + 1904, + 448 + ], + "id": "f2aca2bd-e72d-4457-9a6b-c4b0f8bcc558", + "name": "Actualizar datos del empleado y sesion asignada1", + "credentials": { + "supabaseApi": { + "id": "2PlsR6rpK7rQTIEn", + "name": "Sofia test - Supabase account" + } + } } ], "connections": { @@ -4892,7 +4869,7 @@ "main": [ [ { - "node": "Obtener coordinador", + "node": "Pais?", "type": "main", "index": 0 } @@ -4910,7 +4887,7 @@ "main": [ [ { - "node": "Tiene correo?1", + "node": "Tiene correo y pais?", "type": "main", "index": 0 } @@ -4919,13 +4896,7 @@ }, "Hay coordinador?": { "main": [ - [ - { - "node": "Pais?", - "type": "main", - "index": 0 - } - ], + [], [ { "node": "Alerta no hay coordinador RRHH", @@ -4994,7 +4965,7 @@ "main": [ [ { - "node": "Tiene correo?", + "node": "Tiene correo y pais?1", "type": "main", "index": 0 } @@ -5087,7 +5058,7 @@ "main": [ [ { - "node": "Obtener coordinador1", + "node": "Registrar empleado a la sesion3", "type": "main", "index": 0 } @@ -5098,7 +5069,7 @@ "main": [ [ { - "node": "Obtener coordinador1", + "node": "Registrar empleado a la sesion2", "type": "main", "index": 0 } @@ -5314,7 +5285,7 @@ "main": [ [ { - "node": "Actualizar datos del empleado y sesion asignada2", + "node": "Actualizar datos del empleado y sesion asignada", "type": "main", "index": 0 } @@ -5325,7 +5296,7 @@ "main": [ [ { - "node": "Actualizar datos del empleado y sesion asignada3", + "node": "Actualizar datos del empleado y sesion asignada1", "type": "main", "index": 0 } @@ -5336,7 +5307,7 @@ "main": [ [ { - "node": "Registrar empleado a la sesion", + "node": "Convertir fecha a espanol", "type": "main", "index": 0 } @@ -5347,7 +5318,7 @@ "main": [ [ { - "node": "Registrar empleado a la sesion1", + "node": "Convertir fecha a ingles", "type": "main", "index": 0 } @@ -5398,35 +5369,6 @@ ] ] }, - "Tiene correo?": { - "main": [ - [ - { - "node": "Entra hoy?1", - "type": "main", - "index": 0 - } - ], - [ - { - "node": "Wait2", - "type": "main", - "index": 0 - } - ] - ] - }, - "Actualizar datos del empleado y sesion asignada2": { - "main": [ - [ - { - "node": "Registrar empleado a la sesion2", - "type": "main", - "index": 0 - } - ] - ] - }, "Obtener notificados": { "main": [ [ @@ -5575,35 +5517,6 @@ ] ] }, - "Actualizar datos del empleado y sesion asignada3": { - "main": [ - [ - { - "node": "Registrar empleado a la sesion3", - "type": "main", - "index": 0 - } - ] - ] - }, - "Tiene correo?1": { - "main": [ - [ - { - "node": "Entra hoy?", - "type": "main", - "index": 0 - } - ], - [ - { - "node": "Insertar a inscritos (inactivo)", - "type": "main", - "index": 0 - } - ] - ] - }, "Schedule Trigger4": { "main": [ [ @@ -5997,7 +5910,7 @@ "main": [ [ { - "node": "Convertir fecha a espanol", + "node": "Obtener coordinador", "type": "main", "index": 0 } @@ -6008,7 +5921,7 @@ "main": [ [ { - "node": "Convertir fecha a ingles", + "node": "Obtener coordinador", "type": "main", "index": 0 } @@ -6019,7 +5932,7 @@ "main": [ [ { - "node": "Convertir fecha a espanol1", + "node": "Obtener coordinador1", "type": "main", "index": 0 } @@ -6030,7 +5943,7 @@ "main": [ [ { - "node": "Convertir fecha a ingles1", + "node": "Obtener coordinador1", "type": "main", "index": 0 } @@ -6186,6 +6099,86 @@ } ] ] + }, + "Tiene correo y pais?": { + "main": [ + [ + { + "node": "Entra hoy?", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Insertar a inscritos (inactivo)", + "type": "main", + "index": 0 + } + ] + ] + }, + "Tiene correo y pais?1": { + "main": [ + [ + { + "node": "Entra hoy?1", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Wait2", + "type": "main", + "index": 0 + } + ] + ] + }, + "Send a message espanol": { + "main": [ + [ + { + "node": "Registrar empleado a la sesion", + "type": "main", + "index": 0 + } + ] + ] + }, + "Send a message ingles": { + "main": [ + [ + { + "node": "Registrar empleado a la sesion1", + "type": "main", + "index": 0 + } + ] + ] + }, + "Actualizar datos del empleado y sesion asignada": { + "main": [ + [ + { + "node": "Convertir fecha a espanol1", + "type": "main", + "index": 0 + } + ] + ] + }, + "Actualizar datos del empleado y sesion asignada1": { + "main": [ + [ + { + "node": "Convertir fecha a ingles1", + "type": "main", + "index": 0 + } + ] + ] } }, "settings": { @@ -6210,19 +6203,19 @@ "recurrenceRules": [] }, "node:Comenzo evento ingles": { - "lastTimeChecked": "2026-07-02T19:00:13Z" + "lastTimeChecked": "2026-07-03T15:28:29Z" }, "node:Comenzo evento español": { - "lastTimeChecked": "2026-07-02T18:59:34Z" + "lastTimeChecked": "2026-07-03T15:28:29Z" }, "node:Termino evento español": { - "lastTimeChecked": "2026-07-02T18:59:35Z" + "lastTimeChecked": "2026-07-03T15:28:29Z" }, "node:Termino evento ingles": { - "lastTimeChecked": "2026-07-02T18:59:33Z" + "lastTimeChecked": "2026-07-03T15:28:30Z" }, "node:Prueba": { - "lastTimeChecked": "2026-07-02T18:59:59Z" + "lastTimeChecked": "2026-07-03T15:28:30Z" }, "node:Schedule Trigger2": { "recurrenceRules": [] @@ -6256,320 +6249,11 @@ "item": 0 } } - ], - "Termino evento español": [ - { - "json": { - "kind": "calendar#event", - "etag": "\"3562422476268862\"", - "id": "3ul4moq4isoavr9jhqpcbs7juu_20260617T230000Z", - "status": "confirmed", - "htmlLink": "https://www.google.com/calendar/event?eid=M3VsNG1vcTRpc29hdnI5amhxcGNiczdqdXVfMjAyNjA2MTdUMjMwMDAwWiBldGhlbkBnb21lemxlZW1hcmtldGluZy5jb20", - "created": "2023-06-16T17:18:01.000Z", - "updated": "2026-06-11T20:53:58.134Z", - "summary": "Entrenamiento #TheGLMWay", - "description": "Hola, GLMer!\n\nEn este entrenamiento queremos transmitirte nuestra cultura, nuestro ADN y por qué somos diferentes al resto.\n\nTe esperamos puntual y con todas las ganas de aprender.\n\nNos vemos en el enlace!", - "creator": { - "email": "fvicioso@gomezleemarketing.com", - "displayName": "Francis Vicioso" - }, - "organizer": { - "email": "fvicioso@gomezleemarketing.com", - "displayName": "Francis Vicioso" - }, - "start": { - "dateTime": "2026-06-17T19:00:00-04:00", - "timeZone": "America/Bogota" - }, - "end": { - "dateTime": "2026-06-17T20:00:00-04:00", - "timeZone": "America/Bogota" - }, - "recurringEventId": "3ul4moq4isoavr9jhqpcbs7juu_R20260603T230000", - "originalStartTime": { - "dateTime": "2026-06-17T19:00:00-04:00", - "timeZone": "America/Bogota" - }, - "iCalUID": "3ul4moq4isoavr9jhqpcbs7juu_R20260603T230000@google.com", - "sequence": 1, - "attendees": [ - { - "email": "ymadera@gomezleemarketing.com", - "displayName": "Yanelly Madera", - "responseStatus": "needsAction" - }, - { - "email": "rlee@gomezleemarketing.com", - "displayName": "Rossy Lee", - "responseStatus": "needsAction" - }, - { - "email": "fherrera@gomezleemarketing.com", - "responseStatus": "needsAction" - }, - { - "email": "pmerida@gomezleemarketing.com", - "displayName": "Poul Merida", - "responseStatus": "accepted" - }, - { - "email": "lgomez@gomezleemarketing.com", - "displayName": "Leopoldo Gomez", - "responseStatus": "accepted" - }, - { - "email": "grodriguez@gomezleemarketing.com", - "displayName": "Gerardo Rodriguez", - "responseStatus": "accepted" - }, - { - "email": "gmedina@gomezleemarketing.com", - "displayName": "Gabriel Medina", - "responseStatus": "accepted" - }, - { - "email": "fvicioso@gomezleemarketing.com", - "displayName": "Francis Vicioso", - "organizer": true, - "responseStatus": "accepted" - }, - { - "email": "lmgomez@gomezleemarketing.com", - "displayName": "Lil Gomez", - "responseStatus": "accepted" - }, - { - "email": "lsantana@gomezleemarketing.com", - "displayName": "Lizbeth Santana", - "responseStatus": "needsAction" - }, - { - "email": "jfnunez@gomezleemarketing.com", - "displayName": "José Fernando Núñez", - "responseStatus": "accepted" - }, - { - "email": "lcabrera@gomezleemarketing.com", - "displayName": "Lucy Cabrera", - "responseStatus": "needsAction" - }, - { - "email": "momendoza@gomezleemarketing.com", - "displayName": "Moisés Mendoza", - "responseStatus": "accepted" - }, - { - "email": "clopez@gomezleemarketing.com", - "responseStatus": "accepted" - }, - { - "email": "ccastro@gomezleemarketing.com", - "responseStatus": "accepted" - }, - { - "email": "cmalta@gomezleemarketing.com", - "responseStatus": "accepted" - }, - { - "email": "evitiello@gomezleemarketing.com", - "responseStatus": "accepted" - }, - { - "email": "jgalvez@gomezleemarketing.com", - "responseStatus": "needsAction" - }, - { - "email": "mchang@gomezleemarketing.com", - "responseStatus": "accepted" - }, - { - "email": "mffonseca@gomezleemarketing.com", - "responseStatus": "needsAction" - }, - { - "email": "mperalta@gomezleemarketing.com", - "responseStatus": "accepted" - }, - { - "email": "rrhhcolombia@gomezleemarketing.com", - "displayName": "Edna Leon Aguillon", - "responseStatus": "accepted" - }, - { - "email": "yestrada@gomezleemarketing.com", - "responseStatus": "accepted" - }, - { - "email": "malcala@gomezleemarketing.com", - "responseStatus": "needsAction" - }, - { - "email": "wduran@gomezleemarketing.com", - "responseStatus": "needsAction" - }, - { - "email": "mgomez@gomezleemarketing.com", - "displayName": "Maximo Gomez", - "responseStatus": "accepted" - }, - { - "email": "admincr@gomezleemarketing.com", - "responseStatus": "accepted" - }, - { - "email": "jlgomez@gomezleemarketing.com", - "displayName": "José Leopoldo Gomez", - "responseStatus": "accepted" - }, - { - "email": "cmogollon@gomezleemarketing.com", - "responseStatus": "accepted" - }, - { - "email": "naguirre@gomezleemarketing.com", - "responseStatus": "accepted" - }, - { - "email": "eurroz@gomezleemarketing.com", - "responseStatus": "needsAction" - }, - { - "email": "jmendieta@gomezleemarketing.com", - "responseStatus": "needsAction" - }, - { - "email": "mcgonzalez@gomezleemarketing.com", - "responseStatus": "accepted" - }, - { - "email": "ktellez@gomezleemarketing.com", - "responseStatus": "needsAction" - }, - { - "email": "nconcha@gomezleemarketing.com", - "responseStatus": "needsAction" - }, - { - "email": "lmatos@gomezleemarketing.com", - "displayName": "Luis Matos", - "responseStatus": "needsAction" - }, - { - "email": "ethen@gomezleemarketing.com", - "self": true, - "responseStatus": "needsAction" - } - ], - "hangoutLink": "https://meet.google.com/aao-ixkr-uwu", - "conferenceData": { - "entryPoints": [ - { - "entryPointType": "video", - "uri": "https://meet.google.com/aao-ixkr-uwu", - "label": "meet.google.com/aao-ixkr-uwu" - }, - { - "entryPointType": "more", - "uri": "https://tel.meet/aao-ixkr-uwu?pin=8360818227823", - "pin": "8360818227823" - }, - { - "regionCode": "CO", - "entryPointType": "phone", - "uri": "tel:+57-602-3896750", - "label": "+57 602 3896750", - "pin": "492538130" - } - ], - "conferenceSolution": { - "key": { - "type": "hangoutsMeet" - }, - "name": "Google Meet", - "iconUri": "https://fonts.gstatic.com/s/i/productlogos/meet_2020q4/v6/web-512dp/logo_meet_2020q4_color_2x_web_512dp.png" - }, - "conferenceId": "aao-ixkr-uwu" - }, - "reminders": { - "useDefault": true - }, - "eventType": "default" - }, - "pairedItem": { - "item": 0 - } - } - ], - "Schedule Trigger1": [ - { - "json": { - "timestamp": "2026-07-01T18:00:24.010-04:00", - "Readable date": "July 1st 2026, 6:00:24 pm", - "Readable time": "6:00:24 pm", - "Day of week": "Wednesday", - "Year": "2026", - "Month": "July", - "Day of month": "01", - "Hour": "18", - "Minute": "00", - "Second": "24", - "Timezone": "America/Santo_Domingo (UTC-04:00)" - }, - "pairedItem": { - "item": 0 - } - } - ], - "Webhook": [ - { - "json": { - "headers": { - "host": "agenteit.digitalcompass.agency", - "user-agent": "BambooHR-WebHooks/1.0 (+https://www.bamboohr.com)", - "content-length": "120", - "accept": "*/*", - "content-type": "application/json", - "traceparent": "00-6a466325000000008538f08cea35b99d-cc5e1f3f68342673-01", - "tracestate": "dd=t.dm:-0", - "x-bamboohr-signature": "84400ec7bf11cb911e8f74b304fe65e9637d84e74f52ba9a3475705a736d971a", - "x-bamboohr-timestamp": "1782997797", - "x-datadog-parent-id": "14726242188739749491", - "x-datadog-sampling-priority": "1", - "x-datadog-tags": "_dd.p.tid=6a46632500000000,_dd.p.dm=-0", - "x-datadog-trace-id": "9599687093755689373", - "x-forwarded-for": "3.133.139.186", - "x-forwarded-host": "agenteit.digitalcompass.agency", - "x-forwarded-port": "443", - "x-forwarded-proto": "https", - "x-forwarded-server": "07b4f09d2c65", - "x-real-ip": "3.133.139.186", - "accept-encoding": "gzip" - }, - "params": {}, - "query": {}, - "body": { - "employees": [ - { - "changedFields": [], - "fields": {}, - "id": "50821", - "action": "Created", - "timestamp": "2026-07-02T07:09:53-06:00" - } - ] - }, - "webhookUrl": "https://agenteit.digitalcompass.agency/webhook/glmway", - "executionMode": "production" - }, - "pairedItem": { - "item": 0 - } - } ] }, - "versionId": "fd8d6eab-dabd-462e-a535-455b8571a191", - "activeVersionId": "fd8d6eab-dabd-462e-a535-455b8571a191", - "versionCounter": 4008, + "versionId": "035c48ce-6ce9-4bca-a5ef-cf6e51360ce3", + "activeVersionId": "035c48ce-6ce9-4bca-a5ef-cf6e51360ce3", + "versionCounter": 4224, "triggerCount": 13, "shared": [ { @@ -6592,9 +6276,9 @@ ], "tags": [], "activeVersion": { - "updatedAt": "2026-07-02T17:59:04.000Z", - "createdAt": "2026-07-02T17:58:46.100Z", - "versionId": "fd8d6eab-dabd-462e-a535-455b8571a191", + "updatedAt": "2026-07-03T15:28:30.000Z", + "createdAt": "2026-07-03T15:27:54.655Z", + "versionId": "035c48ce-6ce9-4bca-a5ef-cf6e51360ce3", "workflowId": "F1iPg8hktNAebZua", "nodes": [ { @@ -7380,7 +7064,7 @@ "type": "n8n-nodes-base.if", "typeVersion": 2.3, "position": [ - 912, + 2624, -240 ], "id": "8a2be7cc-85ad-4e44-92a7-fe3f94df703f", @@ -7576,8 +7260,8 @@ }, "type": "n8n-nodes-base.stickyNote", "position": [ - 1264, - -16 + 2768, + -464 ], "typeVersion": 1, "id": "719365c8-8099-4108-a910-83b651d81181", @@ -7622,7 +7306,7 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ - 1152, + 2816, -144 ], "id": "09ce1f03-3dfb-4108-9d25-6c05ac622a6f", @@ -7697,10 +7381,10 @@ }, { "parameters": { - "sendTo": "={{ $('Get an employee').item.json.workEmail }}", + "sendTo": "=eidan.then14@gmail.com", "subject": "Entrenamiento #TheGLMWay", "emailType": "text", - "message": "=Hola, GLMer!\n\nEste {{ $json.hora_convertida }} a las {{ $('Obtener sesiones español').item.json.hora_inicio }} tenemos entrenamiento, y queremos transmitirte nuestra cultura, nuestro ADN y por qué somos diferentes al resto.\n\nTe esperamos puntual y con todas las ganas de aprender.\n\nNos vemos en el enlace!\n\n{{ $('Obtener sesiones español').item.json.enlace_reunion }}", + "message": "=Hola, GLMer!\n\nEste {{ $('Convertir fecha a espanol').item.json.fechaFormateada }} a las {{ $json.hora_convertida }} tenemos entrenamiento, y queremos transmitirte nuestra cultura, nuestro ADN y por qué somos diferentes al resto.\n\nTe esperamos puntual y con todas las ganas de aprender.\n\nNos vemos en el enlace!\n\n{{ $('Obtener sesiones español').item.json.enlace_reunion }}", "options": { "appendAttribution": false } @@ -7708,8 +7392,8 @@ "type": "n8n-nodes-base.gmail", "typeVersion": 2.2, "position": [ - 2672, - -400 + 2080, + -336 ], "id": "e6c3acf5-d54b-4e00-b7a9-74038d27e387", "name": "Send a message espanol", @@ -7723,10 +7407,10 @@ }, { "parameters": { - "sendTo": "={{ $('Get an employee').item.json.workEmail }}", + "sendTo": "=eidan.then14@gmail.com", "subject": "#TheGLMWay Training", "emailType": "text", - "message": "=Hello, GLMer!\n\nThis {{ $json.hora_convertida }} at {{ $('Obtener sesiones ingles').item.json.hora_inicio }} we have training, and we want to share our culture, our DNA, and what makes us different from the rest.\n\nWe expect you to be punctual and eager to learn.\n\nSee you at the link!\n\n{{ $('Obtener sesiones ingles').item.json.enlace_reunion }}", + "message": "=Hello, GLMer!\n\nThis {{ $('Convertir fecha a ingles').item.json.fechaFormateada }} at {{ $json.hora_convertida }} we have training, and we want to share our culture, our DNA, and what makes us different from the rest.\n\nWe expect you to be punctual and eager to learn.\n\nSee you at the link!\n\n{{ $('Obtener sesiones ingles').item.json.enlace_reunion }}", "options": { "appendAttribution": false } @@ -7734,8 +7418,8 @@ "type": "n8n-nodes-base.gmail", "typeVersion": 2.2, "position": [ - 2672, - -224 + 2080, + -160 ], "id": "f173c8d1-9311-405c-a7ee-164726df32f1", "name": "Send a message ingles", @@ -7799,7 +7483,7 @@ "parameters": { "content": "## Notificacion inicial\n\nEnvia notificacion de sesion en el primer dia de trabajo del empleado", "height": 608, - "width": 3216, + "width": 3360, "color": 6 }, "type": "n8n-nodes-base.stickyNote", @@ -7878,7 +7562,7 @@ "parameters": { "content": "## Completar datos y enviar invitacion", "height": 544, - "width": 3696, + "width": 3920, "color": 6 }, "type": "n8n-nodes-base.stickyNote", @@ -7949,11 +7633,11 @@ "conditions": [ { "id": "9674fd7e-dd62-42d4-8931-6c67e59e3dd7", - "leftValue": "={{ !['Jamaica', 'Trinidad and Tobago', 'Barbados', 'Saint Thomas', 'St. Croix', 'Tobago', 'Guyana', 'Aruba'].includes($('Get an employee1').item.json.location) }}", + "leftValue": "={{ [\"Jamaica\", \"Trinidad and Tobago\", \"Barbados\", \"Saint Thomas\", \"St. Croix\", \"Tobago\", \"Guyana\", \"Aruba\"].includes($('Get an employee1').item.json.location) }}", "rightValue": "Jamaica", "operator": { "type": "boolean", - "operation": "true", + "operation": "false", "singleValue": true } } @@ -8058,7 +7742,7 @@ "type": "n8n-nodes-base.if", "typeVersion": 2.3, "position": [ - 3008, + 3056, 352 ], "id": "30b3a4dd-6d50-405d-9c77-27febcc50aa4", @@ -8103,7 +7787,7 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ - 3184, + 3232, 432 ], "id": "67928478-7604-45a4-9ab0-851079e1470c", @@ -8111,10 +7795,10 @@ }, { "parameters": { - "sendTo": "={{ $('Get an employee1').item.json.workEmail }}", + "sendTo": "=eidan.then14@gmail.com", "subject": "Entrenamiento #TheGLMWay", "emailType": "text", - "message": "=Hola, GLMer!\n\nEste {{ $json.hora_convertida }} a las {{ $('Obtener sesiones español1').item.json.hora_inicio }} tenemos entrenamiento, y queremos transmitirte nuestra cultura, nuestro ADN y por qué somos diferentes al resto.\n\nTe esperamos puntual y con todas las ganas de aprender.\n\nNos vemos en el enlace!\n\n{{ $('Obtener sesiones español1').item.json.enlace_reunion }}", + "message": "=Hola, GLMer!\n\nEste {{ $('Convertir fecha a espanol1').item.json.fechaFormateada }} a las {{ $json.hora_convertida }} tenemos entrenamiento, y queremos transmitirte nuestra cultura, nuestro ADN y por qué somos diferentes al resto.\n\nTe esperamos puntual y con todas las ganas de aprender.\n\nNos vemos en el enlace!\n\n{{ $('Obtener sesiones español1').item.json.enlace_reunion }}", "options": { "appendAttribution": false } @@ -8122,7 +7806,7 @@ "type": "n8n-nodes-base.gmail", "typeVersion": 2.2, "position": [ - 2656, + 2480, 272 ], "id": "32302b24-aa4c-4f9a-afc8-ef7e86cad56b", @@ -8137,10 +7821,10 @@ }, { "parameters": { - "sendTo": "={{ $('Get an employee1').item.json.workEmail }}", + "sendTo": "=eidan.then14@gmail.com", "subject": "#TheGLMWay Training", "emailType": "text", - "message": "=Hello, GLMer!\n\nThis {{ $json.hora_convertida }} at {{ $('Obtener sesiones ingles1').item.json.hora_inicio }} we have training, and we want to share our culture, our DNA, and what makes us different from the rest.\n\nWe expect you to be punctual and eager to learn.\n\nSee you at the link!\n\n{{ $('Obtener sesiones ingles1').item.json.enlace_reunion }}", + "message": "=Hello, GLMer!\n\nThis {{ $('Convertir fecha a ingles1').item.json.fechaFormateada }} at {{ $json.hora_convertida }} we have training, and we want to share our culture, our DNA, and what makes us different from the rest.\n\nWe expect you to be punctual and eager to learn.\n\nSee you at the link!\n\n{{ $('Obtener sesiones ingles1').item.json.enlace_reunion }}", "options": { "appendAttribution": false } @@ -8148,7 +7832,7 @@ "type": "n8n-nodes-base.gmail", "typeVersion": 2.2, "position": [ - 2656, + 2480, 448 ], "id": "db2cb6a3-1da8-472a-95eb-1a02de2a5fa4", @@ -8173,74 +7857,12 @@ "conditions": [ { "id": "9674fd7e-dd62-42d4-8931-6c67e59e3dd7", - "leftValue": "={{ $('Get an employee').item.json.location }}", + "leftValue": "={{ [\"Jamaica\", \"Trinidad and Tobago\", \"Barbados\", \"Saint Thomas\", \"St. Croix\", \"Tobago\", \"Guyana\", \"Aruba\"].includes($('Get an employee').item.json.location) }}", "rightValue": "Jamaica", "operator": { - "type": "string", - "operation": "equals" - } - }, - { - "id": "32931394-f4ea-4055-b866-906a81988173", - "leftValue": "={{ $('Get an employee').item.json.location }}", - "rightValue": "Trinidad and Tobago", - "operator": { - "type": "string", - "operation": "equals" - } - }, - { - "id": "ea2a8466-96c6-460f-b08f-d23c06b2d18c", - "leftValue": "={{ $('Get an employee').item.json.location }}", - "rightValue": "Barbados", - "operator": { - "type": "string", - "operation": "equals" - } - }, - { - "id": "28e49217-0c1a-4462-9642-676e54926d3e", - "leftValue": "={{ $('Get an employee').item.json.location }}", - "rightValue": "Saint Thomas", - "operator": { - "type": "string", - "operation": "equals" - } - }, - { - "id": "c6a6aea5-48f4-44dc-92ca-a9f9de9cacf9", - "leftValue": "={{ $('Get an employee').item.json.location }}", - "rightValue": "St. Croix", - "operator": { - "type": "string", - "operation": "equals" - } - }, - { - "id": "e6f52339-ea7c-462f-bdc2-8b7353160e4c", - "leftValue": "={{ $('Get an employee').item.json.location }}", - "rightValue": "Tobago", - "operator": { - "type": "string", - "operation": "equals" - } - }, - { - "id": "b308c2b6-53b4-4d49-b540-cdc03e36528b", - "leftValue": "={{ $('Get an employee').item.json.location }}", - "rightValue": "Guyana", - "operator": { - "type": "string", - "operation": "equals" - } - }, - { - "id": "35a50a33-a2b5-4116-9336-11300357569e", - "leftValue": "={{ $('Get an employee').item.json.location }}", - "rightValue": "Aruba", - "operator": { - "type": "string", - "operation": "equals" + "type": "boolean", + "operation": "false", + "singleValue": true } } ], @@ -8251,8 +7873,8 @@ "type": "n8n-nodes-base.if", "typeVersion": 2.2, "position": [ - 1152, - -320 + 752, + -256 ], "id": "b183c892-8822-4bc3-a92c-4410eac41a01", "name": "Pais?" @@ -8313,7 +7935,7 @@ "type": "n8n-nodes-base.wait", "typeVersion": 1.1, "position": [ - 3360, + 3408, 352 ], "id": "98185de1-e81a-440f-8951-f98bd78c707b", @@ -8338,7 +7960,7 @@ }, { "parameters": { - "sendTo": "={{ $('Loop Over Items1').item.json.email }}", + "sendTo": "=eidan.then14@gmail.com", "subject": "Entrenamiento #TheGLMWay", "emailType": "text", "message": "=¡Hola, GLMer!\n\nEste es un recordatorio de tu entrenamiento, donde te transmitiremos nuestra cultura, nuestro ADN y por qué somos diferentes al resto.\n\n¡Te esperamos puntual y con toda la energía para aprender!\n\nÚnete aquí:\n\n{{ $('Obtener sesion').item.json.enlace_reunion }}", @@ -8364,7 +7986,7 @@ }, { "parameters": { - "sendTo": "={{ $('Loop Over Items1').item.json.email }}", + "sendTo": "=eidan.then14@gmail.com", "subject": "#TheGLMWay Training", "emailType": "text", "message": "=Hello, GLMer!\n\nThis is a reminder about your training session, where we'll share our culture, our DNA, and what makes us different from the rest.\n\nWe're looking forward to seeing you on time and ready to learn!\n\nJoin here:\n\n{{ $('Obtener sesion').item.json.enlace_reunion }}", @@ -8468,7 +8090,7 @@ "type": "n8n-nodes-base.googleSheets", "typeVersion": 4.7, "position": [ - 752, + 2464, -240 ], "id": "d565bfde-93eb-4b39-afc8-4b294c7e9df7", @@ -8510,7 +8132,7 @@ "type": "n8n-nodes-base.googleSheets", "typeVersion": 4.7, "position": [ - 2848, + 2896, 352 ], "id": "3a6f198b-e136-49fb-a171-78164e10b600", @@ -8691,8 +8313,8 @@ "type": "n8n-nodes-base.set", "typeVersion": 3.4, "position": [ - 1376, - -400 + 976, + -336 ], "id": "e8a65f36-8e8e-4135-b7a2-a7ef4617de2f", "name": "Crear variable idioma ES" @@ -8714,8 +8336,8 @@ "type": "n8n-nodes-base.set", "typeVersion": 3.4, "position": [ - 1376, - -224 + 976, + -160 ], "id": "971ae719-5692-4f87-9a57-2287ee44783d", "name": "Crear variable idioma EN" @@ -8736,8 +8358,8 @@ "type": "n8n-nodes-base.supabase", "typeVersion": 1, "position": [ - 1568, - -400 + 1168, + -336 ], "id": "cb9e8a10-a1e7-40c7-8447-2379b0191a8f", "name": "Obtener sesiones español", @@ -8764,8 +8386,8 @@ "type": "n8n-nodes-base.supabase", "typeVersion": 1, "position": [ - 1568, - -224 + 1168, + -160 ], "id": "5ca790ee-4944-4868-98af-89837ac39422", "name": "Obtener sesiones ingles", @@ -8783,8 +8405,8 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 1760, - -400 + 1360, + -336 ], "id": "c2db5e62-7741-4ff2-ad31-71c108dd7386", "name": "Calcular sesion mas cercana" @@ -8796,8 +8418,8 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 1760, - -224 + 1360, + -160 ], "id": "bde8fba9-0d6c-4299-8971-dcd8e0e740b4", "name": "Calcular sesion mas cercana1" @@ -8914,6 +8536,18 @@ { "fieldId": "sesion_id", "fieldValue": "={{ $json.session.id }}" + }, + { + "fieldId": "division", + "fieldValue": "={{ $('Get an employee').item.json.division }}" + }, + { + "fieldId": "puesto", + "fieldValue": "={{ $('Get an employee').item.json.jobTitle }}" + }, + { + "fieldId": "pais", + "fieldValue": "={{ $('Get an employee').item.json.location }}" } ] } @@ -8921,8 +8555,8 @@ "type": "n8n-nodes-base.supabase", "typeVersion": 1, "position": [ - 1920, - -400 + 1520, + -336 ], "id": "dcdef9fc-9c61-45dd-9604-56037eac4c31", "name": "Guardar datos del empleado y sesion asignada", @@ -8973,6 +8607,18 @@ { "fieldId": "sesion_id", "fieldValue": "={{ $json.session.id }}" + }, + { + "fieldId": "division", + "fieldValue": "={{ $('Get an employee').item.json.division }}" + }, + { + "fieldId": "puesto", + "fieldValue": "={{ $('Get an employee').item.json.jobTitle }}" + }, + { + "fieldId": "pais", + "fieldValue": "={{ $('Get an employee').item.json.location }}" } ] } @@ -8980,8 +8626,8 @@ "type": "n8n-nodes-base.supabase", "typeVersion": 1, "position": [ - 1920, - -224 + 1520, + -160 ], "id": "7530270a-b32e-419e-8fc5-b29fa07dda39", "name": "Guardar datos del empleado y sesion asignada1", @@ -9062,131 +8708,6 @@ "name": "Wait2", "webhookId": "1211d7da-55b9-4a73-837d-55934076a799" }, - { - "parameters": { - "conditions": { - "options": { - "caseSensitive": true, - "leftValue": "", - "typeValidation": "strict", - "version": 3 - }, - "conditions": [ - { - "id": "d7d68505-8c34-44cd-b771-56bef28ada41", - "leftValue": "={{ $('Get an employee1').item.json.workEmail }}", - "rightValue": "", - "operator": { - "type": "string", - "operation": "notEmpty", - "singleValue": true - } - }, - { - "id": "a245c081-ef08-4ba2-8164-2d2c35bd1e17", - "leftValue": "={{ $('Get an employee1').item.json.location }}", - "rightValue": "", - "operator": { - "type": "string", - "operation": "notEmpty", - "singleValue": true - } - } - ], - "combinator": "and" - }, - "options": {} - }, - "type": "n8n-nodes-base.if", - "typeVersion": 2.3, - "position": [ - 752, - 352 - ], - "id": "a2a81e91-f617-490a-b1ce-5737944fa23b", - "name": "Tiene correo?" - }, - { - "parameters": { - "operation": "update", - "tableId": "inscritos_glmway", - "filters": { - "conditions": [ - { - "keyName": "empleado_id", - "condition": "eq", - "keyValue": "={{ $('Get an employee1').item.json.id }}" - } - ] - }, - "fieldsUi": { - "fieldValues": [ - { - "fieldId": "empleado_id", - "fieldValue": "={{ $('Informacion extra del empleado1').item.json.id }}" - }, - { - "fieldId": "nombre", - "fieldValue": "={{ $('Get an employee1').item.json.displayName }}" - }, - { - "fieldId": "email", - "fieldValue": "={{ $('Get an employee1').item.json.workEmail }}" - }, - { - "fieldId": "departamento", - "fieldValue": "={{ $('Get an employee1').item.json.department }}" - }, - { - "fieldId": "supervisor_id", - "fieldValue": "={{ $('Informacion extra del empleado1').item.json.supervisorEId }}" - }, - { - "fieldId": "fecha_ingreso", - "fieldValue": "={{ $('Informacion extra del empleado1').item.json.hireDate }}" - }, - { - "fieldId": "fecha_sesion_inscrito", - "fieldValue": "={{ $json.session.fecha_sesion }}" - }, - { - "fieldId": "estado", - "fieldValue": "notificado" - }, - { - "fieldId": "sesion_id", - "fieldValue": "={{ $json.session.id }}" - }, - { - "fieldId": "pais", - "fieldValue": "={{ $('Get an employee1').item.json.location }}" - }, - { - "fieldId": "division", - "fieldValue": "={{ $('Get an employee1').item.json.division }}" - }, - { - "fieldId": "puesto", - "fieldValue": "={{ $('Get an employee1').item.json.jobTitle }}" - } - ] - } - }, - "type": "n8n-nodes-base.supabase", - "typeVersion": 1, - "position": [ - 1904, - 272 - ], - "id": "16d364da-e6fc-4943-bd64-f83ccab66b9f", - "name": "Actualizar datos del empleado y sesion asignada2", - "credentials": { - "supabaseApi": { - "id": "2PlsR6rpK7rQTIEn", - "name": "Sofia test - Supabase account" - } - } - }, { "parameters": { "operation": "get", @@ -9529,131 +9050,6 @@ "id": "bbd0558c-3b3a-462b-957c-83b1975e5413", "name": "Calcular falta 24h o es el mismo dia" }, - { - "parameters": { - "operation": "update", - "tableId": "inscritos_glmway", - "filters": { - "conditions": [ - { - "keyName": "empleado_id", - "condition": "eq", - "keyValue": "={{ $('Get an employee1').item.json.id }}" - } - ] - }, - "fieldsUi": { - "fieldValues": [ - { - "fieldId": "empleado_id", - "fieldValue": "={{ $('Informacion extra del empleado1').item.json.id }}" - }, - { - "fieldId": "nombre", - "fieldValue": "={{ $('Get an employee1').item.json.displayName }}" - }, - { - "fieldId": "email", - "fieldValue": "={{ $('Get an employee1').item.json.workEmail }}" - }, - { - "fieldId": "departamento", - "fieldValue": "={{ $('Get an employee1').item.json.department }}" - }, - { - "fieldId": "supervisor_id", - "fieldValue": "={{ $('Informacion extra del empleado1').item.json.supervisorEId }}" - }, - { - "fieldId": "fecha_ingreso", - "fieldValue": "={{ $('Informacion extra del empleado1').item.json.hireDate }}" - }, - { - "fieldId": "fecha_sesion_inscrito", - "fieldValue": "={{ $json.session.fecha_sesion }}" - }, - { - "fieldId": "estado", - "fieldValue": "notificado" - }, - { - "fieldId": "sesion_id", - "fieldValue": "={{ $json.session.id }}" - }, - { - "fieldId": "pais", - "fieldValue": "={{ $('Get an employee1').item.json.location }}" - }, - { - "fieldId": "division", - "fieldValue": "={{ $('Get an employee1').item.json.division }}" - }, - { - "fieldId": "puesto", - "fieldValue": "={{ $('Get an employee1').item.json.jobTitle }}" - } - ] - } - }, - "type": "n8n-nodes-base.supabase", - "typeVersion": 1, - "position": [ - 1904, - 448 - ], - "id": "f2aca2bd-e72d-4457-9a6b-c4b0f8bcc558", - "name": "Actualizar datos del empleado y sesion asignada3", - "credentials": { - "supabaseApi": { - "id": "2PlsR6rpK7rQTIEn", - "name": "Sofia test - Supabase account" - } - } - }, - { - "parameters": { - "conditions": { - "options": { - "caseSensitive": true, - "leftValue": "", - "typeValidation": "strict", - "version": 3 - }, - "conditions": [ - { - "id": "d7d68505-8c34-44cd-b771-56bef28ada41", - "leftValue": "={{ $('Get an employee').item.json.workEmail }}", - "rightValue": "", - "operator": { - "type": "string", - "operation": "notEmpty", - "singleValue": true - } - }, - { - "id": "ec0276ab-208e-409b-8101-d06e535f541c", - "leftValue": "={{ $('Get an employee').item.json.location }}", - "rightValue": "", - "operator": { - "type": "string", - "operation": "notEmpty", - "singleValue": true - } - } - ], - "combinator": "and" - }, - "options": {} - }, - "type": "n8n-nodes-base.if", - "typeVersion": 2.3, - "position": [ - 336, - -144 - ], - "id": "a9fff247-d1b0-4314-ba8d-e7401086b771", - "name": "Tiene correo?1" - }, { "parameters": { "documentId": { @@ -9753,7 +9149,7 @@ "type": "n8n-nodes-base.scheduleTrigger", "typeVersion": 1.3, "position": [ - 2976, + 3056, -352 ], "id": "ca136518-b776-45ba-b1a2-ad5327dd4cca", @@ -9804,7 +9200,7 @@ "type": "n8n-nodes-base.googleSheets", "typeVersion": 4.7, "position": [ - 3872, + 3952, -352 ], "id": "7c321f7d-bce9-447c-b94c-35f6967a48e3", @@ -9822,7 +9218,7 @@ "type": "n8n-nodes-base.wait", "typeVersion": 1.1, "position": [ - 3696, + 3776, -352 ], "id": "27531838-5dc7-4169-a08a-f4da93899580", @@ -9852,7 +9248,7 @@ "type": "n8n-nodes-base.googleSheets", "typeVersion": 4.7, "position": [ - 3520, + 3600, -352 ], "id": "bd8cb535-6aa3-46df-9ca0-6efc0555f2e4", @@ -9873,7 +9269,7 @@ }, "type": "n8n-nodes-base.stickyNote", "position": [ - 2944, + 3024, -480 ], "typeVersion": 1, @@ -10026,8 +9422,8 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.1, "position": [ - 336, - 3568 + 448, + 3584 ], "credentials": { "googleOAuth2Api": { @@ -10044,8 +9440,8 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 64, - 3264 + 112, + 3488 ], "id": "602289b9-3c7d-4ced-b507-b27401ed9910", "name": "HTTP Request1" @@ -10062,7 +9458,7 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.1, "position": [ - 160, + 320, 2976 ], "credentials": { @@ -10084,8 +9480,8 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.1, "position": [ - 320, - 3296 + 304, + 3472 ], "credentials": { "googleOAuth2Api": { @@ -10171,7 +9567,7 @@ "type": "n8n-nodes-base.googleCalendar", "typeVersion": 1.3, "position": [ - 3168, + 3248, -352 ], "id": "b2b03ce6-6010-4e4f-be7a-d9040286e295", @@ -10190,7 +9586,7 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 3344, + 3424, -352 ], "id": "73c39af9-bc01-4d97-81ee-846aff70b3a6", @@ -10209,7 +9605,7 @@ "type": "n8n-nodes-base.scheduleTrigger", "typeVersion": 1.3, "position": [ - 2976, + 3056, -48 ], "id": "55a755d8-8b74-440f-93c6-8a1ecba4c666", @@ -10223,7 +9619,7 @@ }, "type": "n8n-nodes-base.stickyNote", "position": [ - 2944, + 3024, -160 ], "typeVersion": 1, @@ -10250,7 +9646,7 @@ "type": "n8n-nodes-base.googleCalendar", "typeVersion": 1.3, "position": [ - 4320, + 4400, -208 ], "id": "3c32f96e-cd34-4be4-8c24-b4be7a8f29d9", @@ -10283,7 +9679,7 @@ "type": "n8n-nodes-base.googleSheets", "typeVersion": 4.7, "position": [ - 3152, + 3232, -48 ], "id": "73089147-ba1f-4fb4-ac17-d5670b263fd8", @@ -10321,7 +9717,7 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 3488, + 3568, -48 ], "id": "231f396b-855a-4c50-8d6d-096018e6d2ac", @@ -10336,7 +9732,7 @@ "type": "n8n-nodes-base.aggregate", "typeVersion": 1, "position": [ - 3312, + 3392, -48 ], "id": "e51bd2d5-22b5-46cf-b346-c1ba16bb5c34", @@ -10367,7 +9763,7 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 5120, + 5200, -304 ], "id": "3f4a0807-5f29-49cb-a851-41100e04f5bf", @@ -10382,7 +9778,7 @@ "type": "n8n-nodes-base.aggregate", "typeVersion": 1, "position": [ - 4976, + 5056, -304 ], "id": "3ecbb0c7-f5f5-4644-9f42-8be9502e814d", @@ -10397,7 +9793,7 @@ "type": "n8n-nodes-base.set", "typeVersion": 3.4, "position": [ - 4832, + 4912, -304 ], "id": "a099259d-36e3-48b6-aa77-d8132f33f85e", @@ -10420,7 +9816,7 @@ "type": "n8n-nodes-base.merge", "typeVersion": 3.2, "position": [ - 4688, + 4768, -304 ], "id": "456bcbe4-cc98-48fc-bcd2-40f8961934ae", @@ -10434,7 +9830,7 @@ }, "type": "n8n-nodes-base.stickyNote", "position": [ - 4112, + 4192, -480 ], "typeVersion": 1, @@ -10458,7 +9854,7 @@ "type": "n8n-nodes-base.scheduleTrigger", "typeVersion": 1.3, "position": [ - 4160, + 4240, -288 ], "id": "6ef829bf-1d52-4093-bcc5-45d922393611", @@ -10485,7 +9881,7 @@ "type": "n8n-nodes-base.googleSheets", "typeVersion": 4.7, "position": [ - 4320, + 4400, -384 ], "id": "f1bf8c51-43cf-41d4-93c4-1a1d0a0dac7a", @@ -10505,7 +9901,7 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 4496, + 4576, -208 ], "id": "8f80d9ca-1e4b-4753-b482-df7b0fd24f61", @@ -10967,14 +10363,14 @@ }, "sendBody": true, "specifyBody": "json", - "jsonBody": "={\n \"p_sesion_id\": \"{{ $('Calcular sesion mas cercana').item.json.session.id }}\",\n \"p_pais\": \"{{ $json.pais }}\",\n \"p_empleados\": [\n {\n \"nombre\": \"{{ $json.nombre }}\",\n \"correo\": \"{{ $json.email }}\",\n \"departamento\": \"{{ $json.departamento }}\",\n \"division\": \"{{ $json.division }}\"\n }\n ]\n}", + "jsonBody": "={\n \"p_sesion_id\": \"{{ $('Calcular sesion mas cercana').item.json.session.id }}\",\n \"p_pais\": \"{{ $('Get an employee').item.json.location }}\",\n \"p_empleados\": [\n {\n \"nombre\": \"{{ $('Get an employee').item.json.displayName }}\",\n \"correo\": \"{{ $('Get an employee').item.json.workEmail }}\",\n \"departamento\": \"{{ $('Get an employee').item.json.department }}\",\n \"division\": \"{{ $('Get an employee').item.json.division }}\"\n }\n ]\n}", "options": {} }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 2096, - -400 + 2272, + -336 ], "id": "4ab5f973-c2e1-410e-9212-8ed3b9d372e3", "name": "Registrar empleado a la sesion" @@ -10998,14 +10394,14 @@ }, "sendBody": true, "specifyBody": "json", - "jsonBody": "={\n \"p_sesion_id\": \"{{ $('Calcular sesion mas cercana1').item.json.session.id }}\",\n \"p_pais\": \"{{ $json.pais }}\",\n \"p_empleados\": [\n {\n \"nombre\": \"{{ $json.nombre }}\",\n \"correo\": \"{{ $json.email }}\",\n \"departamento\": \"{{ $json.departamento }}\",\n \"division\": \"{{ $json.division }}\"\n }\n ]\n}", + "jsonBody": "={\n \"p_sesion_id\": \"{{ $('Calcular sesion mas cercana1').item.json.session.id }}\",\n \"p_pais\": \"{{ $('Get an employee').item.json.location }}\",\n \"p_empleados\": [\n {\n \"nombre\": \"{{ $('Get an employee').item.json.displayName }}\",\n \"correo\": \"{{ $('Get an employee').item.json.workEmail }}\",\n \"departamento\": \"{{ $('Get an employee').item.json.department }}\",\n \"division\": \"{{ $('Get an employee').item.json.division }}\"\n }\n ]\n}", "options": {} }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 2096, - -224 + 2272, + -160 ], "id": "5e69165f-16a2-4f7a-ad48-d24c70f3c88b", "name": "Registrar empleado a la sesion1" @@ -11035,7 +10431,7 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 2080, + 2688, 272 ], "id": "f3df197d-b557-45d7-94bb-76f3c300ae61", @@ -11066,7 +10462,7 @@ "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ - 2080, + 2688, 448 ], "id": "23ac8709-b0ac-4bb6-911a-1e7641be075d", @@ -11074,38 +10470,38 @@ }, { "parameters": { - "jsCode": "// Diccionario de meses inglés -> español\nconst meses = {\n january: 'Enero',\n february: 'Febrero',\n march: 'Marzo',\n april: 'Abril',\n may: 'Mayo',\n june: 'Junio',\n july: 'Julio',\n august: 'Agosto',\n september: 'Septiembre',\n october: 'Octubre',\n november: 'Noviembre',\n december: 'Diciembre'\n};\n\nfor (const item of $input.all()) {\n const fecha = $('Calcular sesion mas cercana').first().json.session.fecha_sesion; // Cambia \"fecha\" por el nombre real de tu campo\n const partes = fecha.trim().split(' '); // [\"8\", \"July\"]\n\n const dia = partes[0];\n const mesIngles = partes[1].toLowerCase();\n const mesEspanol = meses[mesIngles] || partes[1];\n\n item.json.fechaFormateada = `${mesEspanol} ${dia}`;\n}\n\nreturn $input.all();" + "jsCode": "// Diccionario de meses inglés -> español\nconst meses = {\n january: 'Enero',\n february: 'Febrero',\n march: 'Marzo',\n april: 'Abril',\n may: 'Mayo',\n june: 'Junio',\n july: 'Julio',\n august: 'Agosto',\n september: 'Septiembre',\n october: 'Octubre',\n november: 'Noviembre',\n december: 'Diciembre'\n};\n\nconst fecha = $('Calcular sesion mas cercana').first().json.session.fecha_sesion;\n\nconst partes = fecha.trim().split(' ');\nconst dia = partes[0];\nconst mesIngles = partes[1].toLowerCase();\nconst mesEspanol = meses[mesIngles] || partes[1];\n\nconst fechaFormateada = `${mesEspanol} ${dia}`;\n\nreturn [\n {\n json: {\n fechaFormateada\n }\n }\n];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 2288, - -400 + 1696, + -336 ], "id": "ad0bb609-e224-4956-bf20-0d624f4ef3ae", "name": "Convertir fecha a espanol" }, { "parameters": { - "jsCode": "function getOrdinalSuffix(dia) {\n const d = parseInt(dia, 10);\n if (d > 3 && d < 21) return `${d}th`; // 11th-13th excepción cubierta aquí\n switch (d % 10) {\n case 1: return `${d}st`;\n case 2: return `${d}nd`;\n case 3: return `${d}rd`;\n default: return `${d}th`;\n }\n}\n\nfor (const item of $input.all()) {\n const fecha = $('Calcular sesion mas cercana1').first().json.session.fecha_sesion; // Cambia \"fecha\" por el nombre real de tu campo\n const partes = fecha.trim().split(' '); // [\"8\", \"July\"]\n\n const dia = partes[0];\n const mes = partes[1];\n const diaConSufijo = getOrdinalSuffix(dia);\n\n item.json.fechaFormateada = `${mes} ${diaConSufijo}`;\n}\n\nreturn $input.all();" + "jsCode": "function getOrdinalSuffix(dia) {\n const d = parseInt(dia, 10);\n if (d > 3 && d < 21) return `${d}th`; // 11th-13th excepción cubierta aquí\n switch (d % 10) {\n case 1: return `${d}st`;\n case 2: return `${d}nd`;\n case 3: return `${d}rd`;\n default: return `${d}th`;\n }\n}\n\nconst fecha = $('Calcular sesion mas cercana1').first().json.session.fecha_sesion; // Cambia \"fecha\" por el nombre real de tu campo\nconst partes = fecha.trim().split(' '); // [\"8\", \"July\"]\n\nconst dia = partes[0];\nconst mes = partes[1];\nconst diaConSufijo = getOrdinalSuffix(dia);\n\nconst fechaFormateada = `${mes} ${diaConSufijo}`;\n\nreturn [\n {\n json: {\n fechaFormateada\n }\n }\n];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 2288, - -224 + 1696, + -160 ], "id": "a1ad0e55-59e3-405e-b75d-d092112e9151", "name": "Convertir fecha a ingles" }, { "parameters": { - "jsCode": "// Diccionario de meses inglés -> español\nconst meses = {\n january: 'Enero',\n february: 'Febrero',\n march: 'Marzo',\n april: 'Abril',\n may: 'Mayo',\n june: 'Junio',\n july: 'Julio',\n august: 'Agosto',\n september: 'Septiembre',\n october: 'Octubre',\n november: 'Noviembre',\n december: 'Diciembre'\n};\n\nfor (const item of $input.all()) {\n const fecha = $('Calcular sesion mas cercana2').first().json.session.fecha_sesion; // Cambia \"fecha\" por el nombre real de tu campo\n const partes = fecha.trim().split(' '); // [\"8\", \"July\"]\n\n const dia = partes[0];\n const mesIngles = partes[1].toLowerCase();\n const mesEspanol = meses[mesIngles] || partes[1];\n\n item.json.fechaFormateada = `${mesEspanol} ${dia}`;\n}\n\nreturn $input.all();" + "jsCode": "// Diccionario de meses inglés -> español\nconst meses = {\n january: 'Enero',\n february: 'Febrero',\n march: 'Marzo',\n april: 'Abril',\n may: 'Mayo',\n june: 'Junio',\n july: 'Julio',\n august: 'Agosto',\n september: 'Septiembre',\n october: 'Octubre',\n november: 'Noviembre',\n december: 'Diciembre'\n};\n\nconst fecha = $('Calcular sesion mas cercana3').first().json.session.fecha_sesion;\n\nconst partes = fecha.trim().split(' ');\nconst dia = partes[0];\nconst mesIngles = partes[1].toLowerCase();\nconst mesEspanol = meses[mesIngles] || partes[1];\n\nconst fechaFormateada = `${mesEspanol} ${dia}`;\n\nreturn [\n {\n json: {\n fechaFormateada\n }\n }\n];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 2272, + 2096, 272 ], "id": "0d7870a9-0d82-49fe-96de-05c20164cffa", @@ -11118,7 +10514,7 @@ "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 2272, + 2096, 448 ], "id": "4abc2638-3ae3-4aba-b45f-0b60e73e3267", @@ -11214,38 +10610,38 @@ }, { "parameters": { - "jsCode": "const TIMEZONES = {\n \"Argentina\": \"America/Argentina/Buenos_Aires\",\n \"Bolivia\": \"America/La_Paz\",\n \"Brasil\": \"America/Sao_Paulo\",\n \"Chile\": \"America/Santiago\",\n \"Colombia\": \"America/Bogota\",\n \"Costa Rica\": \"America/Costa_Rica\",\n \"Cuba\": \"America/Havana\",\n \"Ecuador\": \"America/Guayaquil\",\n \"El Salvador\": \"America/El_Salvador\",\n \"Guatemala\": \"America/Guatemala\",\n \"Honduras\": \"America/Tegucigalpa\",\n \"Mexico\": \"America/Mexico_City\",\n \"Nicaragua\": \"America/Managua\",\n \"Panama\": \"America/Panama\",\n \"Paraguay\": \"America/Asuncion\",\n \"Peru\": \"America/Lima\",\n \"Puerto Rico\": \"America/Puerto_Rico\",\n \"Republica Dominicana\": \"America/Santo_Domingo\",\n \"Uruguay\": \"America/Montevideo\",\n \"Venezuela\": \"America/Caracas\",\n \"Jamaica\": \"America/Jamaica\",\n \"Trinidad and Tobago\": \"America/Port_of_Spain\",\n \"Guyana\": \"America/Guyana\",\n \"Surinam\": \"America/Paramaribo\",\n \"Belice\": \"America/Belize\"\n};\n\n// ==============================\n// FUNCIONES\n// ==============================\n\nfunction normalizarPais(texto) {\n return texto\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .trim()\n .toLowerCase();\n}\n\nfunction obtenerOffsetMinutos(fecha, timeZone) {\n const dtf = new Intl.DateTimeFormat(\"en-US\", {\n timeZone,\n hour12: false,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\"\n });\n\n const partes = dtf.formatToParts(fecha).reduce((acc, p) => {\n acc[p.type] = p.value;\n return acc;\n }, {});\n\n const utcEquivalente = Date.UTC(\n Number(partes.year),\n Number(partes.month) - 1,\n Number(partes.day),\n Number(partes.hour),\n Number(partes.minute),\n Number(partes.second)\n );\n\n return (utcEquivalente - fecha.getTime()) / 60000;\n}\n\nfunction obtenerUTCDesdeHoraLocal(horaTexto, timeZone) {\n const [hora, minuto] = horaTexto.split(\":\").map(Number);\n\n const ahora = new Date();\n\n const y = ahora.getUTCFullYear();\n const m = ahora.getUTCMonth();\n const d = ahora.getUTCDate();\n\n let fechaUTC = new Date(Date.UTC(y, m, d, hora, minuto, 0));\n\n const offset = obtenerOffsetMinutos(fechaUTC, timeZone);\n\n fechaUTC = new Date(fechaUTC.getTime() - offset * 60000);\n\n return fechaUTC;\n}\n\nfunction formatearHora(fechaUTC, timeZone) {\n return new Intl.DateTimeFormat(\"es-DO\", {\n timeZone,\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: false\n }).format(fechaUTC);\n}\n\nfunction convertirHoraDesdeSantoDomingo(horaTexto) {\n\n const fechaUTC = obtenerUTCDesdeHoraLocal(\n horaTexto,\n TIMEZONES[\"Republica Dominicana\"]\n );\n\n const resultado = {};\n\n for (const [pais, tz] of Object.entries(TIMEZONES)) {\n resultado[pais] = formatearHora(fechaUTC, tz);\n }\n\n return resultado;\n}\n\n// ==============================\n// EJECUCIÓN\n// ==============================\n\nconst horaEntrada = $('Calcular sesion mas cercana')\n .first()\n .json\n .session\n .hora_inicio;\n\nif (!horaEntrada || !/^\\d{1,2}:\\d{2}$/.test(horaEntrada)) {\n throw new Error(\n `Formato de hora inválido: \"${horaEntrada}\". Usa HH:mm, por ejemplo 19:00`\n );\n}\n\nconst conversiones = convertirHoraDesdeSantoDomingo(horaEntrada);\n\nreturn items.map(item => {\n\n const paisEntrada = item.json.pais;\n\n if (!paisEntrada) {\n throw new Error('Cada item debe contener el campo \"pais\".');\n }\n\n // Buscar el país ignorando mayúsculas y acentos\n const paisEncontrado = Object.keys(TIMEZONES).find(\n pais => normalizarPais(pais) === normalizarPais(paisEntrada)\n );\n\n if (!paisEncontrado) {\n throw new Error(\n `País no reconocido: \"${paisEntrada}\". Países válidos: ${Object.keys(TIMEZONES).join(\", \")}`\n );\n }\n\n return {\n json: {\n hora_base: horaEntrada,\n pais_base: \"Republica Dominicana\",\n hora_convertida: conversiones[paisEncontrado],\n conversiones\n }\n };\n});" + "jsCode": "const TIMEZONES = {\n \"Argentina\": \"America/Argentina/Buenos_Aires\",\n \"Bolivia\": \"America/La_Paz\",\n \"Brasil\": \"America/Sao_Paulo\",\n \"Chile\": \"America/Santiago\",\n \"Colombia\": \"America/Bogota\",\n \"Costa Rica\": \"America/Costa_Rica\",\n \"Cuba\": \"America/Havana\",\n \"Ecuador\": \"America/Guayaquil\",\n \"El Salvador\": \"America/El_Salvador\",\n \"Guatemala\": \"America/Guatemala\",\n \"Honduras\": \"America/Tegucigalpa\",\n \"Mexico\": \"America/Mexico_City\",\n \"Nicaragua\": \"America/Managua\",\n \"Panama\": \"America/Panama\",\n \"Paraguay\": \"America/Asuncion\",\n \"Peru\": \"America/Lima\",\n \"Puerto Rico\": \"America/Puerto_Rico\",\n \"Republica Dominicana\": \"America/Santo_Domingo\",\n \"Uruguay\": \"America/Montevideo\",\n \"Venezuela\": \"America/Caracas\",\n \"Jamaica\": \"America/Jamaica\",\n \"Trinidad and Tobago\": \"America/Port_of_Spain\",\n \"Guyana\": \"America/Guyana\",\n \"Surinam\": \"America/Paramaribo\",\n \"Belice\": \"America/Belize\"\n};\n\n// ==============================\n// FUNCIONES\n// ==============================\n\nfunction normalizarPais(texto) {\n return texto\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .trim()\n .toLowerCase();\n}\n\nfunction obtenerOffsetMinutos(fecha, timeZone) {\n const dtf = new Intl.DateTimeFormat(\"en-US\", {\n timeZone,\n hour12: false,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\"\n });\n\n const partes = dtf.formatToParts(fecha).reduce((acc, p) => {\n acc[p.type] = p.value;\n return acc;\n }, {});\n\n const utcEquivalente = Date.UTC(\n Number(partes.year),\n Number(partes.month) - 1,\n Number(partes.day),\n Number(partes.hour),\n Number(partes.minute),\n Number(partes.second)\n );\n\n return (utcEquivalente - fecha.getTime()) / 60000;\n}\n\nfunction obtenerUTCDesdeHoraLocal(horaTexto, timeZone) {\n const [hora, minuto] = horaTexto.split(\":\").map(Number);\n\n const ahora = new Date();\n\n const y = ahora.getUTCFullYear();\n const m = ahora.getUTCMonth();\n const d = ahora.getUTCDate();\n\n let fechaUTC = new Date(Date.UTC(y, m, d, hora, minuto, 0));\n\n const offset = obtenerOffsetMinutos(fechaUTC, timeZone);\n\n fechaUTC = new Date(fechaUTC.getTime() - offset * 60000);\n\n return fechaUTC;\n}\n\nfunction formatearHora(fechaUTC, timeZone) {\n return new Intl.DateTimeFormat(\"es-DO\", {\n timeZone,\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: false\n }).format(fechaUTC);\n}\n\nfunction convertirHoraDesdeSantoDomingo(horaTexto) {\n\n const fechaUTC = obtenerUTCDesdeHoraLocal(\n horaTexto,\n TIMEZONES[\"Republica Dominicana\"]\n );\n\n const resultado = {};\n\n for (const [pais, tz] of Object.entries(TIMEZONES)) {\n resultado[pais] = formatearHora(fechaUTC, tz);\n }\n\n return resultado;\n}\n\n// ==============================\n// EJECUCIÓN\n// ==============================\n\nconst horaEntrada = $('Calcular sesion mas cercana')\n .first()\n .json\n .session\n .hora_inicio;\n\nif (!horaEntrada || !/^\\d{1,2}:\\d{2}$/.test(horaEntrada)) {\n throw new Error(\n `Formato de hora inválido: \"${horaEntrada}\". Usa HH:mm, por ejemplo 19:00`\n );\n}\n\nconst conversiones = convertirHoraDesdeSantoDomingo(horaEntrada);\n\nreturn items.map(item => {\n\n const paisEntrada = $('Guardar datos del empleado y sesion asignada').first().json.pais;\n\n if (!paisEntrada) {\n throw new Error('Cada item debe contener el campo \"pais\".');\n }\n\n // Buscar el país ignorando mayúsculas y acentos\n const paisEncontrado = Object.keys(TIMEZONES).find(\n pais => normalizarPais(pais) === normalizarPais(paisEntrada)\n );\n\n if (!paisEncontrado) {\n throw new Error(\n `País no reconocido: \"${paisEntrada}\". Países válidos: ${Object.keys(TIMEZONES).join(\", \")}`\n );\n }\n\n return {\n json: {\n hora_base: horaEntrada,\n pais_base: \"Republica Dominicana\",\n hora_convertida: conversiones[paisEncontrado],\n conversiones\n }\n };\n});" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 2480, - -400 + 1888, + -336 ], "id": "740373c9-0145-41f4-a4b6-9dbb84ffbdaa", "name": "Cambiar zona horaria" }, { "parameters": { - "jsCode": "const TIMEZONES = {\n \"Argentina\": \"America/Argentina/Buenos_Aires\",\n \"Bolivia\": \"America/La_Paz\",\n \"Brasil\": \"America/Sao_Paulo\",\n \"Chile\": \"America/Santiago\",\n \"Colombia\": \"America/Bogota\",\n \"Costa Rica\": \"America/Costa_Rica\",\n \"Cuba\": \"America/Havana\",\n \"Ecuador\": \"America/Guayaquil\",\n \"El Salvador\": \"America/El_Salvador\",\n \"Guatemala\": \"America/Guatemala\",\n \"Honduras\": \"America/Tegucigalpa\",\n \"Mexico\": \"America/Mexico_City\",\n \"Nicaragua\": \"America/Managua\",\n \"Panama\": \"America/Panama\",\n \"Paraguay\": \"America/Asuncion\",\n \"Peru\": \"America/Lima\",\n \"Puerto Rico\": \"America/Puerto_Rico\",\n \"Republica Dominicana\": \"America/Santo_Domingo\",\n \"Uruguay\": \"America/Montevideo\",\n \"Venezuela\": \"America/Caracas\",\n \"Jamaica\": \"America/Jamaica\",\n \"Trinidad and Tobago\": \"America/Port_of_Spain\",\n \"Guyana\": \"America/Guyana\",\n \"Surinam\": \"America/Paramaribo\",\n \"Belice\": \"America/Belize\"\n};\n\n// ==============================\n// FUNCIONES\n// ==============================\n\nfunction normalizarPais(texto) {\n return texto\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .trim()\n .toLowerCase();\n}\n\nfunction obtenerOffsetMinutos(fecha, timeZone) {\n const dtf = new Intl.DateTimeFormat(\"en-US\", {\n timeZone,\n hour12: false,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\"\n });\n\n const partes = dtf.formatToParts(fecha).reduce((acc, p) => {\n acc[p.type] = p.value;\n return acc;\n }, {});\n\n const utcEquivalente = Date.UTC(\n Number(partes.year),\n Number(partes.month) - 1,\n Number(partes.day),\n Number(partes.hour),\n Number(partes.minute),\n Number(partes.second)\n );\n\n return (utcEquivalente - fecha.getTime()) / 60000;\n}\n\nfunction obtenerUTCDesdeHoraLocal(horaTexto, timeZone) {\n const [hora, minuto] = horaTexto.split(\":\").map(Number);\n\n const ahora = new Date();\n\n const y = ahora.getUTCFullYear();\n const m = ahora.getUTCMonth();\n const d = ahora.getUTCDate();\n\n let fechaUTC = new Date(Date.UTC(y, m, d, hora, minuto, 0));\n\n const offset = obtenerOffsetMinutos(fechaUTC, timeZone);\n\n fechaUTC = new Date(fechaUTC.getTime() - offset * 60000);\n\n return fechaUTC;\n}\n\nfunction formatearHora(fechaUTC, timeZone) {\n return new Intl.DateTimeFormat(\"es-DO\", {\n timeZone,\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: false\n }).format(fechaUTC);\n}\n\nfunction convertirHoraDesdeSantoDomingo(horaTexto) {\n\n const fechaUTC = obtenerUTCDesdeHoraLocal(\n horaTexto,\n TIMEZONES[\"Republica Dominicana\"]\n );\n\n const resultado = {};\n\n for (const [pais, tz] of Object.entries(TIMEZONES)) {\n resultado[pais] = formatearHora(fechaUTC, tz);\n }\n\n return resultado;\n}\n\n// ==============================\n// EJECUCIÓN\n// ==============================\n\nconst horaEntrada = $('Calcular sesion mas cercana1')\n .first()\n .json\n .session\n .hora_inicio;\n\nif (!horaEntrada || !/^\\d{1,2}:\\d{2}$/.test(horaEntrada)) {\n throw new Error(\n `Formato de hora inválido: \"${horaEntrada}\". Usa HH:mm, por ejemplo 19:00`\n );\n}\n\nconst conversiones = convertirHoraDesdeSantoDomingo(horaEntrada);\n\nreturn items.map(item => {\n\n const paisEntrada = item.json.pais;\n\n if (!paisEntrada) {\n throw new Error('Cada item debe contener el campo \"pais\".');\n }\n\n // Buscar el país ignorando mayúsculas y acentos\n const paisEncontrado = Object.keys(TIMEZONES).find(\n pais => normalizarPais(pais) === normalizarPais(paisEntrada)\n );\n\n if (!paisEncontrado) {\n throw new Error(\n `País no reconocido: \"${paisEntrada}\". Países válidos: ${Object.keys(TIMEZONES).join(\", \")}`\n );\n }\n\n return {\n json: {\n hora_base: horaEntrada,\n pais_base: \"Republica Dominicana\",\n hora_convertida: conversiones[paisEncontrado],\n conversiones\n }\n };\n});" + "jsCode": "const TIMEZONES = {\n \"Argentina\": \"America/Argentina/Buenos_Aires\",\n \"Bolivia\": \"America/La_Paz\",\n \"Brasil\": \"America/Sao_Paulo\",\n \"Chile\": \"America/Santiago\",\n \"Colombia\": \"America/Bogota\",\n \"Costa Rica\": \"America/Costa_Rica\",\n \"Cuba\": \"America/Havana\",\n \"Ecuador\": \"America/Guayaquil\",\n \"El Salvador\": \"America/El_Salvador\",\n \"Guatemala\": \"America/Guatemala\",\n \"Honduras\": \"America/Tegucigalpa\",\n \"Mexico\": \"America/Mexico_City\",\n \"Nicaragua\": \"America/Managua\",\n \"Panama\": \"America/Panama\",\n \"Paraguay\": \"America/Asuncion\",\n \"Peru\": \"America/Lima\",\n \"Puerto Rico\": \"America/Puerto_Rico\",\n \"Republica Dominicana\": \"America/Santo_Domingo\",\n \"Uruguay\": \"America/Montevideo\",\n \"Venezuela\": \"America/Caracas\",\n \"Jamaica\": \"America/Jamaica\",\n \"Trinidad and Tobago\": \"America/Port_of_Spain\",\n \"Guyana\": \"America/Guyana\",\n \"Surinam\": \"America/Paramaribo\",\n \"Belice\": \"America/Belize\"\n};\n\n// ==============================\n// FUNCIONES\n// ==============================\n\nfunction normalizarPais(texto) {\n return texto\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .trim()\n .toLowerCase();\n}\n\nfunction obtenerOffsetMinutos(fecha, timeZone) {\n const dtf = new Intl.DateTimeFormat(\"en-US\", {\n timeZone,\n hour12: false,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\"\n });\n\n const partes = dtf.formatToParts(fecha).reduce((acc, p) => {\n acc[p.type] = p.value;\n return acc;\n }, {});\n\n const utcEquivalente = Date.UTC(\n Number(partes.year),\n Number(partes.month) - 1,\n Number(partes.day),\n Number(partes.hour),\n Number(partes.minute),\n Number(partes.second)\n );\n\n return (utcEquivalente - fecha.getTime()) / 60000;\n}\n\nfunction obtenerUTCDesdeHoraLocal(horaTexto, timeZone) {\n const [hora, minuto] = horaTexto.split(\":\").map(Number);\n\n const ahora = new Date();\n\n const y = ahora.getUTCFullYear();\n const m = ahora.getUTCMonth();\n const d = ahora.getUTCDate();\n\n let fechaUTC = new Date(Date.UTC(y, m, d, hora, minuto, 0));\n\n const offset = obtenerOffsetMinutos(fechaUTC, timeZone);\n\n fechaUTC = new Date(fechaUTC.getTime() - offset * 60000);\n\n return fechaUTC;\n}\n\nfunction formatearHora(fechaUTC, timeZone) {\n return new Intl.DateTimeFormat(\"es-DO\", {\n timeZone,\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: false\n }).format(fechaUTC);\n}\n\nfunction convertirHoraDesdeSantoDomingo(horaTexto) {\n\n const fechaUTC = obtenerUTCDesdeHoraLocal(\n horaTexto,\n TIMEZONES[\"Republica Dominicana\"]\n );\n\n const resultado = {};\n\n for (const [pais, tz] of Object.entries(TIMEZONES)) {\n resultado[pais] = formatearHora(fechaUTC, tz);\n }\n\n return resultado;\n}\n\n// ==============================\n// EJECUCIÓN\n// ==============================\n\nconst horaEntrada = $('Calcular sesion mas cercana1')\n .first()\n .json\n .session\n .hora_inicio;\n\nif (!horaEntrada || !/^\\d{1,2}:\\d{2}$/.test(horaEntrada)) {\n throw new Error(\n `Formato de hora inválido: \"${horaEntrada}\". Usa HH:mm, por ejemplo 19:00`\n );\n}\n\nconst conversiones = convertirHoraDesdeSantoDomingo(horaEntrada);\n\nreturn items.map(item => {\n\n const paisEntrada = $('Guardar datos del empleado y sesion asignada1').first().json.pais;\n\n if (!paisEntrada) {\n throw new Error('Cada item debe contener el campo \"pais\".');\n }\n\n // Buscar el país ignorando mayúsculas y acentos\n const paisEncontrado = Object.keys(TIMEZONES).find(\n pais => normalizarPais(pais) === normalizarPais(paisEntrada)\n );\n\n if (!paisEncontrado) {\n throw new Error(\n `País no reconocido: \"${paisEntrada}\". Países válidos: ${Object.keys(TIMEZONES).join(\", \")}`\n );\n }\n\n return {\n json: {\n hora_base: horaEntrada,\n pais_base: \"Republica Dominicana\",\n hora_convertida: conversiones[paisEncontrado],\n conversiones\n }\n };\n});" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 2480, - -224 + 1888, + -160 ], "id": "77da2dc7-546b-4ab7-a7c7-fa621196b2d0", "name": "Cambiar zona horaria1" }, { "parameters": { - "jsCode": "const TIMEZONES = {\n \"Argentina\": \"America/Argentina/Buenos_Aires\",\n \"Bolivia\": \"America/La_Paz\",\n \"Brasil\": \"America/Sao_Paulo\",\n \"Chile\": \"America/Santiago\",\n \"Colombia\": \"America/Bogota\",\n \"Costa Rica\": \"America/Costa_Rica\",\n \"Cuba\": \"America/Havana\",\n \"Ecuador\": \"America/Guayaquil\",\n \"El Salvador\": \"America/El_Salvador\",\n \"Guatemala\": \"America/Guatemala\",\n \"Honduras\": \"America/Tegucigalpa\",\n \"Mexico\": \"America/Mexico_City\",\n \"Nicaragua\": \"America/Managua\",\n \"Panama\": \"America/Panama\",\n \"Paraguay\": \"America/Asuncion\",\n \"Peru\": \"America/Lima\",\n \"Puerto Rico\": \"America/Puerto_Rico\",\n \"Republica Dominicana\": \"America/Santo_Domingo\",\n \"Uruguay\": \"America/Montevideo\",\n \"Venezuela\": \"America/Caracas\",\n \"Jamaica\": \"America/Jamaica\",\n \"Trinidad and Tobago\": \"America/Port_of_Spain\",\n \"Guyana\": \"America/Guyana\",\n \"Surinam\": \"America/Paramaribo\",\n \"Belice\": \"America/Belize\"\n};\n\n// ==============================\n// FUNCIONES\n// ==============================\n\nfunction normalizarPais(texto) {\n return texto\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .trim()\n .toLowerCase();\n}\n\nfunction obtenerOffsetMinutos(fecha, timeZone) {\n const dtf = new Intl.DateTimeFormat(\"en-US\", {\n timeZone,\n hour12: false,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\"\n });\n\n const partes = dtf.formatToParts(fecha).reduce((acc, p) => {\n acc[p.type] = p.value;\n return acc;\n }, {});\n\n const utcEquivalente = Date.UTC(\n Number(partes.year),\n Number(partes.month) - 1,\n Number(partes.day),\n Number(partes.hour),\n Number(partes.minute),\n Number(partes.second)\n );\n\n return (utcEquivalente - fecha.getTime()) / 60000;\n}\n\nfunction obtenerUTCDesdeHoraLocal(horaTexto, timeZone) {\n const [hora, minuto] = horaTexto.split(\":\").map(Number);\n\n const ahora = new Date();\n\n const y = ahora.getUTCFullYear();\n const m = ahora.getUTCMonth();\n const d = ahora.getUTCDate();\n\n let fechaUTC = new Date(Date.UTC(y, m, d, hora, minuto, 0));\n\n const offset = obtenerOffsetMinutos(fechaUTC, timeZone);\n\n fechaUTC = new Date(fechaUTC.getTime() - offset * 60000);\n\n return fechaUTC;\n}\n\nfunction formatearHora(fechaUTC, timeZone) {\n return new Intl.DateTimeFormat(\"es-DO\", {\n timeZone,\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: false\n }).format(fechaUTC);\n}\n\nfunction convertirHoraDesdeSantoDomingo(horaTexto) {\n\n const fechaUTC = obtenerUTCDesdeHoraLocal(\n horaTexto,\n TIMEZONES[\"Republica Dominicana\"]\n );\n\n const resultado = {};\n\n for (const [pais, tz] of Object.entries(TIMEZONES)) {\n resultado[pais] = formatearHora(fechaUTC, tz);\n }\n\n return resultado;\n}\n\n// ==============================\n// EJECUCIÓN\n// ==============================\n\nconst horaEntrada = $('Calcular sesion mas cercana2')\n .first()\n .json\n .session\n .hora_inicio;\n\nif (!horaEntrada || !/^\\d{1,2}:\\d{2}$/.test(horaEntrada)) {\n throw new Error(\n `Formato de hora inválido: \"${horaEntrada}\". Usa HH:mm, por ejemplo 19:00`\n );\n}\n\nconst conversiones = convertirHoraDesdeSantoDomingo(horaEntrada);\n\nreturn items.map(item => {\n\n const paisEntrada = item.json.pais;\n\n if (!paisEntrada) {\n throw new Error('Cada item debe contener el campo \"pais\".');\n }\n\n // Buscar el país ignorando mayúsculas y acentos\n const paisEncontrado = Object.keys(TIMEZONES).find(\n pais => normalizarPais(pais) === normalizarPais(paisEntrada)\n );\n\n if (!paisEncontrado) {\n throw new Error(\n `País no reconocido: \"${paisEntrada}\". Países válidos: ${Object.keys(TIMEZONES).join(\", \")}`\n );\n }\n\n return {\n json: {\n hora_base: horaEntrada,\n pais_base: \"Republica Dominicana\",\n hora_convertida: conversiones[paisEncontrado],\n conversiones\n }\n };\n});" + "jsCode": "const TIMEZONES = {\n \"Argentina\": \"America/Argentina/Buenos_Aires\",\n \"Bolivia\": \"America/La_Paz\",\n \"Brasil\": \"America/Sao_Paulo\",\n \"Chile\": \"America/Santiago\",\n \"Colombia\": \"America/Bogota\",\n \"Costa Rica\": \"America/Costa_Rica\",\n \"Cuba\": \"America/Havana\",\n \"Ecuador\": \"America/Guayaquil\",\n \"El Salvador\": \"America/El_Salvador\",\n \"Guatemala\": \"America/Guatemala\",\n \"Honduras\": \"America/Tegucigalpa\",\n \"Mexico\": \"America/Mexico_City\",\n \"Nicaragua\": \"America/Managua\",\n \"Panama\": \"America/Panama\",\n \"Paraguay\": \"America/Asuncion\",\n \"Peru\": \"America/Lima\",\n \"Puerto Rico\": \"America/Puerto_Rico\",\n \"Republica Dominicana\": \"America/Santo_Domingo\",\n \"Uruguay\": \"America/Montevideo\",\n \"Venezuela\": \"America/Caracas\",\n \"Jamaica\": \"America/Jamaica\",\n \"Trinidad and Tobago\": \"America/Port_of_Spain\",\n \"Guyana\": \"America/Guyana\",\n \"Surinam\": \"America/Paramaribo\",\n \"Belice\": \"America/Belize\"\n};\n\n// ==============================\n// FUNCIONES\n// ==============================\n\nfunction normalizarPais(texto) {\n return texto\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .trim()\n .toLowerCase();\n}\n\nfunction obtenerOffsetMinutos(fecha, timeZone) {\n const dtf = new Intl.DateTimeFormat(\"en-US\", {\n timeZone,\n hour12: false,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\"\n });\n\n const partes = dtf.formatToParts(fecha).reduce((acc, p) => {\n acc[p.type] = p.value;\n return acc;\n }, {});\n\n const utcEquivalente = Date.UTC(\n Number(partes.year),\n Number(partes.month) - 1,\n Number(partes.day),\n Number(partes.hour),\n Number(partes.minute),\n Number(partes.second)\n );\n\n return (utcEquivalente - fecha.getTime()) / 60000;\n}\n\nfunction obtenerUTCDesdeHoraLocal(horaTexto, timeZone) {\n const [hora, minuto] = horaTexto.split(\":\").map(Number);\n\n const ahora = new Date();\n\n const y = ahora.getUTCFullYear();\n const m = ahora.getUTCMonth();\n const d = ahora.getUTCDate();\n\n let fechaUTC = new Date(Date.UTC(y, m, d, hora, minuto, 0));\n\n const offset = obtenerOffsetMinutos(fechaUTC, timeZone);\n\n fechaUTC = new Date(fechaUTC.getTime() - offset * 60000);\n\n return fechaUTC;\n}\n\nfunction formatearHora(fechaUTC, timeZone) {\n return new Intl.DateTimeFormat(\"es-DO\", {\n timeZone,\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: false\n }).format(fechaUTC);\n}\n\nfunction convertirHoraDesdeSantoDomingo(horaTexto) {\n\n const fechaUTC = obtenerUTCDesdeHoraLocal(\n horaTexto,\n TIMEZONES[\"Republica Dominicana\"]\n );\n\n const resultado = {};\n\n for (const [pais, tz] of Object.entries(TIMEZONES)) {\n resultado[pais] = formatearHora(fechaUTC, tz);\n }\n\n return resultado;\n}\n\n// ==============================\n// EJECUCIÓN\n// ==============================\n\nconst horaEntrada = $('Calcular sesion mas cercana2')\n .first()\n .json\n .session\n .hora_inicio;\n\nif (!horaEntrada || !/^\\d{1,2}:\\d{2}$/.test(horaEntrada)) {\n throw new Error(\n `Formato de hora inválido: \"${horaEntrada}\". Usa HH:mm, por ejemplo 19:00`\n );\n}\n\nconst conversiones = convertirHoraDesdeSantoDomingo(horaEntrada);\n\nreturn items.map(item => {\n\n const paisEntrada = $('Actualizar datos del empleado y sesion asignada').first().json.pais;\n\n if (!paisEntrada) {\n throw new Error('Cada item debe contener el campo \"pais\".');\n }\n\n // Buscar el país ignorando mayúsculas y acentos\n const paisEncontrado = Object.keys(TIMEZONES).find(\n pais => normalizarPais(pais) === normalizarPais(paisEntrada)\n );\n\n if (!paisEncontrado) {\n throw new Error(\n `País no reconocido: \"${paisEntrada}\". Países válidos: ${Object.keys(TIMEZONES).join(\", \")}`\n );\n }\n\n return {\n json: {\n hora_base: horaEntrada,\n pais_base: \"Republica Dominicana\",\n hora_convertida: conversiones[paisEncontrado],\n conversiones\n }\n };\n});" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 2464, + 2288, 272 ], "id": "bbd8c7de-64eb-4262-a77b-b7307ab9c0c6", @@ -11253,12 +10649,12 @@ }, { "parameters": { - "jsCode": "const TIMEZONES = {\n \"Argentina\": \"America/Argentina/Buenos_Aires\",\n \"Bolivia\": \"America/La_Paz\",\n \"Brasil\": \"America/Sao_Paulo\",\n \"Chile\": \"America/Santiago\",\n \"Colombia\": \"America/Bogota\",\n \"Costa Rica\": \"America/Costa_Rica\",\n \"Cuba\": \"America/Havana\",\n \"Ecuador\": \"America/Guayaquil\",\n \"El Salvador\": \"America/El_Salvador\",\n \"Guatemala\": \"America/Guatemala\",\n \"Honduras\": \"America/Tegucigalpa\",\n \"Mexico\": \"America/Mexico_City\",\n \"Nicaragua\": \"America/Managua\",\n \"Panama\": \"America/Panama\",\n \"Paraguay\": \"America/Asuncion\",\n \"Peru\": \"America/Lima\",\n \"Puerto Rico\": \"America/Puerto_Rico\",\n \"Republica Dominicana\": \"America/Santo_Domingo\",\n \"Uruguay\": \"America/Montevideo\",\n \"Venezuela\": \"America/Caracas\",\n \"Jamaica\": \"America/Jamaica\",\n \"Trinidad and Tobago\": \"America/Port_of_Spain\",\n \"Guyana\": \"America/Guyana\",\n \"Surinam\": \"America/Paramaribo\",\n \"Belice\": \"America/Belize\"\n};\n\n// ==============================\n// FUNCIONES\n// ==============================\n\nfunction normalizarPais(texto) {\n return texto\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .trim()\n .toLowerCase();\n}\n\nfunction obtenerOffsetMinutos(fecha, timeZone) {\n const dtf = new Intl.DateTimeFormat(\"en-US\", {\n timeZone,\n hour12: false,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\"\n });\n\n const partes = dtf.formatToParts(fecha).reduce((acc, p) => {\n acc[p.type] = p.value;\n return acc;\n }, {});\n\n const utcEquivalente = Date.UTC(\n Number(partes.year),\n Number(partes.month) - 1,\n Number(partes.day),\n Number(partes.hour),\n Number(partes.minute),\n Number(partes.second)\n );\n\n return (utcEquivalente - fecha.getTime()) / 60000;\n}\n\nfunction obtenerUTCDesdeHoraLocal(horaTexto, timeZone) {\n const [hora, minuto] = horaTexto.split(\":\").map(Number);\n\n const ahora = new Date();\n\n const y = ahora.getUTCFullYear();\n const m = ahora.getUTCMonth();\n const d = ahora.getUTCDate();\n\n let fechaUTC = new Date(Date.UTC(y, m, d, hora, minuto, 0));\n\n const offset = obtenerOffsetMinutos(fechaUTC, timeZone);\n\n fechaUTC = new Date(fechaUTC.getTime() - offset * 60000);\n\n return fechaUTC;\n}\n\nfunction formatearHora(fechaUTC, timeZone) {\n return new Intl.DateTimeFormat(\"es-DO\", {\n timeZone,\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: false\n }).format(fechaUTC);\n}\n\nfunction convertirHoraDesdeSantoDomingo(horaTexto) {\n\n const fechaUTC = obtenerUTCDesdeHoraLocal(\n horaTexto,\n TIMEZONES[\"Republica Dominicana\"]\n );\n\n const resultado = {};\n\n for (const [pais, tz] of Object.entries(TIMEZONES)) {\n resultado[pais] = formatearHora(fechaUTC, tz);\n }\n\n return resultado;\n}\n\n// ==============================\n// EJECUCIÓN\n// ==============================\n\nconst horaEntrada = $('Calcular sesion mas cercana3')\n .first()\n .json\n .session\n .hora_inicio;\n\nif (!horaEntrada || !/^\\d{1,2}:\\d{2}$/.test(horaEntrada)) {\n throw new Error(\n `Formato de hora inválido: \"${horaEntrada}\". Usa HH:mm, por ejemplo 19:00`\n );\n}\n\nconst conversiones = convertirHoraDesdeSantoDomingo(horaEntrada);\n\nreturn items.map(item => {\n\n const paisEntrada = item.json.pais;\n\n if (!paisEntrada) {\n throw new Error('Cada item debe contener el campo \"pais\".');\n }\n\n // Buscar el país ignorando mayúsculas y acentos\n const paisEncontrado = Object.keys(TIMEZONES).find(\n pais => normalizarPais(pais) === normalizarPais(paisEntrada)\n );\n\n if (!paisEncontrado) {\n throw new Error(\n `País no reconocido: \"${paisEntrada}\". Países válidos: ${Object.keys(TIMEZONES).join(\", \")}`\n );\n }\n\n return {\n json: {\n hora_base: horaEntrada,\n pais_base: \"Republica Dominicana\",\n hora_convertida: conversiones[paisEncontrado],\n conversiones\n }\n };\n});" + "jsCode": "const TIMEZONES = {\n \"Argentina\": \"America/Argentina/Buenos_Aires\",\n \"Bolivia\": \"America/La_Paz\",\n \"Brasil\": \"America/Sao_Paulo\",\n \"Chile\": \"America/Santiago\",\n \"Colombia\": \"America/Bogota\",\n \"Costa Rica\": \"America/Costa_Rica\",\n \"Cuba\": \"America/Havana\",\n \"Ecuador\": \"America/Guayaquil\",\n \"El Salvador\": \"America/El_Salvador\",\n \"Guatemala\": \"America/Guatemala\",\n \"Honduras\": \"America/Tegucigalpa\",\n \"Mexico\": \"America/Mexico_City\",\n \"Nicaragua\": \"America/Managua\",\n \"Panama\": \"America/Panama\",\n \"Paraguay\": \"America/Asuncion\",\n \"Peru\": \"America/Lima\",\n \"Puerto Rico\": \"America/Puerto_Rico\",\n \"Republica Dominicana\": \"America/Santo_Domingo\",\n \"Uruguay\": \"America/Montevideo\",\n \"Venezuela\": \"America/Caracas\",\n \"Jamaica\": \"America/Jamaica\",\n \"Trinidad and Tobago\": \"America/Port_of_Spain\",\n \"Guyana\": \"America/Guyana\",\n \"Surinam\": \"America/Paramaribo\",\n \"Belice\": \"America/Belize\"\n};\n\n// ==============================\n// FUNCIONES\n// ==============================\n\nfunction normalizarPais(texto) {\n return texto\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .trim()\n .toLowerCase();\n}\n\nfunction obtenerOffsetMinutos(fecha, timeZone) {\n const dtf = new Intl.DateTimeFormat(\"en-US\", {\n timeZone,\n hour12: false,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\"\n });\n\n const partes = dtf.formatToParts(fecha).reduce((acc, p) => {\n acc[p.type] = p.value;\n return acc;\n }, {});\n\n const utcEquivalente = Date.UTC(\n Number(partes.year),\n Number(partes.month) - 1,\n Number(partes.day),\n Number(partes.hour),\n Number(partes.minute),\n Number(partes.second)\n );\n\n return (utcEquivalente - fecha.getTime()) / 60000;\n}\n\nfunction obtenerUTCDesdeHoraLocal(horaTexto, timeZone) {\n const [hora, minuto] = horaTexto.split(\":\").map(Number);\n\n const ahora = new Date();\n\n const y = ahora.getUTCFullYear();\n const m = ahora.getUTCMonth();\n const d = ahora.getUTCDate();\n\n let fechaUTC = new Date(Date.UTC(y, m, d, hora, minuto, 0));\n\n const offset = obtenerOffsetMinutos(fechaUTC, timeZone);\n\n fechaUTC = new Date(fechaUTC.getTime() - offset * 60000);\n\n return fechaUTC;\n}\n\nfunction formatearHora(fechaUTC, timeZone) {\n return new Intl.DateTimeFormat(\"es-DO\", {\n timeZone,\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: false\n }).format(fechaUTC);\n}\n\nfunction convertirHoraDesdeSantoDomingo(horaTexto) {\n\n const fechaUTC = obtenerUTCDesdeHoraLocal(\n horaTexto,\n TIMEZONES[\"Republica Dominicana\"]\n );\n\n const resultado = {};\n\n for (const [pais, tz] of Object.entries(TIMEZONES)) {\n resultado[pais] = formatearHora(fechaUTC, tz);\n }\n\n return resultado;\n}\n\n// ==============================\n// EJECUCIÓN\n// ==============================\n\nconst horaEntrada = $('Calcular sesion mas cercana3')\n .first()\n .json\n .session\n .hora_inicio;\n\nif (!horaEntrada || !/^\\d{1,2}:\\d{2}$/.test(horaEntrada)) {\n throw new Error(\n `Formato de hora inválido: \"${horaEntrada}\". Usa HH:mm, por ejemplo 19:00`\n );\n}\n\nconst conversiones = convertirHoraDesdeSantoDomingo(horaEntrada);\n\nreturn items.map(item => {\n\n const paisEntrada = $('Actualizar datos del empleado y sesion asignada1').first().json.pais;\n\n if (!paisEntrada) {\n throw new Error('Cada item debe contener el campo \"pais\".');\n }\n\n // Buscar el país ignorando mayúsculas y acentos\n const paisEncontrado = Object.keys(TIMEZONES).find(\n pais => normalizarPais(pais) === normalizarPais(paisEntrada)\n );\n\n if (!paisEncontrado) {\n throw new Error(\n `País no reconocido: \"${paisEntrada}\". Países válidos: ${Object.keys(TIMEZONES).join(\", \")}`\n );\n }\n\n return {\n json: {\n hora_base: horaEntrada,\n pais_base: \"Republica Dominicana\",\n hora_convertida: conversiones[paisEncontrado],\n conversiones\n }\n };\n});" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ - 2464, + 2288, 448 ], "id": "677acc91-b856-482e-aa2c-9b329221918a", @@ -11341,6 +10737,271 @@ "name": "Sofia test - Supabase account" } } + }, + { + "parameters": { + "resource": "meeting", + "operation": "addToLiveMeeting", + "additionalFields": {} + }, + "type": "@firefliesai/n8n-nodes-fireflies.fireflies", + "typeVersion": 1, + "position": [ + -336, + 3440 + ], + "id": "6852b24e-9982-487d-a926-942f6d2bb7b3", + "name": "Add fred to a live meeting" + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict", + "version": 3 + }, + "conditions": [ + { + "id": "d7d68505-8c34-44cd-b771-56bef28ada41", + "leftValue": "={{ $('Get an employee').item.json.workEmail }}", + "rightValue": "", + "operator": { + "type": "string", + "operation": "notEmpty", + "singleValue": true + } + }, + { + "id": "ec0276ab-208e-409b-8101-d06e535f541c", + "leftValue": "={{ $('Get an employee').item.json.location }}", + "rightValue": "", + "operator": { + "type": "string", + "operation": "notEmpty", + "singleValue": true + } + } + ], + "combinator": "and" + }, + "options": {} + }, + "type": "n8n-nodes-base.if", + "typeVersion": 2.3, + "position": [ + 352, + -144 + ], + "id": "a9fff247-d1b0-4314-ba8d-e7401086b771", + "name": "Tiene correo y pais?" + }, + { + "parameters": { + "conditions": { + "options": { + "caseSensitive": true, + "leftValue": "", + "typeValidation": "strict", + "version": 3 + }, + "conditions": [ + { + "id": "d7d68505-8c34-44cd-b771-56bef28ada41", + "leftValue": "={{ $('Get an employee1').item.json.workEmail }}", + "rightValue": "", + "operator": { + "type": "string", + "operation": "notEmpty", + "singleValue": true + } + }, + { + "id": "a245c081-ef08-4ba2-8164-2d2c35bd1e17", + "leftValue": "={{ $('Get an employee1').item.json.location }}", + "rightValue": "", + "operator": { + "type": "string", + "operation": "notEmpty", + "singleValue": true + } + } + ], + "combinator": "and" + }, + "options": {} + }, + "type": "n8n-nodes-base.if", + "typeVersion": 2.3, + "position": [ + 752, + 352 + ], + "id": "a2a81e91-f617-490a-b1ce-5737944fa23b", + "name": "Tiene correo y pais?1" + }, + { + "parameters": { + "operation": "update", + "tableId": "inscritos_glmway", + "filters": { + "conditions": [ + { + "keyName": "empleado_id", + "condition": "eq", + "keyValue": "={{ $('Get an employee1').item.json.id }}" + } + ] + }, + "fieldsUi": { + "fieldValues": [ + { + "fieldId": "empleado_id", + "fieldValue": "={{ $('Informacion extra del empleado1').item.json.id }}" + }, + { + "fieldId": "nombre", + "fieldValue": "={{ $('Get an employee1').item.json.displayName }}" + }, + { + "fieldId": "email", + "fieldValue": "={{ $('Get an employee1').item.json.workEmail }}" + }, + { + "fieldId": "departamento", + "fieldValue": "={{ $('Get an employee1').item.json.department }}" + }, + { + "fieldId": "supervisor_id", + "fieldValue": "={{ $('Informacion extra del empleado1').item.json.supervisorEId }}" + }, + { + "fieldId": "fecha_ingreso", + "fieldValue": "={{ $('Informacion extra del empleado1').item.json.hireDate }}" + }, + { + "fieldId": "fecha_sesion_inscrito", + "fieldValue": "={{ $json.session.fecha_sesion }}" + }, + { + "fieldId": "estado", + "fieldValue": "notificado" + }, + { + "fieldId": "sesion_id", + "fieldValue": "={{ $json.session.id }}" + }, + { + "fieldId": "pais", + "fieldValue": "={{ $('Get an employee1').item.json.location }}" + }, + { + "fieldId": "division", + "fieldValue": "={{ $('Get an employee1').item.json.division }}" + }, + { + "fieldId": "puesto", + "fieldValue": "={{ $('Get an employee1').item.json.jobTitle }}" + } + ] + } + }, + "type": "n8n-nodes-base.supabase", + "typeVersion": 1, + "position": [ + 1904, + 272 + ], + "id": "16d364da-e6fc-4943-bd64-f83ccab66b9f", + "name": "Actualizar datos del empleado y sesion asignada", + "credentials": { + "supabaseApi": { + "id": "2PlsR6rpK7rQTIEn", + "name": "Sofia test - Supabase account" + } + } + }, + { + "parameters": { + "operation": "update", + "tableId": "inscritos_glmway", + "filters": { + "conditions": [ + { + "keyName": "empleado_id", + "condition": "eq", + "keyValue": "={{ $('Get an employee1').item.json.id }}" + } + ] + }, + "fieldsUi": { + "fieldValues": [ + { + "fieldId": "empleado_id", + "fieldValue": "={{ $('Informacion extra del empleado1').item.json.id }}" + }, + { + "fieldId": "nombre", + "fieldValue": "={{ $('Get an employee1').item.json.displayName }}" + }, + { + "fieldId": "email", + "fieldValue": "={{ $('Get an employee1').item.json.workEmail }}" + }, + { + "fieldId": "departamento", + "fieldValue": "={{ $('Get an employee1').item.json.department }}" + }, + { + "fieldId": "supervisor_id", + "fieldValue": "={{ $('Informacion extra del empleado1').item.json.supervisorEId }}" + }, + { + "fieldId": "fecha_ingreso", + "fieldValue": "={{ $('Informacion extra del empleado1').item.json.hireDate }}" + }, + { + "fieldId": "fecha_sesion_inscrito", + "fieldValue": "={{ $json.session.fecha_sesion }}" + }, + { + "fieldId": "estado", + "fieldValue": "notificado" + }, + { + "fieldId": "sesion_id", + "fieldValue": "={{ $json.session.id }}" + }, + { + "fieldId": "pais", + "fieldValue": "={{ $('Get an employee1').item.json.location }}" + }, + { + "fieldId": "division", + "fieldValue": "={{ $('Get an employee1').item.json.division }}" + }, + { + "fieldId": "puesto", + "fieldValue": "={{ $('Get an employee1').item.json.jobTitle }}" + } + ] + } + }, + "type": "n8n-nodes-base.supabase", + "typeVersion": 1, + "position": [ + 1904, + 448 + ], + "id": "f2aca2bd-e72d-4457-9a6b-c4b0f8bcc558", + "name": "Actualizar datos del empleado y sesion asignada1", + "credentials": { + "supabaseApi": { + "id": "2PlsR6rpK7rQTIEn", + "name": "Sofia test - Supabase account" + } + } } ], "connections": { @@ -11481,7 +11142,7 @@ "main": [ [ { - "node": "Obtener coordinador", + "node": "Pais?", "type": "main", "index": 0 } @@ -11499,7 +11160,7 @@ "main": [ [ { - "node": "Tiene correo?1", + "node": "Tiene correo y pais?", "type": "main", "index": 0 } @@ -11508,13 +11169,7 @@ }, "Hay coordinador?": { "main": [ - [ - { - "node": "Pais?", - "type": "main", - "index": 0 - } - ], + [], [ { "node": "Alerta no hay coordinador RRHH", @@ -11583,7 +11238,7 @@ "main": [ [ { - "node": "Tiene correo?", + "node": "Tiene correo y pais?1", "type": "main", "index": 0 } @@ -11676,7 +11331,7 @@ "main": [ [ { - "node": "Obtener coordinador1", + "node": "Registrar empleado a la sesion3", "type": "main", "index": 0 } @@ -11687,7 +11342,7 @@ "main": [ [ { - "node": "Obtener coordinador1", + "node": "Registrar empleado a la sesion2", "type": "main", "index": 0 } @@ -11903,7 +11558,7 @@ "main": [ [ { - "node": "Actualizar datos del empleado y sesion asignada2", + "node": "Actualizar datos del empleado y sesion asignada", "type": "main", "index": 0 } @@ -11914,7 +11569,7 @@ "main": [ [ { - "node": "Actualizar datos del empleado y sesion asignada3", + "node": "Actualizar datos del empleado y sesion asignada1", "type": "main", "index": 0 } @@ -11925,7 +11580,7 @@ "main": [ [ { - "node": "Registrar empleado a la sesion", + "node": "Convertir fecha a espanol", "type": "main", "index": 0 } @@ -11936,7 +11591,7 @@ "main": [ [ { - "node": "Registrar empleado a la sesion1", + "node": "Convertir fecha a ingles", "type": "main", "index": 0 } @@ -11987,35 +11642,6 @@ ] ] }, - "Tiene correo?": { - "main": [ - [ - { - "node": "Entra hoy?1", - "type": "main", - "index": 0 - } - ], - [ - { - "node": "Wait2", - "type": "main", - "index": 0 - } - ] - ] - }, - "Actualizar datos del empleado y sesion asignada2": { - "main": [ - [ - { - "node": "Registrar empleado a la sesion2", - "type": "main", - "index": 0 - } - ] - ] - }, "Obtener notificados": { "main": [ [ @@ -12164,35 +11790,6 @@ ] ] }, - "Actualizar datos del empleado y sesion asignada3": { - "main": [ - [ - { - "node": "Registrar empleado a la sesion3", - "type": "main", - "index": 0 - } - ] - ] - }, - "Tiene correo?1": { - "main": [ - [ - { - "node": "Entra hoy?", - "type": "main", - "index": 0 - } - ], - [ - { - "node": "Insertar a inscritos (inactivo)", - "type": "main", - "index": 0 - } - ] - ] - }, "Schedule Trigger4": { "main": [ [ @@ -12586,7 +12183,7 @@ "main": [ [ { - "node": "Convertir fecha a espanol", + "node": "Obtener coordinador", "type": "main", "index": 0 } @@ -12597,7 +12194,7 @@ "main": [ [ { - "node": "Convertir fecha a ingles", + "node": "Obtener coordinador", "type": "main", "index": 0 } @@ -12608,7 +12205,7 @@ "main": [ [ { - "node": "Convertir fecha a espanol1", + "node": "Obtener coordinador1", "type": "main", "index": 0 } @@ -12619,7 +12216,7 @@ "main": [ [ { - "node": "Convertir fecha a ingles1", + "node": "Obtener coordinador1", "type": "main", "index": 0 } @@ -12775,18 +12372,98 @@ } ] ] + }, + "Tiene correo y pais?": { + "main": [ + [ + { + "node": "Entra hoy?", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Insertar a inscritos (inactivo)", + "type": "main", + "index": 0 + } + ] + ] + }, + "Tiene correo y pais?1": { + "main": [ + [ + { + "node": "Entra hoy?1", + "type": "main", + "index": 0 + } + ], + [ + { + "node": "Wait2", + "type": "main", + "index": 0 + } + ] + ] + }, + "Send a message espanol": { + "main": [ + [ + { + "node": "Registrar empleado a la sesion", + "type": "main", + "index": 0 + } + ] + ] + }, + "Send a message ingles": { + "main": [ + [ + { + "node": "Registrar empleado a la sesion1", + "type": "main", + "index": 0 + } + ] + ] + }, + "Actualizar datos del empleado y sesion asignada": { + "main": [ + [ + { + "node": "Convertir fecha a espanol1", + "type": "main", + "index": 0 + } + ] + ] + }, + "Actualizar datos del empleado y sesion asignada1": { + "main": [ + [ + { + "node": "Convertir fecha a ingles1", + "type": "main", + "index": 0 + } + ] + ] } }, "authors": "Eidan Then", - "name": "Version fd8d6eab", + "name": "Version 035c48ce", "description": "", "autosaved": true, "workflowPublishHistory": [ { - "createdAt": "2026-07-02T17:59:04.569Z", - "id": 2294, + "createdAt": "2026-07-03T15:28:30.414Z", + "id": 2358, "workflowId": "F1iPg8hktNAebZua", - "versionId": "fd8d6eab-dabd-462e-a535-455b8571a191", + "versionId": "035c48ce-6ce9-4bca-a5ef-cf6e51360ce3", "event": "activated", "userId": "de14e7e5-491b-4983-abb2-f88af42e92fd" }