使用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 凭证
使用的节点 (17)
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 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)可能需要您自行付费。
相关工作流推荐
YouTube评论情感和关键词提取器
使用Gemini AI分析YouTube评论情感和关键词并通过Telegram报告
Set
Code
Telegram
+10
20 节点Budi SJ
市场调研
使用Google Vision OCR、Telegram和Google Sheets的自动化财务报告
使用Google Vision OCR、AI和Telegram处理收据到Google表格
If
Set
Code
+12
31 节点Budi SJ
发票处理
自动化视频生成器
使用 DeepSeek、TTS 和 Together.ai 从脚本生成 AI 视频
Set
Code
Wait
+15
81 节点Lakindu Siriwardana
内容创作
使用AI和RSS的多平台YouTube内容生成器
使用AI和RSS从YouTube生成多平台内容
If
Set
Code
+10
37 节点Budi SJ
内容创作
基于 AI、社交媒体和 WhatsApp 链接的自动化本地商业线索生成器
使用 AI、社交媒体和 WhatsApp 链接自动生成本地商业线索
If
Code
Limit
+9
29 节点Budi SJ
潜在客户开发
自动化应用分析与ASO报告生成器
使用Gemini AI和Google Docs从Google Play应用生成ASO报告
Code
Telegram
Google Docs
+5
13 节点Budi SJ
市场调研
工作流信息
难度等级
高级
节点数量17
分类2
节点类型11
作者
Budi SJ
@budisjI’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 查看 →
分享此工作流