8
n8n 中文网amn8n.com

使用Vision API和LLM实现自动化发票收集与数据提取

高级

这是一个Invoice Processing, Multimodal AI领域的自动化工作流,包含 17 个节点。主要使用 Set, Code, Telegram, FormTrigger, GoogleDrive 等节点。 使用Google Vision OCR、Gemini LLM和Google Sheets提取和结构化发票数据

前置要求
  • Telegram Bot Token
  • Google Drive API 凭证
  • 可能需要目标 API 的认证凭证
  • Google Sheets API 凭证
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "id": "weV4UB3UBRHEfe1k",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "使用 Vision API 和 LLM 实现自动化发票收集与数据提取",
  "tags": [],
  "nodes": [
    {
      "id": "2b378a23-08b9-4b7e-b1c5-114087802a71",
      "name": "便签1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -340,
        -480
      ],
      "parameters": {
        "width": 580,
        "height": 1200,
        "content": "# 使用 Vision API 和 LLM 实现自动化发票收集与数据提取"
      },
      "typeVersion": 1
    },
    {
      "id": "e4ac27f9-6db0-489f-bd7f-033fd792fc7c",
      "name": "设置 Vision API",
      "type": "n8n-nodes-base.set",
      "position": [
        1120,
        20
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "586cf442-13be-4996-9824-366e20ab864e",
              "name": "visionAPI",
              "type": "string",
              "value": "YOUR_VISION_API_KEY_HERE"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "2e81ab2f-5f8f-4676-bfbf-9753bad4369e",
      "name": "基础 LLM 链",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        1540,
        20
      ],
      "parameters": {
        "text": "={{ $json.responses[0].fullTextAnnotation.text }}",
        "batching": {},
        "messages": {
          "messageValues": [
            {
              "message": "=You are a professional accountant experienced in preparing financial reports and classifying expenses into appropriate categories.\nYou will receive input data extracted via OCR that needs to be parsed and structured.\n\nInstructions:\n\nOutput must be in the same language as the input.\nParse and return the data in this column order:\nDATE : Extract in YYYY-MM-DD format, if not found use current date\nNO VOUCHER : Extract invoice or voucher number, if not found return not found\nTRANSACTION DETAIL : Short summary of products or services, if not found return not found\nVENDOR : Store or vendor name, if not found return not found\nVALUE : Transaction total amount as a number without currency symbol, if not found return 0\n\nMissing text fields : not found\nMissing numeric values : 0\nOutput only the structured data, no extra explanations"
            }
          ]
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.7
    },
    {
      "id": "d0ca7089-c557-48d8-a854-310efbc5b5be",
      "name": "OpenRouter 聊天模型",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        1540,
        220
      ],
      "parameters": {
        "model": "google/gemini-2.0-flash-exp:free",
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "22bbee6d-a897-4f2a-b0c9-06b7574ebf8e",
      "name": "结构化输出解析器",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1700,
        220
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"DATE\": \"2025-07-07\",\n  \"NO VOUCHER\": \"INV-001234\",\n  \"TRANSACTION DETAIL\": \"Product summary\",\n  \"VENDOR\": \"Vendor Name or Shop Name\",\n  \"VALUE\": 0\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "8a108ae0-3061-49a9-aef1-c426f078cca1",
      "name": "下载文件",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        740,
        20
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "options": {},
        "operation": "download"
      },
      "typeVersion": 3
    },
    {
      "id": "0a96b787-f8e4-408c-80d8-dc2a868c93e4",
      "name": "HTTP 请求",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1320,
        20
      ],
      "parameters": {
        "url": "=https://vision.googleapis.com/v1/images:annotate?key={{ $json.visionAPI }}",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"requests\": [\n    {\n      \"image\": {\n        \"content\": \"{{ $('Code').item.json.base64 }}\"\n      },\n      \"features\": [\n        {\n          \"type\": \"TEXT_DETECTION\"\n        }\n      ]\n    }\n  ]\n}\n",
        "sendBody": true,
        "specifyBody": "json"
      },
      "typeVersion": 4.2
    },
    {
      "id": "c2b91608-a4bc-4c65-9697-af3d05e6b097",
      "name": "发送文本消息",
      "type": "n8n-nodes-base.telegram",
      "position": [
        2300,
        20
      ],
      "parameters": {
        "text": "=💳 New transaction : \n- Date : {{ $json.DATE }}\n- Transaction detail : {{ $json['TRANSACTION DETAIL'] }}\n- Vendor : {{ $json.VENDOR }}\n- Total transaction : {{ $json.VALUE }}\n\n---",
        "chatId": "YOUR_TELEGRAM_CHAT_ID",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "89ae0865-ac70-4cdb-8f14-e64dd023ede2",
      "name": "上传文件",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        520,
        20
      ],
      "parameters": {
        "name": "={{ $json.Image[0].filename }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_GOOGLE_DRIVE_FOLDER_ID"
        },
        "inputDataFieldName": "=Image"
      },
      "typeVersion": 3
    },
    {
      "id": "2dc29bd4-058e-426f-a78c-e99b15f67c82",
      "name": "代码",
      "type": "n8n-nodes-base.code",
      "position": [
        940,
        20
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Convert file to base64 for Vision API\nconst base64 = item.binary.data.data; // 'data' is the binary name\nreturn {\n  json: {\n    base64\n  }\n};\n"
      },
      "typeVersion": 2
    },
    {
      "id": "a755e54a-5361-46aa-8db0-089a22195b96",
      "name": "代码1",
      "type": "n8n-nodes-base.code",
      "position": [
        1880,
        20
      ],
      "parameters": {
        "jsCode": "function cleanNumber(n) {\n  return parseInt(n.toString().replace(/[.,]/g, '')) || 0;\n}\n\n// Get output from $json\nconst output = $json.output || {};\n\n// If there are Items, process them. If not, skip.\nconst items = Array.isArray(output.Items)\n  ? output.Items.map(item => ({\n      ...item,\n      Quantity: cleanNumber(item.Quantity),\n      \"Unit Price\": cleanNumber(item[\"Unit Price\"]),\n      Total: cleanNumber(item.Total),\n    }))\n  : undefined;\n\n// Optional: clean Total Amount as well\nconst totalAmount = output[\"Total Amount\"]\n  ? cleanNumber(output[\"Total Amount\"])\n  : 0;\n\nreturn {\n  json: {\n    output: {\n      ...output,\n      ...(items && { Items: items }),\n      \"Total Amount\": totalAmount,\n    }\n  }\n};\n"
      },
      "typeVersion": 2
    },
    {
      "id": "606d3086-073c-40b5-b65e-c9de3101d86d",
      "name": "在表格中追加或更新行",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2100,
        20
      ],
      "parameters": {
        "columns": {
          "value": {
            "ID": "={{ $('Download file').item.json.id }}",
            "IMG": "={{ $('Download file').item.json.webViewLink }}",
            "DATE": "={{ $json.output.DATE }}",
            "VALUE": "={{ $json.output.VALUE }}",
            "VENDOR": "={{ $json.output.VENDOR }}",
            "FILE NAME": "={{ $('Download file').item.json.name }}",
            "NO VOUCHER": "={{ $json.output['NO VOUCHER'] }}",
            "TRANSACTION DETAIL": "={{ $json.output['TRANSACTION DETAIL'] }}"
          },
          "schema": [
            {
              "id": "ID",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "FILE NAME",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "FILE NAME",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "IMG",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "IMG",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "DATE",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "DATE",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "NO VOUCHER",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "NO VOUCHER",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "TRANSACTION DETAIL",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "TRANSACTION DETAIL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "VENDOR",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "VENDOR",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "VALUE",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "VALUE",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "ID"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_GOOGLE_SHEETS_DOCUMENT_ID"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "71add4c5-64ef-49e2-9fbf-7b6034b17705",
      "name": "表单提交时",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        300,
        20
      ],
      "parameters": {
        "options": {
          "appendAttribution": false
        },
        "formTitle": "Upload Purchase Invoice",
        "formFields": {
          "values": [
            {
              "fieldType": "file",
              "fieldLabel": "Image",
              "requiredField": true,
              "acceptFileTypes": ".jpg, .png, .jpeg"
            }
          ]
        },
        "responseMode": "lastNode"
      },
      "typeVersion": 2.2
    },
    {
      "id": "98b5b08e-2b7c-4360-a224-43fd6059bb34",
      "name": "便签2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        260,
        -200
      ],
      "parameters": {
        "color": 2,
        "width": 600,
        "height": 400,
        "content": "- 当用户提交名为\"上传采购发票\"的表单时,此节点触发工作流。"
      },
      "typeVersion": 1
    },
    {
      "id": "4e897daa-cde8-4d25-8217-9f722c68fe4d",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        900,
        -200
      ],
      "parameters": {
        "color": 4,
        "width": 560,
        "height": 400,
        "content": "- 将下载的发票文件(二进制)转换为 Base64 格式,以便发送到 Google Vision API。"
      },
      "typeVersion": 1
    },
    {
      "id": "510e3239-fbbd-4b47-9c31-813994c3e251",
      "name": "便签3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1480,
        -200
      ],
      "parameters": {
        "color": 5,
        "width": 560,
        "height": 580,
        "content": "- 通过 LLM 处理 OCR 文本,提取并结构化关键发票详情。"
      },
      "typeVersion": 1
    },
    {
      "id": "71dcd4e0-84cc-4b20-ac60-6701cc4e5f60",
      "name": "便签4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2060,
        -200
      ],
      "parameters": {
        "color": 6,
        "width": 380,
        "height": 580,
        "content": "- 将提取和清理后的发票数据写入 Google Sheets 文档,添加新行或更新现有行。"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "a58b0780-6c63-40bb-84bd-a621579d6eef",
  "connections": {
    "Code": {
      "main": [
        [
          {
            "node": "Set Vision API",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code1": {
      "main": [
        [
          {
            "node": "Append or update row in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload file": {
      "main": [
        [
          {
            "node": "Download file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request": {
      "main": [
        [
          {
            "node": "Basic LLM Chain",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download file": {
      "main": [
        [
          {
            "node": "Code",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Vision API": {
      "main": [
        [
          {
            "node": "HTTP Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Basic LLM Chain": {
      "main": [
        [
          {
            "node": "Code1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "On form submission": {
      "main": [
        [
          {
            "node": "Upload file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Basic LLM Chain",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Basic LLM Chain",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Append or update row in sheet": {
      "main": [
        [
          {
            "node": "Send a text message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

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

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

高级 - 发票处理, 多模态 AI

需要付费吗?

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

工作流信息
难度等级
高级
节点数量17
分类2
节点类型11
难度说明

适合高级用户,包含 16+ 个节点的复杂工作流

作者
Budi SJ

Budi SJ

@budisj

I’m a Product Designer who also works as an Automation Developer. With a background in product design and systems thinking, I build user-centered workflows. My focus is on helping teams and businesses work more productively through impactful automation systems.

外部链接
在 n8n.io 查看

分享此工作流