Transferencia automática de archivos de Google Drive a FTP con registro y informes JSON
Este es unFile Management, Miscellaneous, Multimodal AIflujo de automatización del dominio deautomatización que contiene 15 nodos.Utiliza principalmente nodos como If, Ftp, Code, Webhook, EmailSend. Transferencia automatizada de archivos de Google Drive a FTP con registro y reporte de JSON
- •Punto final de HTTP Webhook (n8n generará automáticamente)
- •Credenciales de API de Google Drive
Nodos utilizados (15)
{
"id": "LJmjAaP6VnaYVBF9",
"meta": {
"instanceId": "ade915387b18f7a3b9a14fd8fb677fdbace0ade794de7914e8790d907cd285d0",
"templateCredsSetupCompleted": true
},
"name": "Automated Google Drive to FTP File Transfer with JSON Logging and Reporting",
"tags": [],
"nodes": [
{
"id": "52861d1c-200e-46dc-84cc-964db24965df",
"name": "Nota Adhesiva",
"type": "n8n-nodes-base.stickyNote",
"position": [
224,
400
],
"parameters": {
"width": 444,
"height": 180,
"content": "🔗 **WEBHOOK TRIGGER**\n\nManual trigger endpoint:\nPOST to: `/webhook-transfer-status`\n\nUse for on-demand transfers or external integrations."
},
"typeVersion": 1
},
{
"id": "81c1ff80-5b17-46a2-9b48-d25894340817",
"name": "Activador Programado",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
304,
32
],
"parameters": {
"rule": {
"interval": [
{
"field": "hours",
"hoursInterval": 6
}
]
}
},
"typeVersion": 1.1
},
{
"id": "fb27fb5b-5ff4-4bb4-82e3-44ad39b72022",
"name": "Obtener Archivos de Drive",
"type": "n8n-nodes-base.googleDrive",
"position": [
496,
32
],
"parameters": {
"operation": "search"
},
"typeVersion": 3
},
{
"id": "112f4226-ff78-4da8-9d97-b729d2ae54cb",
"name": "Filtrar y Validar Archivos",
"type": "n8n-nodes-base.code",
"position": [
704,
32
],
"parameters": {
"jsCode": "const transferNotes = {\n metadata: {\n created: new Date().toISOString(),\n lastUpdated: new Date().toISOString(),\n totalFiles: 0,\n successfulTransfers: 0,\n failedTransfers: 0,\n skippedFiles: 0\n },\n settings: {\n maxFileSizeMB: 50,\n allowedExtensions: ['.pdf', '.doc', '.docx', '.txt', '.jpg', '.png', '.zip', '.xlsx'],\n autoDeleteAfterTransfer: false,\n verifyTransfer: true\n },\n transfers: [],\n notes: {\n general: 'File transfer from Google Drive to FTP server',\n lastRun: new Date().toISOString(),\n instructions: 'This workflow automatically transfers files from Google Drive to FTP'\n }\n};\n\nconst driveFiles = $input.all();\nconst validFiles = [];\n\nfor (const fileItem of driveFiles) {\n const file = fileItem.json;\n const fileName = file.name;\n const fileSize = parseInt(file.size) || 0;\n const fileExtension = fileName.substring(fileName.lastIndexOf('.')).toLowerCase();\n \n const maxSizeBytes = transferNotes.settings.maxFileSizeMB * 1024 * 1024;\n const isAllowedExtension = transferNotes.settings.allowedExtensions.includes(fileExtension);\n const isSizeOk = fileSize <= maxSizeBytes;\n \n if (isAllowedExtension && isSizeOk) {\n validFiles.push({\n id: file.id,\n name: fileName,\n size: fileSize,\n extension: fileExtension,\n modifiedTime: file.modifiedTime,\n mimeType: file.mimeType,\n transferStatus: 'pending'\n });\n } else {\n transferNotes.transfers.push({\n timestamp: new Date().toISOString(),\n fileId: file.id,\n fileName: fileName,\n fileSize: fileSize,\n status: 'skipped',\n reason: !isAllowedExtension ? 'Invalid file extension' : 'File too large',\n details: {\n extension: fileExtension,\n sizeMB: Math.round(fileSize / 1024 / 1024 * 100) / 100\n }\n });\n transferNotes.metadata.skippedFiles++;\n }\n}\n\ntransferNotes.metadata.totalFiles = validFiles.length;\n\nreturn [{\n json: {\n transferNotes: transferNotes,\n validFiles: validFiles,\n totalFilesFound: driveFiles.length,\n validFilesCount: validFiles.length\n }\n}];"
},
"typeVersion": 2
},
{
"id": "d9f3620c-c532-43fa-9b8b-0b6e47737fd0",
"name": "Procesar Uno por Uno",
"type": "n8n-nodes-base.splitInBatches",
"position": [
896,
32
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "7622280e-523d-40ed-84a6-6467c46470e8",
"name": "Descargar desde Drive",
"type": "n8n-nodes-base.googleDrive",
"position": [
1104,
32
],
"parameters": {
"fileId": "={{ $json.validFiles[$json.batchIndex].id }}",
"options": {},
"operation": "download"
},
"typeVersion": 3
},
{
"id": "90b25c0a-0719-4b24-ac62-e61781e27533",
"name": "Subir a FTP",
"type": "n8n-nodes-base.ftp",
"position": [
1296,
32
],
"parameters": {
"path": "/remote/directory/{{ $json.validFiles[$json.batchIndex].name }}",
"options": {}
},
"typeVersion": 1
},
{
"id": "9cf1b93b-5584-48d9-bb96-91c2665719cf",
"name": "Actualizar Notas - Éxito",
"type": "n8n-nodes-base.code",
"position": [
1504,
-64
],
"parameters": {
"jsCode": "const currentFile = $('split-files').item.json.validFiles[$('split-files').item.json.batchIndex];\nconst transferNotes = $('filter-files').item.json.transferNotes;\n\nconst transferRecord = {\n timestamp: new Date().toISOString(),\n fileId: currentFile.id,\n fileName: currentFile.name,\n fileSize: currentFile.size,\n status: 'success',\n transferDuration: null,\n ftpPath: `/remote/directory/${currentFile.name}`,\n details: {\n extension: currentFile.extension,\n mimeType: currentFile.mimeType,\n sizeMB: Math.round(currentFile.size / 1024 / 1024 * 100) / 100\n }\n};\n\ntransferNotes.transfers.push(transferRecord);\ntransferNotes.metadata.successfulTransfers++;\ntransferNotes.metadata.lastUpdated = new Date().toISOString();\n\nreturn [{\n json: {\n transferNotes: transferNotes,\n currentTransfer: transferRecord,\n message: `Successfully transferred file: ${currentFile.name}`\n }\n}];"
},
"typeVersion": 2
},
{
"id": "5ea1483c-1b95-443e-b57f-08a192bc76f9",
"name": "Actualizar Notas - Error",
"type": "n8n-nodes-base.code",
"position": [
1504,
144
],
"parameters": {
"jsCode": "const currentFile = $('split-files').item.json.validFiles[$('split-files').item.json.batchIndex];\nconst transferNotes = $('filter-files').item.json.transferNotes;\nconst errorInfo = $input.last().error || 'Unknown error';\n\nconst transferRecord = {\n timestamp: new Date().toISOString(),\n fileId: currentFile.id,\n fileName: currentFile.name,\n fileSize: currentFile.size,\n status: 'failed',\n errorMessage: errorInfo.message || errorInfo,\n details: {\n extension: currentFile.extension,\n mimeType: currentFile.mimeType,\n sizeMB: Math.round(currentFile.size / 1024 / 1024 * 100) / 100\n }\n};\n\ntransferNotes.transfers.push(transferRecord);\ntransferNotes.metadata.failedTransfers++;\ntransferNotes.metadata.lastUpdated = new Date().toISOString();\n\nreturn [{\n json: {\n transferNotes: transferNotes,\n currentTransfer: transferRecord,\n message: `Error during file transfer: ${currentFile.name} - ${errorInfo.message || errorInfo}`\n }\n}];"
},
"typeVersion": 2
},
{
"id": "ea8a7f9c-b7a8-4a15-8584-7fe59a7d18bd",
"name": "Verificar si Hay Más Archivos",
"type": "n8n-nodes-base.if",
"position": [
1696,
32
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "success-condition",
"operator": {
"type": "boolean",
"operation": "equal"
},
"leftValue": "={{ $json.batchIndex < ($json.validFiles.length - 1) }}",
"rightValue": true
}
]
}
},
"typeVersion": 2
},
{
"id": "25732bf1-2c41-44b3-bcbf-a492f30be6e9",
"name": "Guardar Notas JSON",
"type": "n8n-nodes-base.writeBinaryFile",
"position": [
1904,
32
],
"parameters": {
"options": {},
"fileName": "transfer_notes_{{ new Date().toISOString().split('T')[0] }}.json"
},
"typeVersion": 1
},
{
"id": "b400936c-4f5d-4b7e-b414-38accc14bd7a",
"name": "Subir Notas a Drive",
"type": "n8n-nodes-base.googleDrive",
"position": [
2096,
32
],
"parameters": {
"name": "transfer_notes_{{ new Date().toISOString().split('T')[0] }}.json",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "list",
"value": "root",
"cachedResultName": "/ (Root folder)"
}
},
"typeVersion": 3
},
{
"id": "9a4bffa9-6d4b-495e-af69-68884eeadaab",
"name": "Enviar Correo de Reporte",
"type": "n8n-nodes-base.emailSend",
"position": [
2304,
32
],
"webhookId": "4ef2b12e-aae1-4c93-a034-13bdda075fad",
"parameters": {
"options": {
"appendAttribution": false
},
"subject": "Google Drive to FTP File Transfer - Report"
},
"typeVersion": 2.1
},
{
"id": "234ca9a5-6ce6-470d-b1f4-31671cf782c3",
"name": "Webhook Trigger",
"type": "n8n-nodes-base.webhook",
"position": [
304,
240
],
"webhookId": "transfer-webhook-id",
"parameters": {
"path": "/webhook-transfer-status",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 2
},
{
"id": "e5ebea62-bc9c-4a56-a52d-0a657df83e2c",
"name": "Crear Reporte Final",
"type": "n8n-nodes-base.code",
"position": [
1904,
240
],
"parameters": {
"jsCode": "const transferNotes = $json.transferNotes;\nconst summary = {\n executionDate: new Date().toLocaleString('en-US'),\n totalFiles: transferNotes.metadata.totalFiles,\n successful: transferNotes.metadata.successfulTransfers,\n failed: transferNotes.metadata.failedTransfers,\n skipped: transferNotes.metadata.skippedFiles,\n successRate: transferNotes.metadata.totalFiles > 0 ? Math.round((transferNotes.metadata.successfulTransfers / transferNotes.metadata.totalFiles) * 100) : 0,\n settings: transferNotes.settings,\n lastUpdated: transferNotes.metadata.lastUpdated\n};\n\nconst successfulTransfers = transferNotes.transfers.filter(t => t.status === 'success').map(t => ({\n fileName: t.fileName,\n sizeMB: t.details.sizeMB,\n timestamp: t.timestamp\n}));\n\nconst failedTransfers = transferNotes.transfers.filter(t => t.status === 'failed').map(t => ({\n fileName: t.fileName,\n error: t.errorMessage,\n timestamp: t.timestamp\n}));\n\nreturn [{\n json: {\n summary: summary,\n successfulTransfers: successfulTransfers,\n failedTransfers: failedTransfers,\n fullNotes: transferNotes\n }\n}];"
},
"typeVersion": 2
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "ce584da0-35fd-4b92-a862-13b3256a376b",
"connections": {
"90b25c0a-0719-4b24-ac62-e61781e27533": {
"main": [
[
{
"node": "9cf1b93b-5584-48d9-bb96-91c2665719cf",
"type": "main",
"index": 0
}
]
]
},
"fb27fb5b-5ff4-4bb4-82e3-44ad39b72022": {
"main": [
[
{
"node": "112f4226-ff78-4da8-9d97-b729d2ae54cb",
"type": "main",
"index": 0
}
]
]
},
"25732bf1-2c41-44b3-bcbf-a492f30be6e9": {
"main": [
[
{
"node": "b400936c-4f5d-4b7e-b414-38accc14bd7a",
"type": "main",
"index": 0
}
]
]
},
"234ca9a5-6ce6-470d-b1f4-31671cf782c3": {
"main": [
[
{
"node": "fb27fb5b-5ff4-4bb4-82e3-44ad39b72022",
"type": "main",
"index": 0
}
]
]
},
"81c1ff80-5b17-46a2-9b48-d25894340817": {
"main": [
[
{
"node": "fb27fb5b-5ff4-4bb4-82e3-44ad39b72022",
"type": "main",
"index": 0
}
]
]
},
"d9f3620c-c532-43fa-9b8b-0b6e47737fd0": {
"main": [
[
{
"node": "7622280e-523d-40ed-84a6-6467c46470e8",
"type": "main",
"index": 0
}
],
[
{
"node": "e5ebea62-bc9c-4a56-a52d-0a657df83e2c",
"type": "main",
"index": 0
}
]
]
},
"ea8a7f9c-b7a8-4a15-8584-7fe59a7d18bd": {
"main": [
[
{
"node": "d9f3620c-c532-43fa-9b8b-0b6e47737fd0",
"type": "main",
"index": 0
}
],
[
{
"node": "25732bf1-2c41-44b3-bcbf-a492f30be6e9",
"type": "main",
"index": 0
}
]
]
},
"e5ebea62-bc9c-4a56-a52d-0a657df83e2c": {
"main": [
[
{
"node": "25732bf1-2c41-44b3-bcbf-a492f30be6e9",
"type": "main",
"index": 0
}
]
]
},
"7622280e-523d-40ed-84a6-6467c46470e8": {
"main": [
[
{
"node": "90b25c0a-0719-4b24-ac62-e61781e27533",
"type": "main",
"index": 0
}
]
]
},
"5ea1483c-1b95-443e-b57f-08a192bc76f9": {
"main": [
[
{
"node": "ea8a7f9c-b7a8-4a15-8584-7fe59a7d18bd",
"type": "main",
"index": 0
}
]
]
},
"b400936c-4f5d-4b7e-b414-38accc14bd7a": {
"main": [
[
{
"node": "9a4bffa9-6d4b-495e-af69-68884eeadaab",
"type": "main",
"index": 0
}
]
]
},
"9cf1b93b-5584-48d9-bb96-91c2665719cf": {
"main": [
[
{
"node": "ea8a7f9c-b7a8-4a15-8584-7fe59a7d18bd",
"type": "main",
"index": 0
}
]
]
},
"112f4226-ff78-4da8-9d97-b729d2ae54cb": {
"main": [
[
{
"node": "d9f3620c-c532-43fa-9b8b-0b6e47737fd0",
"type": "main",
"index": 0
}
]
]
}
}
}¿Cómo usar este flujo de trabajo?
Copie el código de configuración JSON de arriba, cree un nuevo flujo de trabajo en su instancia de n8n y seleccione "Importar desde JSON", pegue la configuración y luego modifique la configuración de credenciales según sea necesario.
¿En qué escenarios es adecuado este flujo de trabajo?
Intermedio - Gestión de archivos, Varios, IA Multimodal
¿Es de pago?
Este flujo de trabajo es completamente gratuito, puede importarlo y usarlo directamente. Sin embargo, tenga en cuenta que los servicios de terceros utilizados en el flujo de trabajo (como la API de OpenAI) pueden requerir un pago por su cuenta.
Flujos de trabajo relacionados recomendados
Dariusz Koryto
@dakoCompartir este flujo de trabajo