8
n8n 中文网amn8n.com

自动化Google Drive到FTP文件传输与JSON日志记录和报告

中级

这是一个File Management, Miscellaneous, Multimodal AI领域的自动化工作流,包含 15 个节点。主要使用 If, Ftp, Code, Webhook, EmailSend 等节点。 自动化Google Drive到FTP文件传输与JSON日志记录和报告

前置要求
  • HTTP Webhook 端点(n8n 会自动生成)
  • Google Drive API 凭证
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "id": "LJmjAaP6VnaYVBF9",
  "meta": {
    "instanceId": "ade915387b18f7a3b9a14fd8fb677fdbace0ade794de7914e8790d907cd285d0",
    "templateCredsSetupCompleted": true
  },
  "name": "自动化 Google Drive 到 FTP 文件传输与 JSON 日志记录和报告",
  "tags": [],
  "nodes": [
    {
      "id": "52861d1c-200e-46dc-84cc-964db24965df",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        224,
        400
      ],
      "parameters": {
        "width": 444,
        "height": 180,
        "content": "🔗 **WEBHOOK 触发器**"
      },
      "typeVersion": 1
    },
    {
      "id": "81c1ff80-5b17-46a2-9b48-d25894340817",
      "name": "定时触发器",
      "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": "获取 Drive 文件",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        496,
        32
      ],
      "parameters": {
        "operation": "search"
      },
      "typeVersion": 3
    },
    {
      "id": "112f4226-ff78-4da8-9d97-b729d2ae54cb",
      "name": "过滤和验证文件",
      "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": "逐个处理",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        896,
        32
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "7622280e-523d-40ed-84a6-6467c46470e8",
      "name": "从 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": "上传到 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": "更新备注 - 成功",
      "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": "更新备注 - 错误",
      "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": "检查是否有更多文件",
      "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": "保存备注 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": "上传备注到 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": "发送报告邮件",
      "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触发器",
      "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": "创建最终报告",
      "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": {
    "Upload to FTP": {
      "main": [
        [
          {
            "node": "Update Notes - Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Drive Files": {
      "main": [
        [
          {
            "node": "Filter & Validate Files",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save Notes JSON": {
      "main": [
        [
          {
            "node": "Upload Notes to Drive",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook Trigger": {
      "main": [
        [
          {
            "node": "Get Drive Files",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Get Drive Files",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Process One by One": {
      "main": [
        [
          {
            "node": "Download from Drive",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Create Final Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check if More Files": {
      "main": [
        [
          {
            "node": "Process One by One",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Save Notes JSON",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Final Report": {
      "main": [
        [
          {
            "node": "Save Notes JSON",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download from Drive": {
      "main": [
        [
          {
            "node": "Upload to FTP",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Notes - Error": {
      "main": [
        [
          {
            "node": "Check if More Files",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload Notes to Drive": {
      "main": [
        [
          {
            "node": "Send Report Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Notes - Success": {
      "main": [
        [
          {
            "node": "Check if More Files",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter & Validate Files": {
      "main": [
        [
          {
            "node": "Process One by One",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

中级 - 文件管理, 杂项, 多模态 AI

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
中级
节点数量15
分类3
节点类型10
难度说明

适合有一定经验的用户,包含 6-15 个节点的中等复杂度工作流

外部链接
在 n8n.io 查看

分享此工作流