Update backup: Tablero CDC - Refrescar Banco Fulgencio Diario
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"updatedAt": "2026-07-25T17:10:33.663Z",
|
"updatedAt": "2026-07-27T14:23:33.135Z",
|
||||||
"createdAt": "2026-06-16T17:22:11.395Z",
|
"createdAt": "2026-06-16T17:22:11.395Z",
|
||||||
"id": "g2JtKXNz5GDbkmQH",
|
"id": "g2JtKXNz5GDbkmQH",
|
||||||
"name": "Tablero CDC - Refrescar Banco Fulgencio Diario",
|
"name": "Tablero CDC - Refrescar Banco Fulgencio Diario",
|
||||||
@@ -68,7 +68,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"jsCode": "function clean(value) {\n return String(value ?? '').trim();\n}\n\nfunction extractGoogleFileId(url) {\n const text = clean(url);\n\n if (!text) return '';\n\n const patterns = [\n /\\/d\\/([a-zA-Z0-9_-]+)/,\n /id=([a-zA-Z0-9_-]+)/,\n /\\/file\\/d\\/([a-zA-Z0-9_-]+)/,\n /\\/presentation\\/d\\/([a-zA-Z0-9_-]+)/,\n ];\n\n for (const pattern of patterns) {\n const match = text.match(pattern);\n if (match && match[1]) return match[1];\n }\n\n return '';\n}\n\nconst rows = $input.all();\n\nconst result = [];\n\nfor (const item of rows) {\n const row = item.json || {};\n\n const origen = clean(row.tablero_origen);\n const syncKey = clean(row.tablero_sync_key);\n const projectId = clean(row.tablero_project_id);\n const proposalUrl = clean(row['Enlace a la propuesta']);\n const existingFileId = clean(row.file_id);\n const fileId = existingFileId || extractGoogleFileId(proposalUrl);\n\n if (origen !== 'Tablero CDC') continue;\n if (!syncKey) continue;\n if (!projectId) continue;\n if (!proposalUrl) continue;\n\n result.push({\n json: {\n ...row,\n file_id_refresco: fileId,\n proposal_url_refresco: proposalUrl,\n refresh_attempts_actual: Number(row.refresh_attempts || 0),\n },\n });\n}\n\nreturn items;"
|
"jsCode": "function clean(value) {\n return String(value ?? '').trim();\n}\n\nfunction extractGoogleFileId(url) {\n const text = clean(url);\n\n if (!text) return '';\n\n const patterns = [\n /\\/d\\/([a-zA-Z0-9_-]+)/,\n /[?&]id=([a-zA-Z0-9_-]+)/,\n /\\/file\\/d\\/([a-zA-Z0-9_-]+)/,\n /\\/presentation\\/d\\/([a-zA-Z0-9_-]+)/,\n ];\n\n for (const pattern of patterns) {\n const match = text.match(pattern);\n\n if (match?.[1]) {\n return match[1];\n }\n }\n\n return '';\n}\n\nconst rows = $input.all();\nconst result = [];\n\nfor (let index = 0; index < rows.length; index++) {\n const item = rows[index];\n const row = item.json || {};\n\n const origen = clean(row.tablero_origen).toLowerCase();\n const syncKey = clean(row.tablero_sync_key);\n const projectId = clean(row.tablero_project_id);\n const proposalUrl = clean(row['Enlace a la propuesta']);\n\n const existingFileId = clean(row.file_id);\n const extractedFileId = extractGoogleFileId(proposalUrl);\n const fileId = existingFileId || extractedFileId;\n\n // Solo procesar filas válidas provenientes de Tablero CDC.\n if (origen !== 'tablero cdc') continue;\n if (!syncKey) continue;\n if (!projectId) continue;\n if (!proposalUrl) continue;\n\n result.push({\n json: {\n ...row,\n\n // Dejamos ambos campos consistentes.\n file_id: fileId,\n file_id_refresco: fileId,\n\n proposal_url_refresco: proposalUrl,\n refresh_attempts_actual: Number(row.refresh_attempts || 0),\n },\n\n // Conserva la vinculación entre el elemento original y el resultado.\n pairedItem: {\n item: index,\n },\n });\n}\n\nif (result.length === 0) {\n throw new Error(\n 'No se encontraron filas válidas de Tablero CDC con tablero_sync_key, tablero_project_id y enlace.'\n );\n}\n\nreturn result;"
|
||||||
},
|
},
|
||||||
"type": "n8n-nodes-base.code",
|
"type": "n8n-nodes-base.code",
|
||||||
"typeVersion": 2,
|
"typeVersion": 2,
|
||||||
@@ -104,7 +104,7 @@
|
|||||||
"conditions": [
|
"conditions": [
|
||||||
{
|
{
|
||||||
"id": "8c79f0ce-b901-43c8-b863-ad490d267c37",
|
"id": "8c79f0ce-b901-43c8-b863-ad490d267c37",
|
||||||
"leftValue": "={{ $json[\"file_id\"] }}",
|
"leftValue": "={{ String($json.file_id_refresco || $json.file_id || '').trim() }}",
|
||||||
"rightValue": "",
|
"rightValue": "",
|
||||||
"operator": {
|
"operator": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@@ -152,7 +152,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"jsCode": "const original = $('IF - Tiene file_id?').item.json || {};\nconst metadata = $json || {};\n\nfunction clean(value) {\n return String(value ?? '').trim();\n}\n\nfunction toDate(value) {\n const date = value ? new Date(value) : null;\n if (!date || Number.isNaN(date.getTime())) return null;\n return date;\n}\n\nconst driveModifiedTime = clean(metadata.modifiedTime || metadata.modified_time);\nconst lastRefresh = clean(original.ultimo_refresco_ia);\nconst existingDriveModified = clean(original.drive_modified_time);\n\nconst driveDate = toDate(driveModifiedTime);\nconst lastRefreshDate = toDate(lastRefresh);\nconst existingDriveDate = toDate(existingDriveModified);\n\nconst driveSizeBytes = Number(metadata.size || 0);\nconst driveSizeMb = driveSizeBytes ? Number((driveSizeBytes / 1024 / 1024).toFixed(2)) : 0;\n\nlet shouldRefresh = false;\nlet reason = '';\n\nif (!driveDate) {\n shouldRefresh = false;\n reason = 'sin_modified_time';\n} else if (!lastRefreshDate) {\n shouldRefresh = true;\n reason = 'nunca_refrescado';\n} else if (driveDate > lastRefreshDate) {\n shouldRefresh = true;\n reason = 'archivo_modificado_desde_ultimo_refresco';\n} else if (existingDriveDate && driveDate > existingDriveDate) {\n shouldRefresh = true;\n reason = 'drive_modified_time_cambio';\n} else {\n shouldRefresh = false;\n reason = 'sin_cambios';\n}\n\nreturn [\n {\n json: {\n ...original,\n drive_file_id: metadata.id || original.file_id_refresco,\n drive_name: metadata.name || '',\n drive_mime_type: metadata.mimeType || '',\n drive_modified_time_actual: driveModifiedTime,\n drive_size_bytes: driveSizeBytes,\n drive_size_mb: driveSizeMb,\n should_refresh: shouldRefresh,\n refresh_reason: reason,\n },\n },\n];"
|
"jsCode": "const original = $('IF - Tiene file_id?').item.json || {};\nconst metadata = $json || {};\n\nfunction clean(value) {\n return String(value ?? '').trim();\n}\n\nfunction toDate(value) {\n const date = value ? new Date(value) : null;\n\n if (!date || Number.isNaN(date.getTime())) {\n return null;\n }\n\n return date;\n}\n\nconst driveModifiedTime = clean(\n metadata.modifiedTime || metadata.modified_time\n);\n\nconst lastRefresh = clean(original.ultimo_refresco_ia);\nconst existingDriveModified = clean(original.drive_modified_time);\nconst previousStatus = clean(original.refresh_status).toUpperCase();\n\nconst driveDate = toDate(driveModifiedTime);\nconst lastRefreshDate = toDate(lastRefresh);\nconst existingDriveDate = toDate(existingDriveModified);\n\nconst driveSizeBytes = Number(metadata.size || 0);\n\nconst driveSizeMb = driveSizeBytes\n ? Number((driveSizeBytes / 1024 / 1024).toFixed(2))\n : 0;\n\n// Estados que deben volver a intentarse aunque una ejecución anterior\n// haya escrito incorrectamente ultimo_refresco_ia.\nconst retryableStatuses = new Set([\n 'PENDIENTE',\n 'SIN_FILE_ID',\n 'ERROR_METADATA_DRIVE',\n 'ERROR_EXPORT_SLIDES',\n 'ERROR_CONVERT_PPTX',\n 'SIN_CONTENIDO',\n 'PPTX_DEMASIADO_PESADO',\n]);\n\nlet shouldRefresh = false;\nlet reason = '';\n\nif (retryableStatuses.has(previousStatus)) {\n shouldRefresh = true;\n reason = `reintento_estado_${previousStatus.toLowerCase()}`;\n} else if (!driveDate) {\n shouldRefresh = false;\n reason = 'sin_modified_time';\n} else if (!lastRefreshDate) {\n shouldRefresh = true;\n reason = 'nunca_refrescado';\n} else if (driveDate > lastRefreshDate) {\n shouldRefresh = true;\n reason = 'archivo_modificado_desde_ultimo_refresco';\n} else if (existingDriveDate && driveDate > existingDriveDate) {\n shouldRefresh = true;\n reason = 'drive_modified_time_cambio';\n} else {\n shouldRefresh = false;\n reason = 'sin_cambios';\n}\n\nreturn [\n {\n json: {\n ...original,\n\n drive_file_id:\n metadata.id ||\n original.file_id_refresco ||\n original.file_id ||\n '',\n\n drive_name: metadata.name || '',\n drive_mime_type: metadata.mimeType || '',\n drive_modified_time_actual: driveModifiedTime,\n drive_size_bytes: driveSizeBytes,\n drive_size_mb: driveSizeMb,\n\n should_refresh: shouldRefresh,\n refresh_reason: reason,\n },\n },\n];"
|
||||||
},
|
},
|
||||||
"type": "n8n-nodes-base.code",
|
"type": "n8n-nodes-base.code",
|
||||||
"typeVersion": 2,
|
"typeVersion": 2,
|
||||||
@@ -371,7 +371,7 @@
|
|||||||
"columns": {
|
"columns": {
|
||||||
"mappingMode": "defineBelow",
|
"mappingMode": "defineBelow",
|
||||||
"value": {
|
"value": {
|
||||||
"tablero_sync_key": "={{ $json[\"tablero_sync_key\"]}}",
|
"tablero_sync_key": "={{ String($json.tablero_sync_key || '').trim() }}",
|
||||||
"NOMBRE": "={{ $json[\"NOMBRE\"]}}",
|
"NOMBRE": "={{ $json[\"NOMBRE\"]}}",
|
||||||
"TIPO DE ACCION": "={{ $json[\"TIPO DE ACCION\"]}}",
|
"TIPO DE ACCION": "={{ $json[\"TIPO DE ACCION\"]}}",
|
||||||
"CLIENTE": "={{ $json[\"CLIENTE\"]}}",
|
"CLIENTE": "={{ $json[\"CLIENTE\"]}}",
|
||||||
@@ -714,6 +714,8 @@
|
|||||||
],
|
],
|
||||||
"id": "f6487012-88de-4be3-b62e-fa9bdfdda270",
|
"id": "f6487012-88de-4be3-b62e-fa9bdfdda270",
|
||||||
"name": "Google Sheets - Upsert Banco Fulgencio",
|
"name": "Google Sheets - Upsert Banco Fulgencio",
|
||||||
|
"retryOnFail": true,
|
||||||
|
"maxTries": 5,
|
||||||
"credentials": {
|
"credentials": {
|
||||||
"googleSheetsOAuth2Api": {
|
"googleSheetsOAuth2Api": {
|
||||||
"id": "K0hDZh3a85MpOHCs",
|
"id": "K0hDZh3a85MpOHCs",
|
||||||
@@ -723,7 +725,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"jsCode": "const original = $('Code - Preparar texto IA Refresco').item.json || {};\n\nreturn [\n {\n json: {\n ...original,\n drive_modified_time: original.drive_modified_time_actual || original.drive_modified_time || '',\n ultimo_refresco_ia: new Date().toISOString(),\n refresh_status: 'SIN_CONTENIDO',\n refresh_attempts: original.refresh_attempts || 1,\n procesado_ia: false,\n\n converted_google_slides_id: original.converted_google_slides_id || '',\n converted_google_slides_link: original.converted_google_slides_link || '',\n },\n },\n];"
|
"jsCode": "const original = $('Code - Preparar texto IA Refresco').item.json || {};\n\nreturn [\n {\n json: {\n ...original,\n drive_modified_time: original.drive_modified_time_actual || original.drive_modified_time || '',\n ultimo_refresco_ia: original.ultimo_refresco_ia || '',\n ultima_actualizacion: new Date().toISOString(),\n refresh_status: 'SIN_CONTENIDO',\n refresh_attempts: original.refresh_attempts || 1,\n procesado_ia: false,\n\n converted_google_slides_id: original.converted_google_slides_id || '',\n converted_google_slides_link: original.converted_google_slides_link || '',\n },\n },\n];"
|
||||||
},
|
},
|
||||||
"type": "n8n-nodes-base.code",
|
"type": "n8n-nodes-base.code",
|
||||||
"typeVersion": 2,
|
"typeVersion": 2,
|
||||||
@@ -749,7 +751,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"jsCode": "const original = $('IF - Tiene file_id?').item.json || {};\nconst errorData = $json || {};\n\nfunction stringifyError(value) {\n try {\n if (typeof value === 'string') return value;\n return JSON.stringify(value).slice(0, 500);\n } catch (error) {\n return String(value).slice(0, 500);\n }\n}\n\nreturn [\n {\n json: {\n ...original,\n drive_modified_time: original.drive_modified_time || '',\n ultimo_refresco_ia: new Date().toISOString(),\n refresh_status: 'ERROR_METADATA_DRIVE',\n refresh_attempts: Number(original.refresh_attempts_actual || original.refresh_attempts || 0) + 1,\n procesado_ia: false,\n motivos_revision: `error_metadata_drive: ${stringifyError(errorData)}`,\n\n converted_google_slides_id: original.converted_google_slides_id || '',\n converted_google_slides_link: original.converted_google_slides_link || '',\n },\n },\n];"
|
"jsCode": "const original = $('IF - Tiene file_id?').item.json || {};\nconst errorData = $json || {};\n\nfunction stringifyError(value) {\n try {\n if (typeof value === 'string') return value;\n return JSON.stringify(value).slice(0, 500);\n } catch (error) {\n return String(value).slice(0, 500);\n }\n}\n\nreturn [\n {\n json: {\n ...original,\n drive_modified_time: original.drive_modified_time || '',\n ultimo_refresco_ia: original.ultimo_refresco_ia || '',\n ultima_actualizacion: new Date().toISOString(),\n refresh_status: 'ERROR_METADATA_DRIVE',\n refresh_attempts: Number(original.refresh_attempts_actual || original.refresh_attempts || 0) + 1,\n procesado_ia: false,\n motivos_revision: `error_metadata_drive: ${stringifyError(errorData)}`,\n\n converted_google_slides_id: original.converted_google_slides_id || '',\n converted_google_slides_link: original.converted_google_slides_link || '',\n },\n },\n];"
|
||||||
},
|
},
|
||||||
"type": "n8n-nodes-base.code",
|
"type": "n8n-nodes-base.code",
|
||||||
"typeVersion": 2,
|
"typeVersion": 2,
|
||||||
@@ -762,7 +764,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"jsCode": "function getNodeJson(name) {\n try {\n return $(name).item.json || {};\n } catch (error) {\n return {};\n }\n}\n\nconst evaluated = getNodeJson('Code - Evaluar refresco');\nconst converted = getNodeJson('Code - Preparar ID convertido');\n\nconst original = Object.keys(converted).length ? converted : evaluated;\nconst errorData = $json || {};\n\nfunction stringifyError(value) {\n try {\n if (typeof value === 'string') return value;\n return JSON.stringify(value).slice(0, 500);\n } catch (error) {\n return String(value).slice(0, 500);\n }\n}\n\nreturn [\n {\n json: {\n ...original,\n drive_modified_time: original.drive_modified_time_actual || original.drive_modified_time || '',\n ultimo_refresco_ia: new Date().toISOString(),\n refresh_status: 'ERROR_EXPORT_SLIDES',\n refresh_attempts: Number(original.refresh_attempts_actual || original.refresh_attempts || 0) + 1,\n procesado_ia: false,\n motivos_revision: `error_export_slides: ${stringifyError(errorData)}`,\n\n converted_google_slides_id: original.converted_google_slides_id || '',\n converted_google_slides_link: original.converted_google_slides_link || '',\n },\n },\n];"
|
"jsCode": "function getNodeJson(name) {\n try {\n return $(name).item.json || {};\n } catch (error) {\n return {};\n }\n}\n\nconst evaluated = getNodeJson('Code - Evaluar refresco');\nconst converted = getNodeJson('Code - Preparar ID convertido');\n\nconst original = Object.keys(converted).length ? converted : evaluated;\nconst errorData = $json || {};\n\nfunction stringifyError(value) {\n try {\n if (typeof value === 'string') return value;\n return JSON.stringify(value).slice(0, 500);\n } catch (error) {\n return String(value).slice(0, 500);\n }\n}\n\nreturn [\n {\n json: {\n ...original,\n drive_modified_time: original.drive_modified_time_actual || original.drive_modified_time || '',\n ultimo_refresco_ia: original.ultimo_refresco_ia || '',\n ultima_actualizacion: new Date().toISOString(),\n refresh_status: 'ERROR_EXPORT_SLIDES',\n refresh_attempts: Number(original.refresh_attempts_actual || original.refresh_attempts || 0) + 1,\n procesado_ia: false,\n motivos_revision: `error_export_slides: ${stringifyError(errorData)}`,\n\n converted_google_slides_id: original.converted_google_slides_id || '',\n converted_google_slides_link: original.converted_google_slides_link || '',\n },\n },\n];"
|
||||||
},
|
},
|
||||||
"type": "n8n-nodes-base.code",
|
"type": "n8n-nodes-base.code",
|
||||||
"typeVersion": 2,
|
"typeVersion": 2,
|
||||||
@@ -849,7 +851,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"jsCode": "const original = $('IF - Es Google Slides nativo?').item.json || {};\nconst response = $json || {};\n\nfunction clean(value) {\n return String(value ?? '').trim();\n}\n\nif (!response.ok || !response.converted_google_slides_id) {\n return [\n {\n json: {\n ...original,\n drive_modified_time: original.drive_modified_time_actual || original.drive_modified_time || '',\n ultimo_refresco_ia: new Date().toISOString(),\n refresh_status: 'ERROR_CONVERT_PPTX',\n refresh_attempts: Number(original.refresh_attempts_actual || original.refresh_attempts || 0) + 1,\n procesado_ia: false,\n motivos_revision: `error_convert_pptx: ${clean(response.error || JSON.stringify(response)).slice(0, 300)}`,\n },\n },\n ];\n}\n\nreturn [\n {\n json: {\n ...original,\n\n drive_file_id_original: original.drive_file_id || original.file_id_refresco || '',\n drive_file_id: response.converted_google_slides_id,\n drive_mime_type: 'application/vnd.google-apps.presentation',\n\n converted_google_slides_id: response.converted_google_slides_id,\n converted_google_slides_link: response.converted_google_slides_link,\n\n refresh_status: 'CONVERTIDO_PPTX',\n },\n },\n];"
|
"jsCode": "const original = $('IF - Es Google Slides nativo?').item.json || {};\nconst response = $json || {};\n\nfunction clean(value) {\n return String(value ?? '').trim();\n}\n\nif (!response.ok || !response.converted_google_slides_id) {\n return [\n {\n json: {\n ...original,\n drive_modified_time: original.drive_modified_time_actual || original.drive_modified_time || '',\n ultimo_refresco_ia: original.ultimo_refresco_ia || '',\n ultima_actualizacion: new Date().toISOString(),\n refresh_status: 'ERROR_CONVERT_PPTX',\n refresh_attempts: Number(original.refresh_attempts_actual || original.refresh_attempts || 0) + 1,\n procesado_ia: false,\n motivos_revision: `error_convert_pptx: ${clean(response.error || JSON.stringify(response)).slice(0, 300)}`,\n },\n },\n ];\n}\n\nreturn [\n {\n json: {\n ...original,\n\n drive_file_id_original: original.drive_file_id || original.file_id_refresco || '',\n drive_file_id: response.converted_google_slides_id,\n drive_mime_type: 'application/vnd.google-apps.presentation',\n\n converted_google_slides_id: response.converted_google_slides_id,\n converted_google_slides_link: response.converted_google_slides_link,\n\n refresh_status: 'CONVERTIDO_PPTX',\n },\n },\n];"
|
||||||
},
|
},
|
||||||
"type": "n8n-nodes-base.code",
|
"type": "n8n-nodes-base.code",
|
||||||
"typeVersion": 2,
|
"typeVersion": 2,
|
||||||
@@ -928,7 +930,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"jsCode": "const original = $json || {};\n\nreturn [\n {\n json: {\n ...original,\n drive_modified_time: original.drive_modified_time_actual || original.drive_modified_time || '',\n ultimo_refresco_ia: new Date().toISOString(),\n refresh_status: 'PPTX_DEMASIADO_PESADO',\n refresh_attempts: Number(original.refresh_attempts_actual || original.refresh_attempts || 0) + 1,\n procesado_ia: false,\n motivos_revision: `pptx_demasiado_pesado_para_conversion_google_slides: ${original.drive_size_mb || 0} MB. Google Slides solo permite convertir presentaciones hasta 100 MB.`,\n\n converted_google_slides_id: original.converted_google_slides_id || '',\n converted_google_slides_link: original.converted_google_slides_link || '',\n },\n },\n];"
|
"jsCode": "const original = $json || {};\n\nreturn [\n {\n json: {\n ...original,\n drive_modified_time: original.drive_modified_time_actual || original.drive_modified_time || '',\n ultimo_refresco_ia: original.ultimo_refresco_ia || '',\n ultima_actualizacion: new Date().toISOString(),\n refresh_status: 'PPTX_DEMASIADO_PESADO',\n refresh_attempts: Number(original.refresh_attempts_actual || original.refresh_attempts || 0) + 1,\n procesado_ia: false,\n motivos_revision: `pptx_demasiado_pesado_para_conversion_google_slides: ${original.drive_size_mb || 0} MB. Google Slides solo permite convertir presentaciones hasta 100 MB.`,\n\n converted_google_slides_id: original.converted_google_slides_id || '',\n converted_google_slides_link: original.converted_google_slides_link || '',\n },\n },\n];"
|
||||||
},
|
},
|
||||||
"type": "n8n-nodes-base.code",
|
"type": "n8n-nodes-base.code",
|
||||||
"typeVersion": 2,
|
"typeVersion": 2,
|
||||||
@@ -1002,6 +1004,54 @@
|
|||||||
],
|
],
|
||||||
"id": "fc72547c-317e-4ac7-9428-825e8504f143",
|
"id": "fc72547c-317e-4ac7-9428-825e8504f143",
|
||||||
"name": "Sticky Note3"
|
"name": "Sticky Note3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"conditions": {
|
||||||
|
"options": {
|
||||||
|
"caseSensitive": true,
|
||||||
|
"leftValue": "",
|
||||||
|
"typeValidation": "strict",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"id": "cb44c645-00ba-43c1-a8f0-2fe556ebc382",
|
||||||
|
"leftValue": "={{ String($json.tablero_sync_key || '').trim() }}",
|
||||||
|
"rightValue": "",
|
||||||
|
"operator": {
|
||||||
|
"type": "string",
|
||||||
|
"operation": "notEmpty",
|
||||||
|
"singleValue": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"combinator": "and"
|
||||||
|
},
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.if",
|
||||||
|
"typeVersion": 2.3,
|
||||||
|
"position": [
|
||||||
|
5024,
|
||||||
|
112
|
||||||
|
],
|
||||||
|
"id": "1b56b546-c4af-412d-bef8-8105eb830ae1",
|
||||||
|
"name": "IF - Tiene sync key antes de Upsert?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"amount": 4
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.wait",
|
||||||
|
"typeVersion": 1.1,
|
||||||
|
"position": [
|
||||||
|
2768,
|
||||||
|
432
|
||||||
|
],
|
||||||
|
"id": "be090d5c-6fb6-4087-b25b-83fb8e3a3392",
|
||||||
|
"name": "Wait - Respetar cuota Google Sheets",
|
||||||
|
"webhookId": "8b997d7c-097c-4c8a-8793-6bce3db5e142"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"connections": {
|
"connections": {
|
||||||
@@ -1188,7 +1238,7 @@
|
|||||||
"main": [
|
"main": [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"node": "Google Sheets - Upsert Banco Fulgencio",
|
"node": "IF - Tiene sync key antes de Upsert?",
|
||||||
"type": "main",
|
"type": "main",
|
||||||
"index": 0
|
"index": 0
|
||||||
}
|
}
|
||||||
@@ -1199,7 +1249,7 @@
|
|||||||
"main": [
|
"main": [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"node": "Google Sheets - Upsert Banco Fulgencio",
|
"node": "IF - Tiene sync key antes de Upsert?",
|
||||||
"type": "main",
|
"type": "main",
|
||||||
"index": 0
|
"index": 0
|
||||||
}
|
}
|
||||||
@@ -1210,7 +1260,7 @@
|
|||||||
"main": [
|
"main": [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"node": "Loop - Filas Banco Fulgencio",
|
"node": "Wait - Respetar cuota Google Sheets",
|
||||||
"type": "main",
|
"type": "main",
|
||||||
"index": 0
|
"index": 0
|
||||||
}
|
}
|
||||||
@@ -1221,7 +1271,7 @@
|
|||||||
"main": [
|
"main": [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"node": "Google Sheets - Upsert Banco Fulgencio",
|
"node": "IF - Tiene sync key antes de Upsert?",
|
||||||
"type": "main",
|
"type": "main",
|
||||||
"index": 0
|
"index": 0
|
||||||
}
|
}
|
||||||
@@ -1232,7 +1282,7 @@
|
|||||||
"main": [
|
"main": [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"node": "Google Sheets - Upsert Banco Fulgencio",
|
"node": "IF - Tiene sync key antes de Upsert?",
|
||||||
"type": "main",
|
"type": "main",
|
||||||
"index": 0
|
"index": 0
|
||||||
}
|
}
|
||||||
@@ -1243,7 +1293,7 @@
|
|||||||
"main": [
|
"main": [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"node": "Google Sheets - Upsert Banco Fulgencio",
|
"node": "IF - Tiene sync key antes de Upsert?",
|
||||||
"type": "main",
|
"type": "main",
|
||||||
"index": 0
|
"index": 0
|
||||||
}
|
}
|
||||||
@@ -1301,7 +1351,7 @@
|
|||||||
],
|
],
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"node": "Google Sheets - Upsert Banco Fulgencio",
|
"node": "IF - Tiene sync key antes de Upsert?",
|
||||||
"type": "main",
|
"type": "main",
|
||||||
"index": 0
|
"index": 0
|
||||||
}
|
}
|
||||||
@@ -1327,6 +1377,17 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"Code - Marcar PPTX demasiado pesado": {
|
"Code - Marcar PPTX demasiado pesado": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "IF - Tiene sync key antes de Upsert?",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"IF - Tiene sync key antes de Upsert?": {
|
||||||
"main": [
|
"main": [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
@@ -1334,6 +1395,24 @@
|
|||||||
"type": "main",
|
"type": "main",
|
||||||
"index": 0
|
"index": 0
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Loop - Filas Banco Fulgencio",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Wait - Respetar cuota Google Sheets": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Loop - Filas Banco Fulgencio",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1355,9 +1434,9 @@
|
|||||||
"meta": {
|
"meta": {
|
||||||
"templateCredsSetupCompleted": true
|
"templateCredsSetupCompleted": true
|
||||||
},
|
},
|
||||||
"versionId": "a92fd2c1-b300-4def-8cd7-fdb0bde1bdfe",
|
"versionId": "db8caedf-99e0-4c41-b43a-4b115621fb4a",
|
||||||
"activeVersionId": "a92fd2c1-b300-4def-8cd7-fdb0bde1bdfe",
|
"activeVersionId": "db8caedf-99e0-4c41-b43a-4b115621fb4a",
|
||||||
"versionCounter": 435,
|
"versionCounter": 499,
|
||||||
"triggerCount": 1,
|
"triggerCount": 1,
|
||||||
"shared": [
|
"shared": [
|
||||||
{
|
{
|
||||||
@@ -1380,9 +1459,9 @@
|
|||||||
],
|
],
|
||||||
"tags": [],
|
"tags": [],
|
||||||
"activeVersion": {
|
"activeVersion": {
|
||||||
"updatedAt": "2026-07-22T14:43:58.000Z",
|
"updatedAt": "2026-07-27T14:23:46.000Z",
|
||||||
"createdAt": "2026-07-22T14:43:55.809Z",
|
"createdAt": "2026-07-27T14:23:33.139Z",
|
||||||
"versionId": "a92fd2c1-b300-4def-8cd7-fdb0bde1bdfe",
|
"versionId": "db8caedf-99e0-4c41-b43a-4b115621fb4a",
|
||||||
"workflowId": "g2JtKXNz5GDbkmQH",
|
"workflowId": "g2JtKXNz5GDbkmQH",
|
||||||
"nodes": [
|
"nodes": [
|
||||||
{
|
{
|
||||||
@@ -1446,7 +1525,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"jsCode": "function clean(value) {\n return String(value ?? '').trim();\n}\n\nfunction extractGoogleFileId(url) {\n const text = clean(url);\n\n if (!text) return '';\n\n const patterns = [\n /\\/d\\/([a-zA-Z0-9_-]+)/,\n /id=([a-zA-Z0-9_-]+)/,\n /\\/file\\/d\\/([a-zA-Z0-9_-]+)/,\n /\\/presentation\\/d\\/([a-zA-Z0-9_-]+)/,\n ];\n\n for (const pattern of patterns) {\n const match = text.match(pattern);\n if (match && match[1]) return match[1];\n }\n\n return '';\n}\n\nconst rows = $input.all();\n\nconst result = [];\n\nfor (const item of rows) {\n const row = item.json || {};\n\n const origen = clean(row.tablero_origen);\n const syncKey = clean(row.tablero_sync_key);\n const projectId = clean(row.tablero_project_id);\n const proposalUrl = clean(row['Enlace a la propuesta']);\n const existingFileId = clean(row.file_id);\n const fileId = existingFileId || extractGoogleFileId(proposalUrl);\n\n if (origen !== 'Tablero CDC') continue;\n if (!syncKey) continue;\n if (!projectId) continue;\n if (!proposalUrl) continue;\n\n result.push({\n json: {\n ...row,\n file_id_refresco: fileId,\n proposal_url_refresco: proposalUrl,\n refresh_attempts_actual: Number(row.refresh_attempts || 0),\n },\n });\n}\n\nreturn items;"
|
"jsCode": "function clean(value) {\n return String(value ?? '').trim();\n}\n\nfunction extractGoogleFileId(url) {\n const text = clean(url);\n\n if (!text) return '';\n\n const patterns = [\n /\\/d\\/([a-zA-Z0-9_-]+)/,\n /[?&]id=([a-zA-Z0-9_-]+)/,\n /\\/file\\/d\\/([a-zA-Z0-9_-]+)/,\n /\\/presentation\\/d\\/([a-zA-Z0-9_-]+)/,\n ];\n\n for (const pattern of patterns) {\n const match = text.match(pattern);\n\n if (match?.[1]) {\n return match[1];\n }\n }\n\n return '';\n}\n\nconst rows = $input.all();\nconst result = [];\n\nfor (let index = 0; index < rows.length; index++) {\n const item = rows[index];\n const row = item.json || {};\n\n const origen = clean(row.tablero_origen).toLowerCase();\n const syncKey = clean(row.tablero_sync_key);\n const projectId = clean(row.tablero_project_id);\n const proposalUrl = clean(row['Enlace a la propuesta']);\n\n const existingFileId = clean(row.file_id);\n const extractedFileId = extractGoogleFileId(proposalUrl);\n const fileId = existingFileId || extractedFileId;\n\n // Solo procesar filas válidas provenientes de Tablero CDC.\n if (origen !== 'tablero cdc') continue;\n if (!syncKey) continue;\n if (!projectId) continue;\n if (!proposalUrl) continue;\n\n result.push({\n json: {\n ...row,\n\n // Dejamos ambos campos consistentes.\n file_id: fileId,\n file_id_refresco: fileId,\n\n proposal_url_refresco: proposalUrl,\n refresh_attempts_actual: Number(row.refresh_attempts || 0),\n },\n\n // Conserva la vinculación entre el elemento original y el resultado.\n pairedItem: {\n item: index,\n },\n });\n}\n\nif (result.length === 0) {\n throw new Error(\n 'No se encontraron filas válidas de Tablero CDC con tablero_sync_key, tablero_project_id y enlace.'\n );\n}\n\nreturn result;"
|
||||||
},
|
},
|
||||||
"type": "n8n-nodes-base.code",
|
"type": "n8n-nodes-base.code",
|
||||||
"typeVersion": 2,
|
"typeVersion": 2,
|
||||||
@@ -1482,7 +1561,7 @@
|
|||||||
"conditions": [
|
"conditions": [
|
||||||
{
|
{
|
||||||
"id": "8c79f0ce-b901-43c8-b863-ad490d267c37",
|
"id": "8c79f0ce-b901-43c8-b863-ad490d267c37",
|
||||||
"leftValue": "={{ $json[\"file_id\"] }}",
|
"leftValue": "={{ String($json.file_id_refresco || $json.file_id || '').trim() }}",
|
||||||
"rightValue": "",
|
"rightValue": "",
|
||||||
"operator": {
|
"operator": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@@ -1530,7 +1609,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"jsCode": "const original = $('IF - Tiene file_id?').item.json || {};\nconst metadata = $json || {};\n\nfunction clean(value) {\n return String(value ?? '').trim();\n}\n\nfunction toDate(value) {\n const date = value ? new Date(value) : null;\n if (!date || Number.isNaN(date.getTime())) return null;\n return date;\n}\n\nconst driveModifiedTime = clean(metadata.modifiedTime || metadata.modified_time);\nconst lastRefresh = clean(original.ultimo_refresco_ia);\nconst existingDriveModified = clean(original.drive_modified_time);\n\nconst driveDate = toDate(driveModifiedTime);\nconst lastRefreshDate = toDate(lastRefresh);\nconst existingDriveDate = toDate(existingDriveModified);\n\nconst driveSizeBytes = Number(metadata.size || 0);\nconst driveSizeMb = driveSizeBytes ? Number((driveSizeBytes / 1024 / 1024).toFixed(2)) : 0;\n\nlet shouldRefresh = false;\nlet reason = '';\n\nif (!driveDate) {\n shouldRefresh = false;\n reason = 'sin_modified_time';\n} else if (!lastRefreshDate) {\n shouldRefresh = true;\n reason = 'nunca_refrescado';\n} else if (driveDate > lastRefreshDate) {\n shouldRefresh = true;\n reason = 'archivo_modificado_desde_ultimo_refresco';\n} else if (existingDriveDate && driveDate > existingDriveDate) {\n shouldRefresh = true;\n reason = 'drive_modified_time_cambio';\n} else {\n shouldRefresh = false;\n reason = 'sin_cambios';\n}\n\nreturn [\n {\n json: {\n ...original,\n drive_file_id: metadata.id || original.file_id_refresco,\n drive_name: metadata.name || '',\n drive_mime_type: metadata.mimeType || '',\n drive_modified_time_actual: driveModifiedTime,\n drive_size_bytes: driveSizeBytes,\n drive_size_mb: driveSizeMb,\n should_refresh: shouldRefresh,\n refresh_reason: reason,\n },\n },\n];"
|
"jsCode": "const original = $('IF - Tiene file_id?').item.json || {};\nconst metadata = $json || {};\n\nfunction clean(value) {\n return String(value ?? '').trim();\n}\n\nfunction toDate(value) {\n const date = value ? new Date(value) : null;\n\n if (!date || Number.isNaN(date.getTime())) {\n return null;\n }\n\n return date;\n}\n\nconst driveModifiedTime = clean(\n metadata.modifiedTime || metadata.modified_time\n);\n\nconst lastRefresh = clean(original.ultimo_refresco_ia);\nconst existingDriveModified = clean(original.drive_modified_time);\nconst previousStatus = clean(original.refresh_status).toUpperCase();\n\nconst driveDate = toDate(driveModifiedTime);\nconst lastRefreshDate = toDate(lastRefresh);\nconst existingDriveDate = toDate(existingDriveModified);\n\nconst driveSizeBytes = Number(metadata.size || 0);\n\nconst driveSizeMb = driveSizeBytes\n ? Number((driveSizeBytes / 1024 / 1024).toFixed(2))\n : 0;\n\n// Estados que deben volver a intentarse aunque una ejecución anterior\n// haya escrito incorrectamente ultimo_refresco_ia.\nconst retryableStatuses = new Set([\n 'PENDIENTE',\n 'SIN_FILE_ID',\n 'ERROR_METADATA_DRIVE',\n 'ERROR_EXPORT_SLIDES',\n 'ERROR_CONVERT_PPTX',\n 'SIN_CONTENIDO',\n 'PPTX_DEMASIADO_PESADO',\n]);\n\nlet shouldRefresh = false;\nlet reason = '';\n\nif (retryableStatuses.has(previousStatus)) {\n shouldRefresh = true;\n reason = `reintento_estado_${previousStatus.toLowerCase()}`;\n} else if (!driveDate) {\n shouldRefresh = false;\n reason = 'sin_modified_time';\n} else if (!lastRefreshDate) {\n shouldRefresh = true;\n reason = 'nunca_refrescado';\n} else if (driveDate > lastRefreshDate) {\n shouldRefresh = true;\n reason = 'archivo_modificado_desde_ultimo_refresco';\n} else if (existingDriveDate && driveDate > existingDriveDate) {\n shouldRefresh = true;\n reason = 'drive_modified_time_cambio';\n} else {\n shouldRefresh = false;\n reason = 'sin_cambios';\n}\n\nreturn [\n {\n json: {\n ...original,\n\n drive_file_id:\n metadata.id ||\n original.file_id_refresco ||\n original.file_id ||\n '',\n\n drive_name: metadata.name || '',\n drive_mime_type: metadata.mimeType || '',\n drive_modified_time_actual: driveModifiedTime,\n drive_size_bytes: driveSizeBytes,\n drive_size_mb: driveSizeMb,\n\n should_refresh: shouldRefresh,\n refresh_reason: reason,\n },\n },\n];"
|
||||||
},
|
},
|
||||||
"type": "n8n-nodes-base.code",
|
"type": "n8n-nodes-base.code",
|
||||||
"typeVersion": 2,
|
"typeVersion": 2,
|
||||||
@@ -1749,7 +1828,7 @@
|
|||||||
"columns": {
|
"columns": {
|
||||||
"mappingMode": "defineBelow",
|
"mappingMode": "defineBelow",
|
||||||
"value": {
|
"value": {
|
||||||
"tablero_sync_key": "={{ $json[\"tablero_sync_key\"]}}",
|
"tablero_sync_key": "={{ String($json.tablero_sync_key || '').trim() }}",
|
||||||
"NOMBRE": "={{ $json[\"NOMBRE\"]}}",
|
"NOMBRE": "={{ $json[\"NOMBRE\"]}}",
|
||||||
"TIPO DE ACCION": "={{ $json[\"TIPO DE ACCION\"]}}",
|
"TIPO DE ACCION": "={{ $json[\"TIPO DE ACCION\"]}}",
|
||||||
"CLIENTE": "={{ $json[\"CLIENTE\"]}}",
|
"CLIENTE": "={{ $json[\"CLIENTE\"]}}",
|
||||||
@@ -2092,6 +2171,8 @@
|
|||||||
],
|
],
|
||||||
"id": "f6487012-88de-4be3-b62e-fa9bdfdda270",
|
"id": "f6487012-88de-4be3-b62e-fa9bdfdda270",
|
||||||
"name": "Google Sheets - Upsert Banco Fulgencio",
|
"name": "Google Sheets - Upsert Banco Fulgencio",
|
||||||
|
"retryOnFail": true,
|
||||||
|
"maxTries": 5,
|
||||||
"credentials": {
|
"credentials": {
|
||||||
"googleSheetsOAuth2Api": {
|
"googleSheetsOAuth2Api": {
|
||||||
"id": "K0hDZh3a85MpOHCs",
|
"id": "K0hDZh3a85MpOHCs",
|
||||||
@@ -2101,7 +2182,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"jsCode": "const original = $('Code - Preparar texto IA Refresco').item.json || {};\n\nreturn [\n {\n json: {\n ...original,\n drive_modified_time: original.drive_modified_time_actual || original.drive_modified_time || '',\n ultimo_refresco_ia: new Date().toISOString(),\n refresh_status: 'SIN_CONTENIDO',\n refresh_attempts: original.refresh_attempts || 1,\n procesado_ia: false,\n\n converted_google_slides_id: original.converted_google_slides_id || '',\n converted_google_slides_link: original.converted_google_slides_link || '',\n },\n },\n];"
|
"jsCode": "const original = $('Code - Preparar texto IA Refresco').item.json || {};\n\nreturn [\n {\n json: {\n ...original,\n drive_modified_time: original.drive_modified_time_actual || original.drive_modified_time || '',\n ultimo_refresco_ia: original.ultimo_refresco_ia || '',\n ultima_actualizacion: new Date().toISOString(),\n refresh_status: 'SIN_CONTENIDO',\n refresh_attempts: original.refresh_attempts || 1,\n procesado_ia: false,\n\n converted_google_slides_id: original.converted_google_slides_id || '',\n converted_google_slides_link: original.converted_google_slides_link || '',\n },\n },\n];"
|
||||||
},
|
},
|
||||||
"type": "n8n-nodes-base.code",
|
"type": "n8n-nodes-base.code",
|
||||||
"typeVersion": 2,
|
"typeVersion": 2,
|
||||||
@@ -2127,7 +2208,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"jsCode": "const original = $('IF - Tiene file_id?').item.json || {};\nconst errorData = $json || {};\n\nfunction stringifyError(value) {\n try {\n if (typeof value === 'string') return value;\n return JSON.stringify(value).slice(0, 500);\n } catch (error) {\n return String(value).slice(0, 500);\n }\n}\n\nreturn [\n {\n json: {\n ...original,\n drive_modified_time: original.drive_modified_time || '',\n ultimo_refresco_ia: new Date().toISOString(),\n refresh_status: 'ERROR_METADATA_DRIVE',\n refresh_attempts: Number(original.refresh_attempts_actual || original.refresh_attempts || 0) + 1,\n procesado_ia: false,\n motivos_revision: `error_metadata_drive: ${stringifyError(errorData)}`,\n\n converted_google_slides_id: original.converted_google_slides_id || '',\n converted_google_slides_link: original.converted_google_slides_link || '',\n },\n },\n];"
|
"jsCode": "const original = $('IF - Tiene file_id?').item.json || {};\nconst errorData = $json || {};\n\nfunction stringifyError(value) {\n try {\n if (typeof value === 'string') return value;\n return JSON.stringify(value).slice(0, 500);\n } catch (error) {\n return String(value).slice(0, 500);\n }\n}\n\nreturn [\n {\n json: {\n ...original,\n drive_modified_time: original.drive_modified_time || '',\n ultimo_refresco_ia: original.ultimo_refresco_ia || '',\n ultima_actualizacion: new Date().toISOString(),\n refresh_status: 'ERROR_METADATA_DRIVE',\n refresh_attempts: Number(original.refresh_attempts_actual || original.refresh_attempts || 0) + 1,\n procesado_ia: false,\n motivos_revision: `error_metadata_drive: ${stringifyError(errorData)}`,\n\n converted_google_slides_id: original.converted_google_slides_id || '',\n converted_google_slides_link: original.converted_google_slides_link || '',\n },\n },\n];"
|
||||||
},
|
},
|
||||||
"type": "n8n-nodes-base.code",
|
"type": "n8n-nodes-base.code",
|
||||||
"typeVersion": 2,
|
"typeVersion": 2,
|
||||||
@@ -2140,7 +2221,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"jsCode": "function getNodeJson(name) {\n try {\n return $(name).item.json || {};\n } catch (error) {\n return {};\n }\n}\n\nconst evaluated = getNodeJson('Code - Evaluar refresco');\nconst converted = getNodeJson('Code - Preparar ID convertido');\n\nconst original = Object.keys(converted).length ? converted : evaluated;\nconst errorData = $json || {};\n\nfunction stringifyError(value) {\n try {\n if (typeof value === 'string') return value;\n return JSON.stringify(value).slice(0, 500);\n } catch (error) {\n return String(value).slice(0, 500);\n }\n}\n\nreturn [\n {\n json: {\n ...original,\n drive_modified_time: original.drive_modified_time_actual || original.drive_modified_time || '',\n ultimo_refresco_ia: new Date().toISOString(),\n refresh_status: 'ERROR_EXPORT_SLIDES',\n refresh_attempts: Number(original.refresh_attempts_actual || original.refresh_attempts || 0) + 1,\n procesado_ia: false,\n motivos_revision: `error_export_slides: ${stringifyError(errorData)}`,\n\n converted_google_slides_id: original.converted_google_slides_id || '',\n converted_google_slides_link: original.converted_google_slides_link || '',\n },\n },\n];"
|
"jsCode": "function getNodeJson(name) {\n try {\n return $(name).item.json || {};\n } catch (error) {\n return {};\n }\n}\n\nconst evaluated = getNodeJson('Code - Evaluar refresco');\nconst converted = getNodeJson('Code - Preparar ID convertido');\n\nconst original = Object.keys(converted).length ? converted : evaluated;\nconst errorData = $json || {};\n\nfunction stringifyError(value) {\n try {\n if (typeof value === 'string') return value;\n return JSON.stringify(value).slice(0, 500);\n } catch (error) {\n return String(value).slice(0, 500);\n }\n}\n\nreturn [\n {\n json: {\n ...original,\n drive_modified_time: original.drive_modified_time_actual || original.drive_modified_time || '',\n ultimo_refresco_ia: original.ultimo_refresco_ia || '',\n ultima_actualizacion: new Date().toISOString(),\n refresh_status: 'ERROR_EXPORT_SLIDES',\n refresh_attempts: Number(original.refresh_attempts_actual || original.refresh_attempts || 0) + 1,\n procesado_ia: false,\n motivos_revision: `error_export_slides: ${stringifyError(errorData)}`,\n\n converted_google_slides_id: original.converted_google_slides_id || '',\n converted_google_slides_link: original.converted_google_slides_link || '',\n },\n },\n];"
|
||||||
},
|
},
|
||||||
"type": "n8n-nodes-base.code",
|
"type": "n8n-nodes-base.code",
|
||||||
"typeVersion": 2,
|
"typeVersion": 2,
|
||||||
@@ -2227,7 +2308,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"jsCode": "const original = $('IF - Es Google Slides nativo?').item.json || {};\nconst response = $json || {};\n\nfunction clean(value) {\n return String(value ?? '').trim();\n}\n\nif (!response.ok || !response.converted_google_slides_id) {\n return [\n {\n json: {\n ...original,\n drive_modified_time: original.drive_modified_time_actual || original.drive_modified_time || '',\n ultimo_refresco_ia: new Date().toISOString(),\n refresh_status: 'ERROR_CONVERT_PPTX',\n refresh_attempts: Number(original.refresh_attempts_actual || original.refresh_attempts || 0) + 1,\n procesado_ia: false,\n motivos_revision: `error_convert_pptx: ${clean(response.error || JSON.stringify(response)).slice(0, 300)}`,\n },\n },\n ];\n}\n\nreturn [\n {\n json: {\n ...original,\n\n drive_file_id_original: original.drive_file_id || original.file_id_refresco || '',\n drive_file_id: response.converted_google_slides_id,\n drive_mime_type: 'application/vnd.google-apps.presentation',\n\n converted_google_slides_id: response.converted_google_slides_id,\n converted_google_slides_link: response.converted_google_slides_link,\n\n refresh_status: 'CONVERTIDO_PPTX',\n },\n },\n];"
|
"jsCode": "const original = $('IF - Es Google Slides nativo?').item.json || {};\nconst response = $json || {};\n\nfunction clean(value) {\n return String(value ?? '').trim();\n}\n\nif (!response.ok || !response.converted_google_slides_id) {\n return [\n {\n json: {\n ...original,\n drive_modified_time: original.drive_modified_time_actual || original.drive_modified_time || '',\n ultimo_refresco_ia: original.ultimo_refresco_ia || '',\n ultima_actualizacion: new Date().toISOString(),\n refresh_status: 'ERROR_CONVERT_PPTX',\n refresh_attempts: Number(original.refresh_attempts_actual || original.refresh_attempts || 0) + 1,\n procesado_ia: false,\n motivos_revision: `error_convert_pptx: ${clean(response.error || JSON.stringify(response)).slice(0, 300)}`,\n },\n },\n ];\n}\n\nreturn [\n {\n json: {\n ...original,\n\n drive_file_id_original: original.drive_file_id || original.file_id_refresco || '',\n drive_file_id: response.converted_google_slides_id,\n drive_mime_type: 'application/vnd.google-apps.presentation',\n\n converted_google_slides_id: response.converted_google_slides_id,\n converted_google_slides_link: response.converted_google_slides_link,\n\n refresh_status: 'CONVERTIDO_PPTX',\n },\n },\n];"
|
||||||
},
|
},
|
||||||
"type": "n8n-nodes-base.code",
|
"type": "n8n-nodes-base.code",
|
||||||
"typeVersion": 2,
|
"typeVersion": 2,
|
||||||
@@ -2306,7 +2387,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"jsCode": "const original = $json || {};\n\nreturn [\n {\n json: {\n ...original,\n drive_modified_time: original.drive_modified_time_actual || original.drive_modified_time || '',\n ultimo_refresco_ia: new Date().toISOString(),\n refresh_status: 'PPTX_DEMASIADO_PESADO',\n refresh_attempts: Number(original.refresh_attempts_actual || original.refresh_attempts || 0) + 1,\n procesado_ia: false,\n motivos_revision: `pptx_demasiado_pesado_para_conversion_google_slides: ${original.drive_size_mb || 0} MB. Google Slides solo permite convertir presentaciones hasta 100 MB.`,\n\n converted_google_slides_id: original.converted_google_slides_id || '',\n converted_google_slides_link: original.converted_google_slides_link || '',\n },\n },\n];"
|
"jsCode": "const original = $json || {};\n\nreturn [\n {\n json: {\n ...original,\n drive_modified_time: original.drive_modified_time_actual || original.drive_modified_time || '',\n ultimo_refresco_ia: original.ultimo_refresco_ia || '',\n ultima_actualizacion: new Date().toISOString(),\n refresh_status: 'PPTX_DEMASIADO_PESADO',\n refresh_attempts: Number(original.refresh_attempts_actual || original.refresh_attempts || 0) + 1,\n procesado_ia: false,\n motivos_revision: `pptx_demasiado_pesado_para_conversion_google_slides: ${original.drive_size_mb || 0} MB. Google Slides solo permite convertir presentaciones hasta 100 MB.`,\n\n converted_google_slides_id: original.converted_google_slides_id || '',\n converted_google_slides_link: original.converted_google_slides_link || '',\n },\n },\n];"
|
||||||
},
|
},
|
||||||
"type": "n8n-nodes-base.code",
|
"type": "n8n-nodes-base.code",
|
||||||
"typeVersion": 2,
|
"typeVersion": 2,
|
||||||
@@ -2380,6 +2461,54 @@
|
|||||||
],
|
],
|
||||||
"id": "fc72547c-317e-4ac7-9428-825e8504f143",
|
"id": "fc72547c-317e-4ac7-9428-825e8504f143",
|
||||||
"name": "Sticky Note3"
|
"name": "Sticky Note3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"conditions": {
|
||||||
|
"options": {
|
||||||
|
"caseSensitive": true,
|
||||||
|
"leftValue": "",
|
||||||
|
"typeValidation": "strict",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"id": "cb44c645-00ba-43c1-a8f0-2fe556ebc382",
|
||||||
|
"leftValue": "={{ String($json.tablero_sync_key || '').trim() }}",
|
||||||
|
"rightValue": "",
|
||||||
|
"operator": {
|
||||||
|
"type": "string",
|
||||||
|
"operation": "notEmpty",
|
||||||
|
"singleValue": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"combinator": "and"
|
||||||
|
},
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.if",
|
||||||
|
"typeVersion": 2.3,
|
||||||
|
"position": [
|
||||||
|
5024,
|
||||||
|
112
|
||||||
|
],
|
||||||
|
"id": "1b56b546-c4af-412d-bef8-8105eb830ae1",
|
||||||
|
"name": "IF - Tiene sync key antes de Upsert?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"amount": 4
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.wait",
|
||||||
|
"typeVersion": 1.1,
|
||||||
|
"position": [
|
||||||
|
2768,
|
||||||
|
432
|
||||||
|
],
|
||||||
|
"id": "be090d5c-6fb6-4087-b25b-83fb8e3a3392",
|
||||||
|
"name": "Wait - Respetar cuota Google Sheets",
|
||||||
|
"webhookId": "8b997d7c-097c-4c8a-8793-6bce3db5e142"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"connections": {
|
"connections": {
|
||||||
@@ -2566,7 +2695,7 @@
|
|||||||
"main": [
|
"main": [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"node": "Google Sheets - Upsert Banco Fulgencio",
|
"node": "IF - Tiene sync key antes de Upsert?",
|
||||||
"type": "main",
|
"type": "main",
|
||||||
"index": 0
|
"index": 0
|
||||||
}
|
}
|
||||||
@@ -2577,7 +2706,7 @@
|
|||||||
"main": [
|
"main": [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"node": "Google Sheets - Upsert Banco Fulgencio",
|
"node": "IF - Tiene sync key antes de Upsert?",
|
||||||
"type": "main",
|
"type": "main",
|
||||||
"index": 0
|
"index": 0
|
||||||
}
|
}
|
||||||
@@ -2588,7 +2717,7 @@
|
|||||||
"main": [
|
"main": [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"node": "Loop - Filas Banco Fulgencio",
|
"node": "Wait - Respetar cuota Google Sheets",
|
||||||
"type": "main",
|
"type": "main",
|
||||||
"index": 0
|
"index": 0
|
||||||
}
|
}
|
||||||
@@ -2599,7 +2728,7 @@
|
|||||||
"main": [
|
"main": [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"node": "Google Sheets - Upsert Banco Fulgencio",
|
"node": "IF - Tiene sync key antes de Upsert?",
|
||||||
"type": "main",
|
"type": "main",
|
||||||
"index": 0
|
"index": 0
|
||||||
}
|
}
|
||||||
@@ -2610,7 +2739,7 @@
|
|||||||
"main": [
|
"main": [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"node": "Google Sheets - Upsert Banco Fulgencio",
|
"node": "IF - Tiene sync key antes de Upsert?",
|
||||||
"type": "main",
|
"type": "main",
|
||||||
"index": 0
|
"index": 0
|
||||||
}
|
}
|
||||||
@@ -2621,7 +2750,7 @@
|
|||||||
"main": [
|
"main": [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"node": "Google Sheets - Upsert Banco Fulgencio",
|
"node": "IF - Tiene sync key antes de Upsert?",
|
||||||
"type": "main",
|
"type": "main",
|
||||||
"index": 0
|
"index": 0
|
||||||
}
|
}
|
||||||
@@ -2679,7 +2808,7 @@
|
|||||||
],
|
],
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"node": "Google Sheets - Upsert Banco Fulgencio",
|
"node": "IF - Tiene sync key antes de Upsert?",
|
||||||
"type": "main",
|
"type": "main",
|
||||||
"index": 0
|
"index": 0
|
||||||
}
|
}
|
||||||
@@ -2705,6 +2834,17 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"Code - Marcar PPTX demasiado pesado": {
|
"Code - Marcar PPTX demasiado pesado": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "IF - Tiene sync key antes de Upsert?",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"IF - Tiene sync key antes de Upsert?": {
|
||||||
"main": [
|
"main": [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
@@ -2712,38 +2852,40 @@
|
|||||||
"type": "main",
|
"type": "main",
|
||||||
"index": 0
|
"index": 0
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Loop - Filas Banco Fulgencio",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Wait - Respetar cuota Google Sheets": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Loop - Filas Banco Fulgencio",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"authors": "Isaac Aracena",
|
"authors": "Isaac Aracena",
|
||||||
"name": "Version a92fd2c1",
|
"name": "Version db8caedf",
|
||||||
"description": "",
|
"description": "",
|
||||||
"autosaved": true,
|
"autosaved": true,
|
||||||
"workflowPublishHistory": [
|
"workflowPublishHistory": [
|
||||||
{
|
{
|
||||||
"createdAt": "2026-07-22T14:43:58.310Z",
|
"createdAt": "2026-07-27T14:23:46.606Z",
|
||||||
"id": 3376,
|
"id": 3494,
|
||||||
"workflowId": "g2JtKXNz5GDbkmQH",
|
"workflowId": "g2JtKXNz5GDbkmQH",
|
||||||
"versionId": "a92fd2c1-b300-4def-8cd7-fdb0bde1bdfe",
|
"versionId": "db8caedf-99e0-4c41-b43a-4b115621fb4a",
|
||||||
"event": "activated",
|
"event": "activated",
|
||||||
"userId": "0a88c0b1-928e-4412-896e-c5d1c99b2029"
|
"userId": "0a88c0b1-928e-4412-896e-c5d1c99b2029"
|
||||||
},
|
|
||||||
{
|
|
||||||
"createdAt": "2026-07-25T17:10:33.819Z",
|
|
||||||
"id": 3428,
|
|
||||||
"workflowId": "g2JtKXNz5GDbkmQH",
|
|
||||||
"versionId": "a92fd2c1-b300-4def-8cd7-fdb0bde1bdfe",
|
|
||||||
"event": "activated",
|
|
||||||
"userId": "0a88c0b1-928e-4412-896e-c5d1c99b2029"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"createdAt": "2026-07-25T17:10:33.748Z",
|
|
||||||
"id": 3427,
|
|
||||||
"workflowId": "g2JtKXNz5GDbkmQH",
|
|
||||||
"versionId": "a92fd2c1-b300-4def-8cd7-fdb0bde1bdfe",
|
|
||||||
"event": "deactivated",
|
|
||||||
"userId": "0a88c0b1-928e-4412-896e-c5d1c99b2029"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user