943 lines
36 KiB
JSON
943 lines
36 KiB
JSON
{
|
|
"updatedAt": "2026-06-05T16:33:58.143Z",
|
|
"createdAt": "2026-05-27T18:36:03.445Z",
|
|
"id": "d39DtIUTQzduqX0v",
|
|
"name": "Tablero CDC - Sync Proyecto a Sheet WEBHOOK",
|
|
"description": null,
|
|
"active": true,
|
|
"isArchived": false,
|
|
"nodes": [
|
|
{
|
|
"parameters": {
|
|
"url": "=https://dbit.digitalcompass.agency/rest/v1/tablero_cdc_projects?id=eq.{{ $('Code - Preparar project_id').first().json.project_id }}&select=*",
|
|
"sendHeaders": true,
|
|
"headerParameters": {
|
|
"parameters": [
|
|
{
|
|
"name": "apikey",
|
|
"value": "=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q"
|
|
},
|
|
{
|
|
"name": "Authorization",
|
|
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q"
|
|
},
|
|
{
|
|
"name": "Accept",
|
|
"value": "application/json"
|
|
},
|
|
{
|
|
"name": "Content-Type",
|
|
"value": "application/json"
|
|
}
|
|
]
|
|
},
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.4,
|
|
"position": [
|
|
608,
|
|
112
|
|
],
|
|
"id": "5fdded5f-5a19-4f40-bc75-21ae92ac3df2",
|
|
"name": "Supabase - Leer proyecto"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"url": "=https://dbit.digitalcompass.agency/rest/v1/tablero_cdc_project_links?project_id=eq.{{ $('Code - Preparar project_id').first().json.project_id }}&select=*&order=created_at.asc",
|
|
"sendHeaders": true,
|
|
"headerParameters": {
|
|
"parameters": [
|
|
{
|
|
"name": "apikey",
|
|
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q"
|
|
},
|
|
{
|
|
"name": "Authorization",
|
|
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q"
|
|
},
|
|
{
|
|
"name": "Accept",
|
|
"value": "application/json"
|
|
},
|
|
{
|
|
"name": "Content-Type",
|
|
"value": "application/json"
|
|
}
|
|
]
|
|
},
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.4,
|
|
"position": [
|
|
816,
|
|
112
|
|
],
|
|
"id": "d2839f2d-af1f-49ab-bfd6-4c3b76f656ad",
|
|
"name": "Supabase - Leer links del proyecto",
|
|
"alwaysOutputData": true
|
|
},
|
|
{
|
|
"parameters": {
|
|
"jsCode": "function getNodeJson(nodeName) {\n try {\n return $(nodeName).first().json;\n } catch (error) {\n return {};\n }\n}\n\nfunction getNodeItems(nodeName) {\n try {\n return $(nodeName).all();\n } catch (error) {\n return [];\n }\n}\n\nfunction normalizeProjectResponse(value) {\n if (Array.isArray(value)) return value[0] || null;\n return value || null;\n}\n\nfunction normalizeLinksResponse(items) {\n const links = [];\n\n for (const item of items) {\n const json = item.json;\n\n if (Array.isArray(json)) {\n links.push(...json);\n } else if (json && typeof json === 'object') {\n links.push(json);\n }\n }\n\n return links.filter(link => link && link.url);\n}\n\nfunction formatMonth(dateValue) {\n const date = dateValue ? new Date(dateValue) : new Date();\n\n if (Number.isNaN(date.getTime())) {\n return '';\n }\n\n return date.toLocaleDateString('es-DO', {\n month: 'long',\n });\n}\n\nfunction formatYear(dateValue) {\n const date = dateValue ? new Date(dateValue) : new Date();\n\n if (Number.isNaN(date.getTime())) {\n return String(new Date().getFullYear());\n }\n\n return String(date.getFullYear());\n}\n\nfunction formatMoney(value) {\n if (value === null || value === undefined || value === '') return '';\n return value;\n}\n\nfunction formatLinks(links, type, prefix) {\n const filtered = links.filter(link => String(link.link_type || '').toLowerCase() === type);\n\n if (!filtered.length) return '';\n\n return filtered\n .map((link, index) => `${prefix}${index + 1}) ${link.url}`)\n .join('\\n');\n}\n\nconst rawProject = getNodeJson('Supabase - Leer proyecto');\nconst project = normalizeProjectResponse(rawProject);\n\nif (!project || !project.id) {\n throw new Error('No se encontró el proyecto en Supabase. Revisa el project_id.');\n}\n\nconst linkItems = getNodeItems('Supabase - Leer links del proyecto');\nconst links = normalizeLinksResponse(linkItems);\n\nconst proposalLinks = formatLinks(links, 'proposal', '');\nconst finalArtLinks = formatLinks(links, 'final_art', 'AF-');\n\nconst createdAt = project.created_at || new Date().toISOString();\n\nreturn [\n {\n json: {\n 'Año': formatYear(createdAt),\n 'Mes': formatMonth(createdAt),\n 'Tipo o nombre de proyecto': project.title || '',\n 'Cliente': project.client || '',\n 'BU Solicita': project.country || '',\n 'Marca': project.brand || '',\n 'CM': project.country_manager || '',\n 'Status': project.status || '',\n 'Comentarios': project.description || '',\n 'Link de propuesta': proposalLinks,\n '$ Interno Cargado': formatMoney(project.internal_amount),\n 'Link del Brief': project.brief_link || '',\n 'Link de artes finales': finalArtLinks,\n 'Project ID': project.id,\n },\n },\n];"
|
|
},
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
1024,
|
|
112
|
|
],
|
|
"id": "1a9e76bd-20f8-481b-82c1-95d631e261ae",
|
|
"name": "Code - Preparar fila Sheet"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"operation": "appendOrUpdate",
|
|
"documentId": {
|
|
"__rl": true,
|
|
"value": "1MfoIs_y7-4ad-g5dxzOo8oAFIdraA_ZT4k-OCGMtT4Q",
|
|
"mode": "list",
|
|
"cachedResultName": "APROBACIONES PROYECTOS",
|
|
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1MfoIs_y7-4ad-g5dxzOo8oAFIdraA_ZT4k-OCGMtT4Q/edit?usp=drivesdk"
|
|
},
|
|
"sheetName": {
|
|
"__rl": true,
|
|
"value": 1563472127,
|
|
"mode": "list",
|
|
"cachedResultName": "PROYECTOS 2026",
|
|
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1MfoIs_y7-4ad-g5dxzOo8oAFIdraA_ZT4k-OCGMtT4Q/edit#gid=1563472127"
|
|
},
|
|
"columns": {
|
|
"mappingMode": "defineBelow",
|
|
"value": {
|
|
"Año": "={{ $json[\"Año\"] }}",
|
|
"Mes": "={{ $json[\"Mes\"] }}",
|
|
"Tipo o nombre de proyecto": "={{ $json[\"Tipo o nombre de proyecto\"] }}",
|
|
"Cliente": "={{ $json[\"Cliente\"] }}",
|
|
"BU Solicita": "={{ $json[\"BU Solicita\"] }}",
|
|
"Marca": "={{ $json[\"Marca\"] }}",
|
|
"CM": "={{ $json[\"CM\"] }}",
|
|
"Status": "={{ $json[\"Status\"] }}",
|
|
"Comentarios": "={{ $json[\"Comentarios\"] }}",
|
|
"Link de propuesta": "={{ $json[\"Link de propuesta\"] }}",
|
|
"$ Interno Cargado": "={{ $json[\"$ Interno Cargado\"] }}",
|
|
"Link del Brief": "={{ $json[\"Link del Brief\"] }}",
|
|
"Link de artes finales": "={{ $json[\"Link de artes finales\"] }}",
|
|
"Project ID": "={{ $json[\"Project ID\"] }}"
|
|
},
|
|
"matchingColumns": [
|
|
"Project ID"
|
|
],
|
|
"schema": [
|
|
{
|
|
"id": "Año",
|
|
"displayName": "Año",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
},
|
|
{
|
|
"id": "Mes",
|
|
"displayName": "Mes",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
},
|
|
{
|
|
"id": "Tipo o nombre de proyecto",
|
|
"displayName": "Tipo o nombre de proyecto",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
},
|
|
{
|
|
"id": "Cliente",
|
|
"displayName": "Cliente",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
},
|
|
{
|
|
"id": "BU Solicita",
|
|
"displayName": "BU Solicita",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
},
|
|
{
|
|
"id": "Marca",
|
|
"displayName": "Marca",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
},
|
|
{
|
|
"id": "CM",
|
|
"displayName": "CM",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
},
|
|
{
|
|
"id": "Status",
|
|
"displayName": "Status",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
},
|
|
{
|
|
"id": "Comentarios",
|
|
"displayName": "Comentarios",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
},
|
|
{
|
|
"id": "Link de propuesta",
|
|
"displayName": "Link de propuesta",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
},
|
|
{
|
|
"id": "$ Interno Cargado",
|
|
"displayName": "$ Interno Cargado",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
},
|
|
{
|
|
"id": "Link del Brief",
|
|
"displayName": "Link del Brief",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
},
|
|
{
|
|
"id": "Link de artes finales",
|
|
"displayName": "Link de artes finales",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
},
|
|
{
|
|
"id": "Project ID",
|
|
"displayName": "Project ID",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
}
|
|
],
|
|
"attemptToConvertTypes": false,
|
|
"convertFieldsToString": false
|
|
},
|
|
"options": {
|
|
"locationDefine": {
|
|
"values": {
|
|
"headerRow": 3,
|
|
"firstDataRow": 4
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"type": "n8n-nodes-base.googleSheets",
|
|
"typeVersion": 4.7,
|
|
"position": [
|
|
1232,
|
|
112
|
|
],
|
|
"id": "d66bf9b4-9694-4f43-8dd6-4e9efe4eece8",
|
|
"name": "Sheets - Upsert proyecto",
|
|
"credentials": {
|
|
"googleSheetsOAuth2Api": {
|
|
"id": "K0hDZh3a85MpOHCs",
|
|
"name": "Google Sheets account 2"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"parameters": {
|
|
"httpMethod": "POST",
|
|
"path": "tablero-cdc-sync-proyecto",
|
|
"responseMode": "responseNode",
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.webhook",
|
|
"typeVersion": 2.1,
|
|
"position": [
|
|
208,
|
|
112
|
|
],
|
|
"id": "b5d0c07b-8b2d-437c-9475-530f64e84247",
|
|
"name": "Webhook",
|
|
"webhookId": "4f237f0a-7607-4a8b-9020-11bc75a6ae32"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"jsCode": "const input = $json || {};\nconst body = input.body || input;\n\nconst projectId =\n body.project_id ||\n body.projectId ||\n body.id ||\n '';\n\nconst action =\n String(body.action || 'sync').trim().toLowerCase();\n\nif (!projectId) {\n throw new Error('Falta project_id en el payload del webhook');\n}\n\nreturn [\n {\n json: {\n action,\n project_id: projectId,\n received_at: new Date().toISOString(),\n },\n },\n];"
|
|
},
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
416,
|
|
112
|
|
],
|
|
"id": "017aafcb-5f7a-407d-8224-caf365186b78",
|
|
"name": "Code - Preparar project_id"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"respondWith": "json",
|
|
"responseBody": "={{\n {\n ok: true,\n message: 'Proyecto sincronizado con Google Sheet',\n project_id: $('Code - Preparar project_id').first().json.project_id\n }\n}}",
|
|
"options": {
|
|
"responseCode": 200
|
|
}
|
|
},
|
|
"type": "n8n-nodes-base.respondToWebhook",
|
|
"typeVersion": 1.5,
|
|
"position": [
|
|
1440,
|
|
112
|
|
],
|
|
"id": "425a3374-03dc-4424-b089-3d86efbd565e",
|
|
"name": "Respond to Webhook"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"content": "Sync Proyecto a Sheet WEBHOOK\n\nFlujo de producción que recibe project_id desde la app Tablero CDC y sincroniza el proyecto con Google Sheet PROYECTOS 2026.\n\nFlujo:\nWebhook -> preparar project_id -> leer projects -> leer project_links -> preparar fila -> upsert en Sheet -> responder webhook.\n\nNotas:\n- La app llama este flujo usando VITE_WEBHOOK_URL.\n- El upsert usa Project ID.\n- Encabezados del Sheet: fila 3.\n- Datos desde fila 4.\n- Filas viejas sin Project ID quedan como histórico.\n- Leer links del proyecto debe tener Always Output Data activo para que proyectos sin links también se peguen.\n\nSi cambia Supabase empresarial/self-hosted, actualizar URL y keys en los HTTP Request.",
|
|
"height": 496,
|
|
"width": 1472
|
|
},
|
|
"type": "n8n-nodes-base.stickyNote",
|
|
"typeVersion": 1,
|
|
"position": [
|
|
160,
|
|
-208
|
|
],
|
|
"id": "16a4a31a-a288-45f5-86fd-be4d92a7a2c1",
|
|
"name": "Sticky Note"
|
|
}
|
|
],
|
|
"connections": {
|
|
"Supabase - Leer proyecto": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Supabase - Leer links del proyecto",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Supabase - Leer links del proyecto": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Code - Preparar fila Sheet",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Code - Preparar fila Sheet": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Sheets - Upsert proyecto",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Webhook": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Code - Preparar project_id",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Code - Preparar project_id": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Supabase - Leer proyecto",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Sheets - Upsert proyecto": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Respond to Webhook",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
}
|
|
},
|
|
"settings": {
|
|
"executionOrder": "v1",
|
|
"binaryMode": "separate",
|
|
"availableInMCP": false,
|
|
"timeSavedMode": "fixed",
|
|
"errorWorkflow": "puF4LUczoSz3hcek",
|
|
"callerPolicy": "workflowsFromSameOwner"
|
|
},
|
|
"staticData": null,
|
|
"meta": {
|
|
"templateCredsSetupCompleted": true
|
|
},
|
|
"versionId": "5702bf85-2a80-4ba8-b24f-9c53612cf7af",
|
|
"activeVersionId": "17638407-8c4f-4070-b040-a23f2750265e",
|
|
"versionCounter": 61,
|
|
"triggerCount": 1,
|
|
"shared": [
|
|
{
|
|
"updatedAt": "2026-05-27T18:36:03.452Z",
|
|
"createdAt": "2026-05-27T18:36:03.452Z",
|
|
"role": "workflow:owner",
|
|
"workflowId": "d39DtIUTQzduqX0v",
|
|
"projectId": "PJpTANzTXIFibWsW",
|
|
"project": {
|
|
"updatedAt": "2026-04-22T14:25:09.686Z",
|
|
"createdAt": "2026-04-22T14:22:54.790Z",
|
|
"id": "PJpTANzTXIFibWsW",
|
|
"name": "Isaac Aracena <iaracena@gomezleemarketing.com>",
|
|
"type": "personal",
|
|
"icon": null,
|
|
"description": null,
|
|
"creatorId": "0a88c0b1-928e-4412-896e-c5d1c99b2029"
|
|
}
|
|
}
|
|
],
|
|
"tags": [],
|
|
"activeVersion": {
|
|
"updatedAt": "2026-06-05T13:32:25.000Z",
|
|
"createdAt": "2026-05-29T23:01:48.396Z",
|
|
"versionId": "17638407-8c4f-4070-b040-a23f2750265e",
|
|
"workflowId": "d39DtIUTQzduqX0v",
|
|
"nodes": [
|
|
{
|
|
"parameters": {
|
|
"url": "=https://dbit.digitalcompass.agency/rest/v1/tablero_cdc_projects?id=eq.{{ $('Code - Preparar project_id').first().json.project_id }}&select=*",
|
|
"sendHeaders": true,
|
|
"headerParameters": {
|
|
"parameters": [
|
|
{
|
|
"name": "apikey",
|
|
"value": "=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q"
|
|
},
|
|
{
|
|
"name": "Authorization",
|
|
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q"
|
|
},
|
|
{
|
|
"name": "Accept",
|
|
"value": "application/json"
|
|
},
|
|
{
|
|
"name": "Content-Type",
|
|
"value": "application/json"
|
|
}
|
|
]
|
|
},
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.4,
|
|
"position": [
|
|
608,
|
|
112
|
|
],
|
|
"id": "5fdded5f-5a19-4f40-bc75-21ae92ac3df2",
|
|
"name": "Supabase - Leer proyecto"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"url": "=https://dbit.digitalcompass.agency/rest/v1/tablero_cdc_project_links?project_id=eq.{{ $('Code - Preparar project_id').first().json.project_id }}&select=*&order=created_at.asc",
|
|
"sendHeaders": true,
|
|
"headerParameters": {
|
|
"parameters": [
|
|
{
|
|
"name": "apikey",
|
|
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q"
|
|
},
|
|
{
|
|
"name": "Authorization",
|
|
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q"
|
|
},
|
|
{
|
|
"name": "Accept",
|
|
"value": "application/json"
|
|
},
|
|
{
|
|
"name": "Content-Type",
|
|
"value": "application/json"
|
|
}
|
|
]
|
|
},
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.4,
|
|
"position": [
|
|
816,
|
|
112
|
|
],
|
|
"id": "d2839f2d-af1f-49ab-bfd6-4c3b76f656ad",
|
|
"name": "Supabase - Leer links del proyecto",
|
|
"alwaysOutputData": true
|
|
},
|
|
{
|
|
"parameters": {
|
|
"jsCode": "function getNodeJson(nodeName) {\n try {\n return $(nodeName).first().json;\n } catch (error) {\n return {};\n }\n}\n\nfunction getNodeItems(nodeName) {\n try {\n return $(nodeName).all();\n } catch (error) {\n return [];\n }\n}\n\nfunction normalizeProjectResponse(value) {\n if (Array.isArray(value)) return value[0] || null;\n return value || null;\n}\n\nfunction normalizeLinksResponse(items) {\n const links = [];\n\n for (const item of items) {\n const json = item.json;\n\n if (Array.isArray(json)) {\n links.push(...json);\n } else if (json && typeof json === 'object') {\n links.push(json);\n }\n }\n\n return links.filter(link => link && link.url);\n}\n\nfunction formatMonth(dateValue) {\n const date = dateValue ? new Date(dateValue) : new Date();\n\n if (Number.isNaN(date.getTime())) {\n return '';\n }\n\n return date.toLocaleDateString('es-DO', {\n month: 'long',\n });\n}\n\nfunction formatYear(dateValue) {\n const date = dateValue ? new Date(dateValue) : new Date();\n\n if (Number.isNaN(date.getTime())) {\n return String(new Date().getFullYear());\n }\n\n return String(date.getFullYear());\n}\n\nfunction formatMoney(value) {\n if (value === null || value === undefined || value === '') return '';\n return value;\n}\n\nfunction formatLinks(links, type, prefix) {\n const filtered = links.filter(link => String(link.link_type || '').toLowerCase() === type);\n\n if (!filtered.length) return '';\n\n return filtered\n .map((link, index) => `${prefix}${index + 1}) ${link.url}`)\n .join('\\n');\n}\n\nconst rawProject = getNodeJson('Supabase - Leer proyecto');\nconst project = normalizeProjectResponse(rawProject);\n\nif (!project || !project.id) {\n throw new Error('No se encontró el proyecto en Supabase. Revisa el project_id.');\n}\n\nconst linkItems = getNodeItems('Supabase - Leer links del proyecto');\nconst links = normalizeLinksResponse(linkItems);\n\nconst proposalLinks = formatLinks(links, 'proposal', '');\nconst finalArtLinks = formatLinks(links, 'final_art', 'AF-');\n\nconst createdAt = project.created_at || new Date().toISOString();\n\nreturn [\n {\n json: {\n 'Año': formatYear(createdAt),\n 'Mes': formatMonth(createdAt),\n 'Tipo o nombre de proyecto': project.title || '',\n 'Cliente': project.client || '',\n 'BU Solicita': project.country || '',\n 'Marca': project.brand || '',\n 'CM': project.country_manager || '',\n 'Status': project.status || '',\n 'Comentarios': project.description || '',\n 'Link de propuesta': proposalLinks,\n '$ Interno Cargado': formatMoney(project.internal_amount),\n 'Link del Brief': project.brief_link || '',\n 'Link de artes finales': finalArtLinks,\n 'Project ID': project.id,\n },\n },\n];"
|
|
},
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
1024,
|
|
112
|
|
],
|
|
"id": "1a9e76bd-20f8-481b-82c1-95d631e261ae",
|
|
"name": "Code - Preparar fila Sheet"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"operation": "appendOrUpdate",
|
|
"documentId": {
|
|
"__rl": true,
|
|
"value": "1MfoIs_y7-4ad-g5dxzOo8oAFIdraA_ZT4k-OCGMtT4Q",
|
|
"mode": "list",
|
|
"cachedResultName": "APROBACIONES PROYECTOS",
|
|
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1MfoIs_y7-4ad-g5dxzOo8oAFIdraA_ZT4k-OCGMtT4Q/edit?usp=drivesdk"
|
|
},
|
|
"sheetName": {
|
|
"__rl": true,
|
|
"value": 1563472127,
|
|
"mode": "list",
|
|
"cachedResultName": "PROYECTOS 2026",
|
|
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1MfoIs_y7-4ad-g5dxzOo8oAFIdraA_ZT4k-OCGMtT4Q/edit#gid=1563472127"
|
|
},
|
|
"columns": {
|
|
"mappingMode": "defineBelow",
|
|
"value": {
|
|
"Año": "={{ $json[\"Año\"] }}",
|
|
"Mes": "={{ $json[\"Mes\"] }}",
|
|
"Tipo o nombre de proyecto": "={{ $json[\"Tipo o nombre de proyecto\"] }}",
|
|
"Cliente": "={{ $json[\"Cliente\"] }}",
|
|
"BU Solicita": "={{ $json[\"BU Solicita\"] }}",
|
|
"Marca": "={{ $json[\"Marca\"] }}",
|
|
"CM": "={{ $json[\"CM\"] }}",
|
|
"Status": "={{ $json[\"Status\"] }}",
|
|
"Comentarios": "={{ $json[\"Comentarios\"] }}",
|
|
"Link de propuesta": "={{ $json[\"Link de propuesta\"] }}",
|
|
"$ Interno Cargado": "={{ $json[\"$ Interno Cargado\"] }}",
|
|
"Link del Brief": "={{ $json[\"Link del Brief\"] }}",
|
|
"Link de artes finales": "={{ $json[\"Link de artes finales\"] }}",
|
|
"Project ID": "={{ $json[\"Project ID\"] }}"
|
|
},
|
|
"matchingColumns": [
|
|
"Project ID"
|
|
],
|
|
"schema": [
|
|
{
|
|
"id": "Año",
|
|
"displayName": "Año",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
},
|
|
{
|
|
"id": "Mes",
|
|
"displayName": "Mes",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
},
|
|
{
|
|
"id": "Tipo o nombre de proyecto",
|
|
"displayName": "Tipo o nombre de proyecto",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
},
|
|
{
|
|
"id": "Cliente",
|
|
"displayName": "Cliente",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
},
|
|
{
|
|
"id": "BU Solicita",
|
|
"displayName": "BU Solicita",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
},
|
|
{
|
|
"id": "Marca",
|
|
"displayName": "Marca",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
},
|
|
{
|
|
"id": "CM",
|
|
"displayName": "CM",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
},
|
|
{
|
|
"id": "Status",
|
|
"displayName": "Status",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
},
|
|
{
|
|
"id": "Comentarios",
|
|
"displayName": "Comentarios",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
},
|
|
{
|
|
"id": "Link de propuesta",
|
|
"displayName": "Link de propuesta",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
},
|
|
{
|
|
"id": "$ Interno Cargado",
|
|
"displayName": "$ Interno Cargado",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
},
|
|
{
|
|
"id": "Link del Brief",
|
|
"displayName": "Link del Brief",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
},
|
|
{
|
|
"id": "Link de artes finales",
|
|
"displayName": "Link de artes finales",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
},
|
|
{
|
|
"id": "Project ID",
|
|
"displayName": "Project ID",
|
|
"required": false,
|
|
"defaultMatch": false,
|
|
"display": true,
|
|
"type": "string",
|
|
"canBeUsedToMatch": true,
|
|
"removed": false
|
|
}
|
|
],
|
|
"attemptToConvertTypes": false,
|
|
"convertFieldsToString": false
|
|
},
|
|
"options": {
|
|
"locationDefine": {
|
|
"values": {
|
|
"headerRow": 3,
|
|
"firstDataRow": 4
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"type": "n8n-nodes-base.googleSheets",
|
|
"typeVersion": 4.7,
|
|
"position": [
|
|
1232,
|
|
112
|
|
],
|
|
"id": "d66bf9b4-9694-4f43-8dd6-4e9efe4eece8",
|
|
"name": "Sheets - Upsert proyecto",
|
|
"credentials": {
|
|
"googleSheetsOAuth2Api": {
|
|
"id": "K0hDZh3a85MpOHCs",
|
|
"name": "Google Sheets account 2"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"parameters": {
|
|
"httpMethod": "POST",
|
|
"path": "tablero-cdc-sync-proyecto",
|
|
"responseMode": "responseNode",
|
|
"options": {}
|
|
},
|
|
"type": "n8n-nodes-base.webhook",
|
|
"typeVersion": 2.1,
|
|
"position": [
|
|
208,
|
|
112
|
|
],
|
|
"id": "b5d0c07b-8b2d-437c-9475-530f64e84247",
|
|
"name": "Webhook",
|
|
"webhookId": "4f237f0a-7607-4a8b-9020-11bc75a6ae32"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"jsCode": "const body = $json.body && typeof $json.body === 'object'\n ? $json.body\n : $json;\n\nconst projectId =\n body.project_id ||\n body.projectId ||\n body.id ||\n '';\n\nif (!projectId) {\n throw new Error('No se recibió project_id en el webhook.');\n}\n\nreturn [\n {\n json: {\n project_id: String(projectId).trim(),\n received_at: new Date().toISOString(),\n },\n },\n];"
|
|
},
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
416,
|
|
112
|
|
],
|
|
"id": "017aafcb-5f7a-407d-8224-caf365186b78",
|
|
"name": "Code - Preparar project_id"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"respondWith": "json",
|
|
"responseBody": "={{\n {\n ok: true,\n message: 'Proyecto sincronizado con Google Sheet',\n project_id: $('Code - Preparar project_id').first().json.project_id\n }\n}}",
|
|
"options": {
|
|
"responseCode": 200
|
|
}
|
|
},
|
|
"type": "n8n-nodes-base.respondToWebhook",
|
|
"typeVersion": 1.5,
|
|
"position": [
|
|
1440,
|
|
112
|
|
],
|
|
"id": "425a3374-03dc-4424-b089-3d86efbd565e",
|
|
"name": "Respond to Webhook"
|
|
},
|
|
{
|
|
"parameters": {
|
|
"content": "Sync Proyecto a Sheet WEBHOOK\n\nFlujo de producción que recibe project_id desde la app Tablero CDC y sincroniza el proyecto con Google Sheet PROYECTOS 2026.\n\nFlujo:\nWebhook -> preparar project_id -> leer projects -> leer project_links -> preparar fila -> upsert en Sheet -> responder webhook.\n\nNotas:\n- La app llama este flujo usando VITE_WEBHOOK_URL.\n- El upsert usa Project ID.\n- Encabezados del Sheet: fila 3.\n- Datos desde fila 4.\n- Filas viejas sin Project ID quedan como histórico.\n- Leer links del proyecto debe tener Always Output Data activo para que proyectos sin links también se peguen.\n\nSi cambia Supabase empresarial/self-hosted, actualizar URL y keys en los HTTP Request.",
|
|
"height": 496,
|
|
"width": 1472
|
|
},
|
|
"type": "n8n-nodes-base.stickyNote",
|
|
"typeVersion": 1,
|
|
"position": [
|
|
160,
|
|
-208
|
|
],
|
|
"id": "16a4a31a-a288-45f5-86fd-be4d92a7a2c1",
|
|
"name": "Sticky Note"
|
|
}
|
|
],
|
|
"connections": {
|
|
"Supabase - Leer proyecto": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Supabase - Leer links del proyecto",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Supabase - Leer links del proyecto": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Code - Preparar fila Sheet",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Code - Preparar fila Sheet": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Sheets - Upsert proyecto",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Webhook": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Code - Preparar project_id",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Code - Preparar project_id": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Supabase - Leer proyecto",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Sheets - Upsert proyecto": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Respond to Webhook",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
}
|
|
},
|
|
"authors": "Isaac Aracena",
|
|
"name": "Tablero CDC - Sync Proyecto a Sheet WWEBHOOK",
|
|
"description": "",
|
|
"autosaved": true,
|
|
"workflowPublishHistory": [
|
|
{
|
|
"createdAt": "2026-05-29T23:03:35.864Z",
|
|
"id": 788,
|
|
"workflowId": "d39DtIUTQzduqX0v",
|
|
"versionId": "17638407-8c4f-4070-b040-a23f2750265e",
|
|
"event": "activated",
|
|
"userId": "0a88c0b1-928e-4412-896e-c5d1c99b2029"
|
|
},
|
|
{
|
|
"createdAt": "2026-06-04T00:43:22.847Z",
|
|
"id": 1082,
|
|
"workflowId": "d39DtIUTQzduqX0v",
|
|
"versionId": "17638407-8c4f-4070-b040-a23f2750265e",
|
|
"event": "activated",
|
|
"userId": "0a88c0b1-928e-4412-896e-c5d1c99b2029"
|
|
},
|
|
{
|
|
"createdAt": "2026-06-05T13:32:25.776Z",
|
|
"id": 1112,
|
|
"workflowId": "d39DtIUTQzduqX0v",
|
|
"versionId": "17638407-8c4f-4070-b040-a23f2750265e",
|
|
"event": "activated",
|
|
"userId": "0a88c0b1-928e-4412-896e-c5d1c99b2029"
|
|
},
|
|
{
|
|
"createdAt": "2026-06-04T00:43:22.817Z",
|
|
"id": 1081,
|
|
"workflowId": "d39DtIUTQzduqX0v",
|
|
"versionId": "17638407-8c4f-4070-b040-a23f2750265e",
|
|
"event": "deactivated",
|
|
"userId": "0a88c0b1-928e-4412-896e-c5d1c99b2029"
|
|
},
|
|
{
|
|
"createdAt": "2026-06-05T13:32:21.145Z",
|
|
"id": 1111,
|
|
"workflowId": "d39DtIUTQzduqX0v",
|
|
"versionId": "17638407-8c4f-4070-b040-a23f2750265e",
|
|
"event": "deactivated",
|
|
"userId": "0a88c0b1-928e-4412-896e-c5d1c99b2029"
|
|
}
|
|
]
|
|
}
|
|
} |