{ "name": "Seguimiento de Impuestos GLM - Google Calendar", "nodes": [ { "parameters": { "httpMethod": "POST", "path": "seguimiento-impuestos-google-calendar", "responseMode": "responseNode", "options": {} }, "type": "n8n-nodes-base.webhook", "typeVersion": 2.1, "position": [ 320, 480 ], "id": "1969add0-835c-459f-906e-ecb0bc43b175", "name": "Webhook - Google Calendar", "webhookId": "seguimiento-impuestos-google-calendar" }, { "parameters": { "jsCode": "let body = $json.body ?? $json;\nif (typeof body === 'string') {\n try { body = JSON.parse(body); }\n catch { body = {}; }\n}\nconst action = String(body.action ?? '').trim().toLowerCase();\nconst payload = body.payload ?? {};\nconst obligationId = String(payload.obligation_id ?? body.obligation_id ?? '').trim();\nconst allowed = ['obligation.created', 'obligation.updated', 'obligation.deleted'];\nreturn [{\n json: {\n valid: allowed.includes(action) && Boolean(obligationId),\n action,\n obligation_id: obligationId,\n message: allowed.includes(action)\n ? (obligationId ? '' : 'Falta obligation_id.')\n : 'Acción no soportada.',\n },\n}];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 560, 480 ], "id": "4257a973-d67c-4972-a140-0acdeaa0367e", "name": "Preparar solicitud" }, { "parameters": { "conditions": { "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict", "version": 2 }, "conditions": [ { "id": "771f008a-734d-436d-9122-448758a2263a", "leftValue": "={{ $json.valid }}", "rightValue": true, "operator": { "type": "boolean", "operation": "true", "singleValue": true } } ], "combinator": "and" }, "options": {} }, "type": "n8n-nodes-base.if", "typeVersion": 2.2, "position": [ 800, 480 ], "id": "7714ac21-6eed-4eaa-aa57-1f145ace0b13", "name": "Solicitud válida" }, { "parameters": { "method": "POST", "url": "https://dbit.digitalcompass.agency/rest/v1/rpc/tax_google_calendar_payload", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "apikey", "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" }, { "name": "Authorization", "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" }, { "name": "Content-Type", "value": "application/json" } ] }, "sendBody": true, "specifyBody": "json", "jsonBody": "={{ { p_obligation_id: $json.obligation_id } }}", "options": {} }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ 1056, 384 ], "id": "60720896-3eef-4a6f-9c8f-406bc777137b", "name": "Supabase - Obtener obligación y asistentes" }, { "parameters": { "jsCode": "const source = $('Preparar solicitud').item.json;\nconst value = $json;\nconst row = Array.isArray(value) ? value[0] : Array.isArray(value?.data) ? value.data[0] : value;\nif (!row?.obligation_id) {\n return [{ json: { ...source, operation: 'noop', reason: 'No se encontró la obligación.' } }];\n}\n\nconst attendees = Array.isArray(row.attendees)\n ? [...new Set(row.attendees.map((email) => String(email ?? '').trim().toLowerCase()).filter(Boolean))]\n : [];\nconst start = `${row.due_date}T08:00:00-04:00`;\nconst end = `${row.due_date}T09:00:00-04:00`;\nconst categoryLabel = row.category === 'nomina' ? 'Nómina' : 'Administración';\nconst summary = `Impuestos · ${row.country_name} · ${row.description}`;\nconst description = [\n 'Seguimiento de Impuestos GLM',\n '',\n `País: ${row.country_name}`,\n `Categoría: ${categoryLabel}`,\n `Fecha límite: ${row.due_date}`,\n `Obligación: ${row.description}`,\n '',\n 'Abrir aplicación: https://home.digitalcompass.agency/',\n].join('\\n');\nconst calendarBody = {\n summary,\n description,\n start: { dateTime: start, timeZone: 'America/Santo_Domingo' },\n end: { dateTime: end, timeZone: 'America/Santo_Domingo' },\n attendees: attendees.map((email) => ({ email })),\n reminders: {\n useDefault: false,\n overrides: [\n { method: 'email', minutes: 0 },\n { method: 'popup', minutes: 0 },\n ],\n },\n extendedProperties: {\n private: {\n glmTaxObligationId: row.obligation_id,\n glmTaxCountryCode: row.country_code,\n glmTaxCategory: row.category,\n },\n },\n};\n\nlet operation = 'create';\nif (source.action === 'obligation.deleted' || row.active === false) {\n operation = row.google_event_id ? 'delete' : 'noop';\n} else if (row.google_event_id) {\n operation = 'update';\n}\n\nreturn [{\n json: {\n ...source,\n ...row,\n attendees,\n start,\n end,\n summary,\n calendar_description: description,\n calendar_body: calendarBody,\n calendar_id: row.calendar_id || 'primary',\n operation,\n },\n}];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 1312, 384 ], "id": "437c0861-d237-43a9-acb6-a3cecad1c748", "name": "Preparar payload Calendar" }, { "parameters": { "jsCode": "return $input.all().filter((item) => item.json.operation === 'create');" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 1568, 256 ], "id": "21075755-7ae2-4f5a-ae0e-63e5e62b9e78", "name": "Preparar crear" }, { "parameters": { "jsCode": "return $input.all().filter((item) => item.json.operation === 'update');" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 1568, 416 ], "id": "b20f873b-1b6d-4fde-8832-1dae87674f60", "name": "Preparar actualizar" }, { "parameters": { "jsCode": "return $input.all().filter((item) => item.json.operation === 'delete');" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 1568, 576 ], "id": "21a0f3e2-c6e6-40e8-b013-30ba4c739a44", "name": "Preparar eliminar" }, { "parameters": { "jsCode": "return $input.all().filter((item) => item.json.operation === 'noop');" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 1568, 736 ], "id": "9efc968a-6ba7-41bd-8bdb-f391a6b482f2", "name": "Preparar sin acción" }, { "parameters": { "method": "POST", "url": "https://www.googleapis.com/calendar/v3/calendars/primary/events?sendUpdates=all", "authentication": "predefinedCredentialType", "nodeCredentialType": "googleCalendarOAuth2Api", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "Content-Type", "value": "application/json" } ] }, "sendBody": true, "specifyBody": "json", "jsonBody": "={{ $json.calendar_body }}", "options": {} }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ 1824, 256 ], "id": "b4a40589-9002-4479-8576-7c01d746fb65", "name": "Google Calendar - Crear evento", "credentials": { "googleCalendarOAuth2Api": { "id": "REEMPLAZAR_CREDENCIAL_GOOGLE_CALENDAR", "name": "Google Calendar GLM" } } }, { "parameters": { "method": "PATCH", "url": "={{ 'https://www.googleapis.com/calendar/v3/calendars/primary/events/' + encodeURIComponent($json.google_event_id) + '?sendUpdates=all' }}", "authentication": "predefinedCredentialType", "nodeCredentialType": "googleCalendarOAuth2Api", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "Content-Type", "value": "application/json" } ] }, "sendBody": true, "specifyBody": "json", "jsonBody": "={{ $json.calendar_body }}", "options": {} }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ 1824, 416 ], "id": "443971f0-bb68-4051-adbc-81f46e7cf785", "name": "Google Calendar - Actualizar evento", "credentials": { "googleCalendarOAuth2Api": { "id": "REEMPLAZAR_CREDENCIAL_GOOGLE_CALENDAR", "name": "Google Calendar GLM" } } }, { "parameters": { "method": "DELETE", "url": "={{ 'https://www.googleapis.com/calendar/v3/calendars/primary/events/' + encodeURIComponent($json.google_event_id) + '?sendUpdates=all' }}", "authentication": "predefinedCredentialType", "nodeCredentialType": "googleCalendarOAuth2Api", "options": {} }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ 1824, 576 ], "id": "9658c53c-ebeb-4c28-94cd-e56011a6175e", "name": "Google Calendar - Eliminar evento", "credentials": { "googleCalendarOAuth2Api": { "id": "REEMPLAZAR_CREDENCIAL_GOOGLE_CALENDAR", "name": "Google Calendar GLM" } } }, { "parameters": { "jsCode": "const source = $('Preparar crear').item.json; return [{ json: { ...source, google_event_id: String($json.id ?? ''), google_response: $json, sync_action: 'create', sync_status: 'active' } }];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 2080, 256 ], "id": "a807b37a-f61c-46de-87f8-74a436a92e00", "name": "Preparar registro creado" }, { "parameters": { "jsCode": "const source = $('Preparar actualizar').item.json; return [{ json: { ...source, google_event_id: source.google_event_id, google_response: $json, sync_action: 'update', sync_status: 'active' } }];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 2080, 416 ], "id": "497396c0-d40e-4613-aeb4-baf52ce8f447", "name": "Preparar registro actualizado" }, { "parameters": { "jsCode": "const source = $('Preparar eliminar').item.json; return [{ json: { ...source, google_event_id: source.google_event_id, google_response: $json ?? {}, sync_action: 'delete', sync_status: 'deleted' } }];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 2080, 576 ], "id": "034ad2a5-526e-4d4c-9a56-db9e83bde071", "name": "Preparar registro eliminado" }, { "parameters": { "method": "POST", "url": "https://dbit.digitalcompass.agency/rest/v1/rpc/tax_record_google_calendar_sync", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "apikey", "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" }, { "name": "Authorization", "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" }, { "name": "Content-Type", "value": "application/json" } ] }, "sendBody": true, "specifyBody": "json", "jsonBody": "={{ { p_obligation_id: $('Preparar registro creado').item.json.obligation_id, p_google_event_id: $('Preparar registro creado').item.json.google_event_id, p_calendar_id: 'primary', p_attendees: $('Preparar registro creado').item.json.attendees, p_status: $('Preparar registro creado').item.json.sync_status, p_last_action: $('Preparar registro creado').item.json.sync_action, p_provider_response: $('Preparar registro creado').item.json.google_response } }}", "options": {} }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ 2336, 256 ], "id": "5072ebec-03ee-49e7-b050-6cc93b538f7b", "name": "Supabase - Registrar creación Calendar" }, { "parameters": { "method": "POST", "url": "https://dbit.digitalcompass.agency/rest/v1/rpc/tax_record_google_calendar_sync", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "apikey", "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" }, { "name": "Authorization", "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" }, { "name": "Content-Type", "value": "application/json" } ] }, "sendBody": true, "specifyBody": "json", "jsonBody": "={{ { p_obligation_id: $('Preparar registro actualizado').item.json.obligation_id, p_google_event_id: $('Preparar registro actualizado').item.json.google_event_id, p_calendar_id: 'primary', p_attendees: $('Preparar registro actualizado').item.json.attendees, p_status: $('Preparar registro actualizado').item.json.sync_status, p_last_action: $('Preparar registro actualizado').item.json.sync_action, p_provider_response: $('Preparar registro actualizado').item.json.google_response } }}", "options": {} }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ 2336, 416 ], "id": "774d2dab-bb85-44e5-aeaf-e4dfe6954931", "name": "Supabase - Registrar actualización Calendar" }, { "parameters": { "method": "POST", "url": "https://dbit.digitalcompass.agency/rest/v1/rpc/tax_record_google_calendar_sync", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "apikey", "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" }, { "name": "Authorization", "value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" }, { "name": "Content-Type", "value": "application/json" } ] }, "sendBody": true, "specifyBody": "json", "jsonBody": "={{ { p_obligation_id: $('Preparar registro eliminado').item.json.obligation_id, p_google_event_id: $('Preparar registro eliminado').item.json.google_event_id, p_calendar_id: 'primary', p_attendees: $('Preparar registro eliminado').item.json.attendees, p_status: $('Preparar registro eliminado').item.json.sync_status, p_last_action: $('Preparar registro eliminado').item.json.sync_action, p_provider_response: $('Preparar registro eliminado').item.json.google_response } }}", "options": {} }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ 2336, 576 ], "id": "67986a91-dbb4-4ab2-b33e-e003ac8895df", "name": "Supabase - Registrar eliminación Calendar" }, { "parameters": { "respondWith": "json", "responseBody": "={{ { ok: true, message: 'Evento creado en Google Calendar.' } }}", "options": { "responseCode": 200, "responseHeaders": { "entries": [ { "name": "Access-Control-Allow-Origin", "value": "*" }, { "name": "Cache-Control", "value": "no-store" } ] } } }, "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.4, "position": [ 2592, 256 ], "id": "932c9da0-2a24-4eb3-ac40-3ccaf5b1895a", "name": "Responder creación" }, { "parameters": { "respondWith": "json", "responseBody": "={{ { ok: true, message: 'Evento actualizado en Google Calendar.' } }}", "options": { "responseCode": 200, "responseHeaders": { "entries": [ { "name": "Access-Control-Allow-Origin", "value": "*" }, { "name": "Cache-Control", "value": "no-store" } ] } } }, "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.4, "position": [ 2592, 416 ], "id": "bbeb54b6-30c9-43f8-9c54-7564a1684d3b", "name": "Responder actualización" }, { "parameters": { "respondWith": "json", "responseBody": "={{ { ok: true, message: 'Evento eliminado de Google Calendar.' } }}", "options": { "responseCode": 200, "responseHeaders": { "entries": [ { "name": "Access-Control-Allow-Origin", "value": "*" }, { "name": "Cache-Control", "value": "no-store" } ] } } }, "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.4, "position": [ 2592, 576 ], "id": "51bee51d-e61a-473a-a200-a447b295a59e", "name": "Responder eliminación" }, { "parameters": { "respondWith": "json", "responseBody": "={{ { ok: true, message: $json.reason || 'No había cambios que sincronizar.' } }}", "options": { "responseCode": 200, "responseHeaders": { "entries": [ { "name": "Access-Control-Allow-Origin", "value": "*" } ] } } }, "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.4, "position": [ 1824, 736 ], "id": "f3b38547-3de2-4499-94c8-7a331cae5c9a", "name": "Responder sin acción" }, { "parameters": { "respondWith": "json", "responseBody": "={{ { ok: false, message: $json.message } }}", "options": { "responseCode": 400, "responseHeaders": { "entries": [ { "name": "Access-Control-Allow-Origin", "value": "*" } ] } } }, "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.4, "position": [ 1056, 656 ], "id": "558b4170-3ae9-471d-a506-5d404ccde75e", "name": "Responder solicitud inválida" } ], "pinData": {}, "connections": { "Webhook - Google Calendar": { "main": [ [ { "node": "Preparar solicitud", "type": "main", "index": 0 } ] ] }, "Preparar solicitud": { "main": [ [ { "node": "Solicitud válida", "type": "main", "index": 0 } ] ] }, "Solicitud válida": { "main": [ [ { "node": "Supabase - Obtener obligación y asistentes", "type": "main", "index": 0 } ], [ { "node": "Responder solicitud inválida", "type": "main", "index": 0 } ] ] }, "Supabase - Obtener obligación y asistentes": { "main": [ [ { "node": "Preparar payload Calendar", "type": "main", "index": 0 } ] ] }, "Preparar payload Calendar": { "main": [ [ { "node": "Preparar crear", "type": "main", "index": 0 }, { "node": "Preparar actualizar", "type": "main", "index": 0 }, { "node": "Preparar eliminar", "type": "main", "index": 0 }, { "node": "Preparar sin acción", "type": "main", "index": 0 } ] ] }, "Preparar crear": { "main": [ [ { "node": "Google Calendar - Crear evento", "type": "main", "index": 0 } ] ] }, "Google Calendar - Crear evento": { "main": [ [ { "node": "Preparar registro creado", "type": "main", "index": 0 } ] ] }, "Preparar registro creado": { "main": [ [ { "node": "Supabase - Registrar creación Calendar", "type": "main", "index": 0 } ] ] }, "Supabase - Registrar creación Calendar": { "main": [ [ { "node": "Responder creación", "type": "main", "index": 0 } ] ] }, "Preparar actualizar": { "main": [ [ { "node": "Google Calendar - Actualizar evento", "type": "main", "index": 0 } ] ] }, "Google Calendar - Actualizar evento": { "main": [ [ { "node": "Preparar registro actualizado", "type": "main", "index": 0 } ] ] }, "Preparar registro actualizado": { "main": [ [ { "node": "Supabase - Registrar actualización Calendar", "type": "main", "index": 0 } ] ] }, "Supabase - Registrar actualización Calendar": { "main": [ [ { "node": "Responder actualización", "type": "main", "index": 0 } ] ] }, "Preparar eliminar": { "main": [ [ { "node": "Google Calendar - Eliminar evento", "type": "main", "index": 0 } ] ] }, "Google Calendar - Eliminar evento": { "main": [ [ { "node": "Preparar registro eliminado", "type": "main", "index": 0 } ] ] }, "Preparar registro eliminado": { "main": [ [ { "node": "Supabase - Registrar eliminación Calendar", "type": "main", "index": 0 } ] ] }, "Supabase - Registrar eliminación Calendar": { "main": [ [ { "node": "Responder eliminación", "type": "main", "index": 0 } ] ] }, "Preparar sin acción": { "main": [ [ { "node": "Responder sin acción", "type": "main", "index": 0 } ] ] } }, "active": false, "settings": { "executionOrder": "v1", "timezone": "America/Santo_Domingo", "callerPolicy": "workflowsFromSameOwner" }, "meta": { "templateCredsSetupCompleted": true } }