8
n8n 中文网amn8n.com

建筑蓝图至Google Sheets自动化

中级

这是一个AI Summarization, Multimodal AI领域的自动化工作流,包含 8 个节点。主要使用 GoogleDrive, GoogleSheets, VlmRun, GoogleDriveTrigger 等节点。 使用VLM Run和Google Drive实现建筑蓝图至Google Sheets自动化

前置要求
  • Google Drive API 凭证
  • Google Sheets API 凭证
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "meta": {
    "instanceId": "96d35e452e0d9a182973416b7532cfc5643239aaaa764a5bf74d52ca84f4a35c"
  },
  "nodes": [
    {
      "id": "437ad354-32ef-4400-afa4-7cc37a819d5b",
      "name": "VLM 运行",
      "type": "@vlm-run/n8n-nodes-vlmrun.vlmRun",
      "position": [
        1744,
        480
      ],
      "parameters": {
        "domain": "construction.blueprint"
      },
      "typeVersion": 1
    },
    {
      "id": "6aa5ea64-0da0-4296-b57d-a002b9ca7b28",
      "name": "在表格中追加行",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2256,
        480
      ],
      "parameters": {
        "columns": {
          "value": {
            "SCALE": "={{ $json.response.title_block.scale }}",
            "ADDRESS": "={{ (v => {\n  const S = x =>\n    x == null ? '' :\n    Array.isArray(x)\n      ? x.map(S).map(s => String(s).trim()).filter(Boolean).join(',\\n')\n      : typeof x === 'object'\n        ? Object.entries(x)\n            .filter(([_, val]) => {\n              if (val == null) return false\n              if (typeof val === 'string') return val.trim() !== ''\n              if (Array.isArray(val)) return val.map(S).some(s => String(s).trim() !== '')\n              if (typeof val === 'object') return Object.keys(val).length > 0\n              return true\n            })\n            .map(([k, val]) => {\n              const sv = S(val)\n              return sv ? `${k}: ${sv}` : ''\n            })\n            .filter(Boolean)\n            .join(',\\n')\n        : String(x).trim()\n  return S(v)\n})($json.response?.title_block?.address) }}\n",
            "DRAWN BY": "={{ $json.response.title_block.drawn_by }}",
            "JOB NAME": "={{ $json.response.title_block.job_name }}",
            "REVISION": "={{ $json.response.title_block.revision }}",
            "CHECKED BY": "={{ $json.response.title_block.checked_by }}",
            "ISSUE DATE": "={{ $json.response.document_metadata.issue_date }}",
            "AGENCY NAME": "={{ $json.response.title_block.agency_name }}",
            "DRAWING TYPE": "={{ $json.response.drawing_type }}",
            "AUTHOR'S NAME": "={{ (v => {\n  const S = x =>\n    x == null ? '' :\n    Array.isArray(x)\n      ? x.map(S).map(s => String(s).trim()).filter(Boolean).join(',\\n')\n      : typeof x === 'object'\n        ? Object.entries(x)\n            .filter(([_, val]) => {\n              if (val == null) return false\n              if (typeof val === 'string') return val.trim() !== ''\n              if (Array.isArray(val)) return val.map(S).some(s => String(s).trim() !== '')\n              if (typeof val === 'object') return Object.keys(val).length > 0\n              return true\n            })\n            .map(([k, val]) => {\n              const sv = S(val)\n              return sv ? `${k}: ${sv}` : ''\n            })\n            .filter(Boolean)\n            .join(',\\n')\n        : String(x).trim()\n  return S(v)\n})($json.response?.document_metadata?.author) }}\n",
            "DOCUMENT TYPE": "={{ $json.response.document_metadata.document_type }}",
            "DOCUMENT TITLE": "={{ $json.response.title_block.document_title }}",
            "DRAWING NUMBER": "={{ $json.response.title_block.drawing_number }}",
            "OTHER METADATA": "={{ (v => {\n  const S = x =>\n    x == null ? '' :\n    Array.isArray(x)\n      ? x.map(S).map(s => String(s).trim()).filter(Boolean).join(',\\n')\n      : typeof x === 'object'\n        ? Object.entries(x)\n            .filter(([_, val]) => {\n              if (val == null) return false\n              if (typeof val === 'string') return val.trim() !== ''\n              if (Array.isArray(val)) return val.map(S).some(s => String(s).trim() !== '')\n              if (typeof val === 'object') return Object.keys(val).length > 0\n              return true\n            })\n            .map(([k, val]) => {\n              const sv = S(val)\n              return sv ? `${k}: ${sv}` : ''\n            })\n            .filter(Boolean)\n            .join(',\\n')\n        : String(x).trim()\n  return S(v)\n})($json.response?.title_block?.other_metadata) }}\n",
            "SCALE LEEGENDS": "={{ $json.response.drawings_blueprints.scale_legends }}",
            "PROJECT DETAILS": "={{ (v => {\n  const S = x =>\n    x == null ? '' :\n    Array.isArray(x)\n      ? x.map(S).map(s => String(s).trim()).filter(Boolean).join(',\\n')\n      : typeof x === 'object'\n        ? Object.entries(x)\n            .filter(([_, val]) => {\n              if (val == null) return false\n              if (typeof val === 'string') return val.trim() !== ''\n              if (Array.isArray(val)) return val.map(S).some(s => String(s).trim() !== '')\n              if (typeof val === 'object') return Object.keys(val).length > 0\n              return true\n            })\n            .map(([k, val]) => {\n              const sv = S(val)\n              return sv ? `${k}: ${sv}` : ''\n            })\n            .filter(Boolean)\n            .join(',\\n')\n        : String(x).trim()\n  return S(v)\n})($json.response?.project_details) }}\n",
            "DOCUMENT NUMBER ": "={{ $json.response.document_metadata.document_number }}",
            "LEGAL COMPLIANCE": "={{ (v => {\n  const S = x =>\n    x == null ? '' :\n    Array.isArray(x)\n      ? x.map(S).map(s => String(s).trim()).filter(Boolean).join(',\\n')\n      : typeof x === 'object'\n        ? Object.entries(x)\n            .filter(([_, val]) => {\n              if (val == null) return false\n              if (typeof val === 'string') return val.trim() !== ''\n              if (Array.isArray(val)) return val.map(S).some(s => String(s).trim() !== '')\n              if (typeof val === 'object') return Object.keys(val).length > 0\n              return true\n            })\n            .map(([k, val]) => {\n              const sv = S(val)\n              return sv ? `${k}: ${sv}` : ''\n            })\n            .filter(Boolean)\n            .join(',\\n')\n        : String(x)\n  return S(v)\n})($json.response?.compliance_legal) }}\n",
            "REVISION HISTORY": "={{ (v => {\n  const S = x =>\n    x == null ? '' :\n    Array.isArray(x)\n      ? x.map(S).map(s => String(s).trim()).filter(Boolean).join(',\\n')\n      : typeof x === 'object'\n        ? Object.entries(x)\n            .filter(([_, val]) => {\n              if (val == null) return false\n              if (typeof val === 'string') return val.trim() !== ''\n              if (Array.isArray(val)) return val.map(S).some(s => String(s).trim() !== '')\n              if (typeof val === 'object') return Object.keys(val).length > 0\n              return true\n            })\n            .map(([k, val]) => {\n              const sv = S(val)\n              return sv ? `${k}: ${sv}` : ''\n            })\n            .filter(Boolean)\n            .join(',\\n')\n        : String(x).trim()\n  return S(v)\n})($json.response?.drawings_blueprints?.revision_history) }}\n",
            "SCALE INFORMATION": "={{ $json.response.scale_information }}",
            "ANNOTATIONS MARKUPS": "={{ (v => {\n  const S = x =>\n    x == null ? '' :\n    Array.isArray(x)\n      ? x.map(S).map(s => String(s).trim()).filter(Boolean).join(',\\n')\n      : typeof x === 'object'\n        ? Object.entries(x)\n            .filter(([_, val]) => {\n              if (val == null) return false\n              if (typeof val === 'string') return val.trim() !== ''\n              if (Array.isArray(val)) return val.map(S).some(s => String(s).trim() !== '')\n              if (typeof val === 'object') return Object.keys(val).length > 0\n              return true\n            })\n            .map(([k, val]) => {\n              const sv = S(val)\n              return sv ? `${k}: ${sv}` : ''\n            })\n            .filter(Boolean)\n            .join(',\\n')\n        : String(x).trim()\n  return S(v)\n})($json.response?.drawings_blueprints?.annotations_markups) }}\n",
            "DRAWING TITLE NUMBERS": "={{ (v => {\n  const S = x =>\n    x == null ? '' :\n    Array.isArray(x)\n      ? x.map(S).map(s => String(s).trim()).filter(Boolean).join(',\\n')\n      : typeof x === 'object'\n        ? Object.entries(x)\n            .filter(([_, val]) => {\n              if (val == null) return false\n              if (typeof val === 'string') return val.trim() !== ''\n              if (Array.isArray(val)) return val.map(S).some(s => String(s).trim() !== '')\n              if (typeof val === 'object') return Object.keys(val).length > 0\n              return true\n            })\n            .map(([k, val]) => {\n              const sv = S(val)\n              return sv ? `${k}: ${sv}` : ''\n            })\n            .filter(Boolean)\n            .join(',\\n')\n        : String(x).trim()\n  return S(v)\n})($json.response?.drawings_blueprints?.drawing_titles_numbers) }}\n"
          },
          "schema": [
            {
              "id": "PROJECT DETAILS",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "PROJECT DETAILS",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "DOCUMENT TYPE",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "DOCUMENT TYPE",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "DOCUMENT NUMBER ",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "DOCUMENT NUMBER ",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ISSUE DATE",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "ISSUE DATE",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "AUTHOR'S NAME",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "AUTHOR'S NAME",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "DRAWING TITLE NUMBERS",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "DRAWING TITLE NUMBERS",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "SCALE LEEGENDS",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "SCALE LEEGENDS",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "REVISION HISTORY",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "REVISION HISTORY",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ANNOTATIONS MARKUPS",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "ANNOTATIONS MARKUPS",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "JOB NAME",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "JOB NAME",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ADDRESS",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "ADDRESS",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "DRAWING NUMBER",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "DRAWING NUMBER",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "REVISION",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "REVISION",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "DRAWN BY",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "DRAWN BY",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "CHECKED BY",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "CHECKED BY",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "SCALE",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "SCALE",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "AGENCY NAME",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "AGENCY NAME",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "DOCUMENT TITLE",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "DOCUMENT TITLE",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "OTHER METADATA",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "OTHER METADATA",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "DRAWING TYPE",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "DRAWING TYPE",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "LEGAL COMPLIANCE",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "LEGAL COMPLIANCE",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "SCALE INFORMATION",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "SCALE INFORMATION",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {
          "useAppend": true
        },
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1NyNXDvHHJwedBSXa8qENv_4nBlqyaU-l3wgtAK-9Om0/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1NyNXDvHHJwedBSXa8qENv_4nBlqyaU-l3wgtAK-9Om0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1NyNXDvHHJwedBSXa8qENv_4nBlqyaU-l3wgtAK-9Om0/edit?usp=drivesdk",
          "cachedResultName": "Construction Blue print"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "42f825ee-f0dd-44c0-91f1-6088fcf29f0d",
      "name": "下载文件",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        1328,
        480
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "options": {},
        "operation": "download"
      },
      "typeVersion": 3
    },
    {
      "id": "72f102a6-e223-437f-bf19-861818ff9b09",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        512,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 480,
        "height": 768,
        "content": "# 使用 VLM 运行处理建筑蓝图"
      },
      "typeVersion": 1
    },
    {
      "id": "145286ec-906c-430d-8448-447eac2bd266",
      "name": "便签2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2048,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 480,
        "height": 768,
        "content": "# 在表格中追加行"
      },
      "typeVersion": 1
    },
    {
      "id": "09952464-9148-44c9-a6c0-ab09b285be87",
      "name": "Google Drive 触发器",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "position": [
        1088,
        480
      ],
      "parameters": {
        "event": "fileCreated",
        "options": {
          "fileType": "all"
        },
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "mode": "list",
          "value": "1E8rvLEWKguorMT36yCD1jY78G0u8g6g7",
          "cachedResultUrl": "https://drive.google.com/drive/folders/1E8rvLEWKguorMT36yCD1jY78G0u8g6g7",
          "cachedResultName": "test_data"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "6b368cd5-0ce9-453f-9e02-28440878aa72",
      "name": "便签1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1024,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 480,
        "height": 768,
        "content": "# 📁 输入处理"
      },
      "typeVersion": 1
    },
    {
      "id": "84b00cb6-ac37-4ea9-ab09-118c40160767",
      "name": "便签3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1536,
        0
      ],
      "parameters": {
        "width": 480,
        "height": 768,
        "content": "# VLM 运行(文档)"
      },
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "VLM Run": {
      "main": [
        [
          {
            "node": "Append row in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download file": {
      "main": [
        [
          {
            "node": "VLM Run",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Drive Trigger": {
      "main": [
        [
          {
            "node": "Download file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

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

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

中级 - AI 摘要总结, 多模态 AI

需要付费吗?

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

工作流信息
难度等级
中级
节点数量8
分类2
节点类型5
难度说明

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

作者
Shahrear

Shahrear

@shahrear

I’m Shahrear, a Software Engineer with over 5 years of experience in full-stack development and workflow automation. I specialize in building intelligent automations using n8n, helping teams streamline operations and boost productivity. I’m also an expert in developing custom n8n nodes, with published work on npm - including the @vlm-run/n8n-nodes-vlmrun package. Linkedin - https://www.linkedin.com/in/shahrear-amin/ Email - shahrearbinamin33@gmail.com

外部链接
在 n8n.io 查看

分享此工作流