AI驱动的发票提取与自动化系统
高级
这是一个Invoice Processing, AI Summarization领域的自动化工作流,包含 32 个节点。主要使用 If, Set, Code, Gmail, GoogleDrive 等节点。 使用Gemini AI、Google Sheets和Gmail通知提取和处理发票
前置要求
- •Google 账号和 Gmail API 凭证
- •Google Drive API 凭证
- •Google Sheets API 凭证
- •Google Gemini API Key
使用的节点 (32)
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
"id": "EFHIQBQltrt7yPxS",
"meta": {
"instanceId": "3caab7a077d6a24bf913833250143556c3033c05ff2ea30885e13d0164c0cec2",
"templateCredsSetupCompleted": true
},
"name": "AI驱动的发票提取与自动化系统",
"tags": [],
"nodes": [
{
"id": "a6a71e48-04d8-4a73-af89-dc5ab7720788",
"name": "当收到聊天消息时",
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"position": [
-256,
672
],
"webhookId": "8c5b49b9-7491-497f-9cd5-22515ea25ba0",
"parameters": {
"options": {
"allowFileUploads": true,
"allowedFilesMimeTypes": " image/*, text/*, application/pdf"
}
},
"executeOnce": false,
"typeVersion": 1.3
},
{
"id": "1f5025c5-043e-4934-8ba9-9964becf178c",
"name": "分析图片1",
"type": "@n8n/n8n-nodes-langchain.googleGemini",
"position": [
128,
672
],
"parameters": {
"text": "What's in this image? Extract all the data And give a very formatted. Output Which has Differently listed Things of invoice",
"modelId": {
"__rl": true,
"mode": "list",
"value": "models/gemini-1.5-flash",
"cachedResultName": "models/gemini-1.5-flash"
},
"options": {},
"resource": "image",
"inputType": "binary",
"operation": "analyze",
"binaryPropertyName": "data0"
},
"credentials": {
"googlePalmApi": {
"id": "sSV7NS6JXz0qjL2i",
"name": "Google Gemini(PaLM) Api account"
}
},
"typeVersion": 1
},
{
"id": "f504934f-3551-4399-a610-f9f8ec1cd246",
"name": "AI Agent1",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
448,
672
],
"parameters": {
"text": "=Here is the invoice data - {{ $json.content.parts[0].text }}",
"options": {
"systemMessage": "=You have invoice data. \nYour task is to structure that data strictly in JSON. \n\nRules: \n- Do not add \\n or \\ in the output. \n\nOutput format:\n\n{\n \"invoice_id\": \"\",\n \"shop_name\": \"\",\n \"date\": \"\",\n \"Total\": \"\",\n \"items\": [\n {\n \"Item_Name\": \"\",\n \"Quantity\": \"\",\n \"Unit_Price\": \"\",\n \"Currency\": \"\"\n }\n ],\n \"optional_fields\": {\n \"Entry_ID\": \"\",\n \"Time\": \"\",\n \"Type\": \"\",\n \"Category\": \"\",\n \"Subcategory\": \"\",\n \"Description\": \"\",\n \"Shop_Address\": \"\",\n \"Payment_Method\": \"\",\n \"GST_Rate\": \"\",\n \"GST_Amount\": \"\",\n \"Receipt_Link\": \"\",\n \"Receipt_Number\": \"\",\n \"Remarks\": \"\",\n \"Tags\": \"\",\n \"Created_Date\": \"\",\n \"Modified_Date\": \"\",\n \"Status\": \"\",\n \"Duplicate_Check\": \"\"\n }\n}\n"
},
"promptType": "define"
},
"typeVersion": 2.2
},
{
"id": "f0999a88-8eb2-407f-8d50-6ca4118bb3df",
"name": "Google Gemini聊天模型1",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
512,
928
],
"parameters": {
"options": {}
},
"credentials": {
"googlePalmApi": {
"id": "sSV7NS6JXz0qjL2i",
"name": "Google Gemini(PaLM) Api account"
}
},
"typeVersion": 1
},
{
"id": "0ee67ef8-d38c-4a78-9267-5e482ef7b7fd",
"name": "获取数据",
"type": "n8n-nodes-base.googleSheets",
"position": [
1280,
672
],
"parameters": {
"options": {},
"filtersUI": {
"values": [
{
"lookupValue": "={{ $json.output.invoice_id }}",
"lookupColumn": "Entry_ID"
}
]
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1240712847,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1T1oFlLqrauskPHAHbRixnIbx4wSK7pY3J5EGlpFzZTQ/edit#gid=1240712847",
"cachedResultName": "Expense_Tracker"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1T1oFlLqrauskPHAHbRixnIbx4wSK7pY3J5EGlpFzZTQ",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1T1oFlLqrauskPHAHbRixnIbx4wSK7pY3J5EGlpFzZTQ/edit?usp=drivesdk",
"cachedResultName": "expense_tracker_n8n"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "2cLBwxQBfcaJ1DCN",
"name": "Google Sheets account"
}
},
"typeVersion": 4.7,
"alwaysOutputData": true
},
{
"id": "6c465765-d7ca-4f09-9720-8799132ec5d0",
"name": "将数据转换为JSON结构格式",
"type": "n8n-nodes-base.set",
"position": [
912,
672
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "9f859c68-cdaa-41d0-bc15-a6ab7db24906",
"name": "output",
"type": "object",
"value": "={{ $json.output }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "c25a3bdb-deef-4d9f-a2e3-2471bc1107fa",
"name": "检查表中数据是否存在",
"type": "n8n-nodes-base.if",
"position": [
1680,
672
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "3a5e1594-1d46-4a0c-81c9-dcdc5243931c",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ Object.keys($items(\"Get data\")[0].json).length === 0 }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "0997e665-a8c5-4bdb-90f5-5d5304a0f355",
"name": "上传发票到Drive",
"type": "n8n-nodes-base.googleDrive",
"position": [
80,
912
],
"parameters": {
"name": "=invoice_data",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "list",
"value": "root",
"cachedResultUrl": "https://drive.google.com/drive",
"cachedResultName": "/ (Root folder)"
},
"inputDataFieldName": "data0"
},
"credentials": {
"googleDriveOAuth2Api": {
"id": "dpqimR5rZMDgJjvs",
"name": "Google Drive account"
}
},
"typeVersion": 3
},
{
"id": "65f8bf39-6813-4def-8cac-274eb5db6c9e",
"name": "便签",
"type": "n8n-nodes-base.stickyNote",
"position": [
-384,
352
],
"parameters": {
"width": 368,
"height": 496,
"content": "## 节点1:**当收到聊天消息时**"
},
"typeVersion": 1
},
{
"id": "bb06ce88-cbc3-4003-a2a8-3fb9b576d371",
"name": "无缺失字段 - 使用payload 2添加新数据",
"type": "n8n-nodes-base.code",
"position": [
3152,
480
],
"parameters": {
"jsCode": "// Function Item node\n// Ensures you only pass through the payload JSON if status = \"ok\"\n\n// 1. Get current item\nconst input = $json;\n\n// 2. Check status\nif (input.status && input.status === \"ok\") {\n // ✅ Status is ok → use the payload JSON\n // 🔽 PLACEHOLDER: replace this with the node where your invoice payload lives\n const payload = $('Make data in json structure format').first().json.output;\n\n return payload;\n\n} else {\n // ❌ Status not ok → return error message\n return {\n status: \"error\",\n message: \"Missing Mandatory field(s) or status not ok\"\n };\n}\n"
},
"typeVersion": 2
},
{
"id": "070e102e-3fd3-4caf-81b6-82eae65a3b00",
"name": "如果 - 检查缺失字段",
"type": "n8n-nodes-base.if",
"position": [
2768,
496
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "6b4e00d8-0504-44a0-bf5b-5d5dd867138e",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.status }}",
"rightValue": "ok"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "84f5c157-36a7-491c-ba9e-52e5d3b08039",
"name": "通过邮件发送缺失字段错误",
"type": "n8n-nodes-base.gmail",
"position": [
3440,
976
],
"webhookId": "acbee7e7-047d-404b-a6c1-c09861fc3c67",
"parameters": {
"sendTo": "xyz@gmail.com",
"message": "=Missing filed - {{ $json.missing_fields.map(field => field).join(', ') }}\n",
"options": {},
"subject": "Missing filed error"
},
"credentials": {
"gmailOAuth2": {
"id": "zystIXitEOECXALa",
"name": "Gmail account"
}
},
"typeVersion": 2.1
},
{
"id": "c33ae480-922e-4596-bd5a-dcd3a6b4aa93",
"name": "重复条目发送邮件",
"type": "n8n-nodes-base.gmail",
"position": [
2080,
992
],
"webhookId": "6ef65cb6-499f-4893-9739-b5f277bd8931",
"parameters": {
"sendTo": "xyz@gmail.com",
"message": "=<html>\n <body style=\"font-family: Arial, sans-serif; color: #333;\">\n <h2 style=\"color:#d9534f;\">⚠ Invoice Already Exists</h2>\n <p>Hello,</p>\n <p>The invoice you attempted to add already exists in the Google Sheet. Here are the details:</p>\n\n <table style=\"border-collapse: collapse; width: 100%; margin: 16px 0;\">\n <tr>\n <td style=\"border: 1px solid #ccc; padding: 8px;\"><strong>Invoice ID</strong></td>\n <td style=\"border: 1px solid #ccc; padding: 8px;\">{{ $json.invoice_id }}</td>\n </tr>\n <tr>\n <td style=\"border: 1px solid #ccc; padding: 8px;\"><strong>Company Name</strong></td>\n <td style=\"border: 1px solid #ccc; padding: 8px;\">{{ $json.Shop_Name }}</td>\n </tr>\n <tr>\n <td style=\"border: 1px solid #ccc; padding: 8px;\"><strong>Date</strong></td>\n <td style=\"border: 1px solid #ccc; padding: 8px;\"> {{ $json.Date }} </td>\n </tr>\n <tr>\n <td style=\"border: 1px solid #ccc; padding: 8px;\"><strong>Total</strong></td>\n <td style=\"border: 1px solid #ccc; padding: 8px;\">{{ $json.Total_Amount }}</td>\n </tr>\n <tr>\n <td style=\"border: 1px solid #ccc; padding: 8px;\"><strong>Items</strong></td>\n <td style=\"border: 1px solid #ccc; padding: 8px;\">{{ $json.Item_Name }}</td>\n </tr>\n </table>\n\n <p style=\"margin-top:16px;\">✅ No changes were made to your sheet, since this record already exists.</p>\n <p>Kind regards,<br>Your Automated Invoice System</p>\n </body>\n</html>\n",
"options": {},
"subject": "=Invoice Already Exists – {{ $json.invoice_id }}"
},
"credentials": {
"gmailOAuth2": {
"id": "zystIXitEOECXALa",
"name": "Gmail account"
}
},
"typeVersion": 2.1
},
{
"id": "444d68a3-9a32-4caf-a930-2b4b83cc92d9",
"name": "使用payload添加新数据",
"type": "n8n-nodes-base.code",
"position": [
2064,
496
],
"parameters": {
"jsCode": "// Function Item node\n// This makes sure you always get the invoice JSON payload, even if Get data is empty.\n\n// 1. Get what Google Sheets returned\nconst sheetItem = $items(\"Get data\") && $items(\"Get data\")[0] \n ? $items(\"Get data\")[0].json \n : {};\n\n// 2. Check if it's empty\nconst sheetEmpty = Object.keys(sheetItem).length === 0;\n\n// 3. If empty → use your original invoice JSON instead\n// >>> REPLACE the placeholder below with the node that has your invoice JSON <<<\n// Example: $items(\"Edit Fields\")[0].json OR paste your raw invoice object\nconst invoicePayload = sheetEmpty \n ? (\n // 🔽 PLACEHOLDER: replace this line with your real JSON source\n $('Make data in json structure format').first().json.output\n )\n : sheetItem;\n\n// 4. Return only the payload JSON\nreturn invoicePayload;\n"
},
"typeVersion": 2
},
{
"id": "5f78f6aa-9b9a-46b5-8d92-5b2d8cc89be2",
"name": "将数据追加到表格",
"type": "n8n-nodes-base.googleSheets",
"position": [
3568,
480
],
"parameters": {
"columns": {
"value": {
"Date": "={{ $json.date }}",
"Time": "=",
"Type": "=",
"Status": "={{ $json.optional_fields.Status }}",
"Category": "=",
"Currency": "={{ $json.items[3].Currency }}",
"Entry_ID": "={{ $json.payload.invoice_id }}",
"GST_Rate": "={{ $json.optional_fields.GST_Rate }}",
"Quantity": "={{ $json.items.map(item => item.Quantity).join(', ') }}",
"Item_Name": "={{ $json.items.map(item => item.Item_Name).join(', ') }}",
"Shop_Name": "={{ $json.shop_name }}",
"GST_Amount": "={{ $json.optional_fields.GST_Amount }}",
"Unit_Price": "={{ $json.items.map(item => item.Unit_Price).join(', ') }}\n",
"invoice_id": "={{ $json.invoice_id }}",
"Description": "={{ $json.optional_fields.Description }}",
"Subcategory": "=",
"Created_Date": "={{ $json.date }}",
"Shop_Address": "={{ $json.optional_fields.Shop_Address }}",
"Total_Amount": "={{ $json.Total }}",
"Modified_Date": "={{ $json.optional_fields.Created_Date }}",
"Payment_Method": "={{ $json.optional_fields.Payment_Method }}"
},
"schema": [
{
"id": "Entry_ID",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Entry_ID",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Date",
"type": "string",
"display": true,
"required": false,
"displayName": "Date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Time",
"type": "string",
"display": true,
"required": false,
"displayName": "Time",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Type",
"type": "string",
"display": true,
"required": false,
"displayName": "Type",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Category",
"type": "string",
"display": true,
"required": false,
"displayName": "Category",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Subcategory",
"type": "string",
"display": true,
"required": false,
"displayName": "Subcategory",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Item_Name",
"type": "string",
"display": true,
"required": false,
"displayName": "Item_Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Description",
"type": "string",
"display": true,
"required": false,
"displayName": "Description",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Quantity",
"type": "string",
"display": true,
"required": false,
"displayName": "Quantity",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Unit",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Unit",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Unit_Price",
"type": "string",
"display": true,
"required": false,
"displayName": "Unit_Price",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Total_Amount",
"type": "string",
"display": true,
"required": false,
"displayName": "Total_Amount",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Currency",
"type": "string",
"display": true,
"required": false,
"displayName": "Currency",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Shop_Name",
"type": "string",
"display": true,
"required": false,
"displayName": "Shop_Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Shop_Address",
"type": "string",
"display": true,
"required": false,
"displayName": "Shop_Address",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Payment_Method",
"type": "string",
"display": true,
"required": false,
"displayName": "Payment_Method",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "GST_Rate",
"type": "string",
"display": true,
"required": false,
"displayName": "GST_Rate",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "GST_Amount",
"type": "string",
"display": true,
"required": false,
"displayName": "GST_Amount",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Receipt_Link",
"type": "string",
"display": true,
"required": false,
"displayName": "Receipt_Link",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Receipt_Number",
"type": "string",
"display": true,
"required": false,
"displayName": "Receipt_Number",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Remarks",
"type": "string",
"display": true,
"required": false,
"displayName": "Remarks",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Tags",
"type": "string",
"display": true,
"required": false,
"displayName": "Tags",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Created_Date",
"type": "string",
"display": true,
"required": false,
"displayName": "Created_Date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Modified_Date",
"type": "string",
"display": true,
"required": false,
"displayName": "Modified_Date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Status",
"type": "string",
"display": true,
"required": false,
"displayName": "Status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Duplicate_Check",
"type": "string",
"display": true,
"required": false,
"displayName": "Duplicate_Check",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "invoice_id",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "invoice_id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "shop_name",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "shop_name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "date",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Total",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Total",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "items",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "items",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "optional_fields",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "optional_fields",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"Entry_ID"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1240712847,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1T1oFlLqrauskPHAHbRixnIbx4wSK7pY3J5EGlpFzZTQ/edit#gid=1240712847",
"cachedResultName": "Expense_Tracker"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1T1oFlLqrauskPHAHbRixnIbx4wSK7pY3J5EGlpFzZTQ",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1T1oFlLqrauskPHAHbRixnIbx4wSK7pY3J5EGlpFzZTQ/edit?usp=drivesdk",
"cachedResultName": "expense_tracker_n8n"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "2cLBwxQBfcaJ1DCN",
"name": "Google Sheets account"
}
},
"typeVersion": 4.7
},
{
"id": "5042aa5c-5d27-4e91-bb34-48adbb466148",
"name": "检查必填字段",
"type": "n8n-nodes-base.code",
"position": [
2400,
496
],
"parameters": {
"jsCode": "// Function Item node\n// Check if mandatory fields are present before appending to Google Sheet\n\n// 1. Get the invoice payload (replace with your correct source node if needed)\nconst payload = $('Make data in json structure format').first().json.output;\n\n// 2. Define mandatory fields\nconst mandatoryFields = [\"invoice_id\", \"shop_name\", \"date\", \"Total\", \"items\"];\n\n// 3. Check missing fields\nconst missing = mandatoryFields.filter(f => {\n if (f === \"items\") {\n return !payload.items || !Array.isArray(payload.items) || payload.items.length === 0;\n }\n return !payload[f] || payload[f].toString().trim() === \"\";\n});\n\n// 4. If missing → return error\nif (missing.length > 0) {\n return {\n json: {\n status: \"error\",\n message: \"Missing Mandatory field(s)\",\n missing_fields: missing\n }\n };\n}\n\n// 5. If all present → return full payload\nreturn {\n json: {\n status: \"ok\",\n payload // 🔽 This is the invoice JSON you’ll pass to Google Sheets\n }\n};\n"
},
"typeVersion": 2
},
{
"id": "e9f03e55-74ba-4576-8807-0b34490a809f",
"name": "发送成功邮件",
"type": "n8n-nodes-base.gmail",
"position": [
3968,
480
],
"webhookId": "6ef65cb6-499f-4893-9739-b5f277bd8931",
"parameters": {
"sendTo": "xyz@gmail.com",
"message": "=<!doctype html>\n<html>\n<head>\n<meta charset=\"utf-8\" />\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\" />\n<style>\n /* Basic reset for email */\n body, table, td, a { -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }\n table { border-collapse: collapse !important; }\n img { border: 0; height: auto; line-height: 100%; outline: none; text-decoration: none; display: block; }\n body { margin: 0; padding: 0; width: 100% !important; font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif; background-color: #f4f6fb; color: #222; }\n\n /* Container */\n .email-wrap {\n width: 100%;\n padding: 28px 16px;\n background: linear-gradient(180deg, #f7f9ff 0%, #f4f6fb 100%);\n }\n .card {\n max-width: 680px;\n margin: 0 auto;\n background: #ffffff;\n border-radius: 14px;\n box-shadow: 0 10px 30px rgba(29,41,81,0.08);\n overflow: hidden;\n border: 1px solid rgba(29,41,81,0.04);\n }\n .card-header {\n padding: 28px 28px 18px 28px;\n background: linear-gradient(90deg,#5b8cff,#2d6df6);\n color: #fff;\n }\n .logo {\n font-weight: 700;\n letter-spacing: -0.2px;\n font-size: 18px;\n }\n .title {\n margin: 8px 0 0 0;\n font-size: 20px;\n font-weight: 700;\n }\n .card-body {\n padding: 22px 28px;\n }\n\n /* Info block */\n .info {\n display: flex;\n gap: 14px;\n flex-wrap: wrap;\n margin-bottom: 18px;\n }\n .info .info-item {\n flex: 1 1 240px;\n background: linear-gradient(180deg,#fbfdff,#f7f9ff);\n border-radius: 10px;\n padding: 12px 14px;\n border: 1px solid rgba(13,34,84,0.04);\n }\n .info .label {\n display: block;\n font-size: 12px;\n color: #5b6b8a;\n margin-bottom: 6px;\n }\n .info .value {\n font-weight: 600;\n color: #17233d;\n font-size: 15px;\n }\n\n /* Items & totals */\n .items {\n width: 100%;\n border-collapse: collapse;\n margin-top: 8px;\n margin-bottom: 14px;\n font-size: 14px;\n }\n .items th {\n text-align: left;\n font-size: 12px;\n font-weight: 700;\n color: #4b5b7a;\n padding: 8px 0;\n border-bottom: 1px solid rgba(72,84,112,0.06);\n }\n .items td {\n padding: 10px 0;\n color: #243142;\n vertical-align: top;\n }\n .items .muted { color: #73809a; font-weight: 500; font-size: 13px; }\n\n .total-row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding-top: 14px;\n border-top: 1px dashed rgba(29,41,81,0.06);\n margin-top: 10px;\n }\n .total-label { color: #5b6b8a; font-weight: 600; }\n .total-value {\n background: linear-gradient(90deg,#fff0f6,#fff);\n color: #d6336c;\n font-weight: 800;\n font-size: 18px;\n padding: 8px 14px;\n border-radius: 8px;\n border: 1px solid rgba(214,51,108,0.08);\n }\n\n /* Footer */\n .footer {\n padding: 18px 28px;\n font-size: 13px;\n color: #627089;\n background: #fbfdff;\n border-top: 1px solid rgba(29,41,81,0.02);\n }\n .cta {\n display:inline-block;\n margin-top: 10px;\n padding: 8px 14px;\n border-radius: 10px;\n font-weight: 700;\n text-decoration: none;\n color: #fff;\n background: linear-gradient(90deg,#2d6df6,#5b8cff);\n }\n\n /* Responsive */\n @media (max-width:480px) {\n .card-header { padding: 20px; }\n .card-body { padding: 16px; }\n .info { gap: 8px; }\n .info .info-item { flex-basis: 100%; }\n }\n</style>\n</head>\n<body>\n <div class=\"email-wrap\" role=\"article\" aria-label=\"Invoice notification\">\n <div class=\"card\" role=\"article\">\n <div class=\"card-header\">\n <div class=\"logo\">Invoice Bot</div>\n <div class=\"title\">New Invoice Added</div>\n </div>\n\n <div class=\"card-body\">\n <!-- Basic info -->\n <div class=\"info\" aria-hidden=\"false\">\n <div class=\"info-item\" role=\"group\" aria-label=\"Invoice ID\">\n <span class=\"label\">Invoice ID</span>\n <div class=\"value\">New INVOICE - {{ $json.invoice_id }}</div>\n </div>\n\n <div class=\"info-item\" role=\"group\" aria-label=\"Company name\">\n <span class=\"label\">Company</span>\n <div class=\"value\">{{ $json.Shop_Name }}</div>\n </div>\n\n <div class=\"info-item\" role=\"group\" aria-label=\"Date\">\n <span class=\"label\">Date</span>\n <div class=\"value\">{{ $json.Date }}</div>\n </div>\n </div>\n\n <!-- Items table -->\n <table class=\"items\" role=\"table\" aria-label=\"Invoice items\">\n <thead>\n <tr>\n <th>Items</th>\n <th style=\"text-align:right\">Price</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td class=\"muted\">{{ $json.Item_Name }}</td>\n <td style=\"text-align:right;\" class=\"muted\">{{ $json.Total_Amount }}</td>\n </tr>\n </tbody>\n </table>\n\n <!-- Total -->\n <div class=\"total-row\" role=\"note\" aria-live=\"polite\">\n <div class=\"total-label\">Total</div>\n <div class=\"total-value\">{{ $json.Total_Amount }}</div>\n </div>\n\n <!-- Call to action / small note -->\n <div style=\"margin-top:16px; font-size:13px; color:#5b6b8a;\">\n Saved to your sheet and Drive. <a href=\"#\" class=\"cta\">Open Dashboard</a>\n </div>\n </div>\n\n <div class=\"footer\">\n <div>Auto-synced by your Invoice System • <strong>{{ $json.invoice_id }}</strong></div>\n <div style=\"margin-top:8px;\">If something looks off, check the original file in your Drive or open the dashboard to edit.</div>\n </div>\n </div>\n </div>\n</body>\n</html>\n",
"options": {},
"subject": "=New invoice - {{ $json.invoice_id }} added in the sheet. "
},
"credentials": {
"gmailOAuth2": {
"id": "zystIXitEOECXALa",
"name": "Gmail account"
}
},
"typeVersion": 2.1
},
{
"id": "3a1e1818-7feb-4a7a-9d9d-a98b7bbb3c77",
"name": "便签2",
"type": "n8n-nodes-base.stickyNote",
"position": [
368,
352
],
"parameters": {
"color": 5,
"width": 384,
"height": 512,
"content": "# 节点3:AI Agent1"
},
"typeVersion": 1
},
{
"id": "016dec77-8044-4bf1-91e2-04347f01b81e",
"name": "便签1",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
352
],
"parameters": {
"color": 3,
"width": 352,
"height": 496,
"content": "## 节点2:**分析图片1**"
},
"typeVersion": 1
},
{
"id": "d04bddae-b8e8-4bdb-a12b-4cad195b739f",
"name": "便签3",
"type": "n8n-nodes-base.stickyNote",
"position": [
368,
880
],
"parameters": {
"color": 6,
"width": 384,
"height": 544,
"content": ""
},
"typeVersion": 1
},
{
"id": "7e2078a0-b8ee-48dc-9649-06695fa7b10b",
"name": "便签4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1152,
352
],
"parameters": {
"width": 368,
"height": 512,
"content": "## 节点6:**获取数据**"
},
"typeVersion": 1
},
{
"id": "b147bb54-67f2-41fd-9f58-e68f58e82dfc",
"name": "便签5",
"type": "n8n-nodes-base.stickyNote",
"position": [
768,
352
],
"parameters": {
"color": 2,
"width": 368,
"height": 512,
"content": "## 节点5:**将数据转换为JSON结构格式**"
},
"typeVersion": 1
},
{
"id": "4fe6abc8-d092-4ae5-aab9-76b31d157e65",
"name": "便签6",
"type": "n8n-nodes-base.stickyNote",
"position": [
1936,
160
],
"parameters": {
"color": 4,
"width": 336,
"height": 496,
"content": "## 节点8:**使用payload添加新数据**"
},
"typeVersion": 1
},
{
"id": "65ff906c-24b0-43fb-af3a-ed8b2382057f",
"name": "便签7",
"type": "n8n-nodes-base.stickyNote",
"position": [
2288,
160
],
"parameters": {
"color": 3,
"width": 336,
"height": 496,
"content": "## 节点9:**检查必填字段**"
},
"typeVersion": 1
},
{
"id": "257b48c4-2f8d-4ead-9d45-37b5130151a6",
"name": "便签8",
"type": "n8n-nodes-base.stickyNote",
"position": [
2640,
160
],
"parameters": {
"color": 5,
"width": 352,
"height": 496,
"content": "## 节点10:**如果 – 检查缺失字段**"
},
"typeVersion": 1
},
{
"id": "d36fab00-4dc9-44e9-b071-e77500233c3c",
"name": "便签9",
"type": "n8n-nodes-base.stickyNote",
"position": [
3008,
160
],
"parameters": {
"width": 400,
"height": 496,
"content": "## 节点11:**无缺失字段 – 使用payload 2添加新数据**"
},
"typeVersion": 1
},
{
"id": "c1e60d32-3270-4440-ab23-dd8f0a3fe778",
"name": "便签 10",
"type": "n8n-nodes-base.stickyNote",
"position": [
3424,
160
],
"parameters": {
"color": 5,
"width": 384,
"height": 496,
"content": "## 节点12:**将数据追加到表格**"
},
"typeVersion": 1
},
{
"id": "7641cc35-64e1-439d-84bb-4631737d7dd8",
"name": "便签 11",
"type": "n8n-nodes-base.stickyNote",
"position": [
3824,
160
],
"parameters": {
"width": 384,
"height": 496,
"content": "## 节点13:**发送成功邮件**"
},
"typeVersion": 1
},
{
"id": "89bd82ca-4f6b-42eb-8899-517915dfb83e",
"name": "便签12",
"type": "n8n-nodes-base.stickyNote",
"position": [
1536,
352
],
"parameters": {
"color": 3,
"width": 384,
"height": 512,
"content": "## 节点7:**检查表中数据是否存在**"
},
"typeVersion": 1
},
{
"id": "6b96884c-eefe-4ec5-a5ce-e148e2130901",
"name": "便签13",
"type": "n8n-nodes-base.stickyNote",
"position": [
1936,
672
],
"parameters": {
"width": 400,
"height": 512,
"content": "## 节点8.1:**重复条目发送邮件**"
},
"typeVersion": 1
},
{
"id": "9b5aeb91-0f7f-465a-b774-bb1f5fed0869",
"name": "便签14",
"type": "n8n-nodes-base.stickyNote",
"position": [
3264,
672
],
"parameters": {
"color": 3,
"width": 448,
"height": 496,
"content": "## 节点11.1:**通过邮件发送缺失字段错误**"
},
"typeVersion": 1
},
{
"id": "374ea423-b33d-4e4e-9a3e-ec3adbffbbbe",
"name": "便签15",
"type": "n8n-nodes-base.stickyNote",
"position": [
-96,
864
],
"parameters": {
"color": 5,
"width": 448,
"height": 480,
"content": ""
},
"typeVersion": 1
}
],
"active": true,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "d48a8383-b848-421a-885c-6a06a77392e2",
"connections": {
"Get data": {
"main": [
[
{
"node": "check if Data exist or not in table",
"type": "main",
"index": 0
}
]
]
},
"AI Agent1": {
"main": [
[
{
"node": "Make data in json structure format",
"type": "main",
"index": 0
}
]
]
},
"Analyze image1": {
"main": [
[
{
"node": "AI Agent1",
"type": "main",
"index": 0
}
]
]
},
"Append data to sheet": {
"main": [
[
{
"node": "Send successful email",
"type": "main",
"index": 0
}
]
]
},
"Check Mandatory fields": {
"main": [
[
{
"node": "If - check missing field",
"type": "main",
"index": 0
}
]
]
},
"Upload invoice to drive": {
"main": [
[]
]
},
"Google Gemini Chat Model1": {
"ai_languageModel": [
[
{
"node": "AI Agent1",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"If - check missing field": {
"main": [
[
{
"node": "no missing field - new data add using payload 2 ",
"type": "main",
"index": 0
}
],
[
{
"node": "Send missing field error on mail",
"type": "main",
"index": 0
}
]
]
},
"New data add using payload": {
"main": [
[
{
"node": "Check Mandatory fields",
"type": "main",
"index": 0
}
]
]
},
"When chat message received": {
"main": [
[
{
"node": "Analyze image1",
"type": "main",
"index": 0
},
{
"node": "Upload invoice to drive",
"type": "main",
"index": 0
}
]
]
},
"Make data in json structure format": {
"main": [
[
{
"node": "Get data",
"type": "main",
"index": 0
}
]
]
},
"check if Data exist or not in table": {
"main": [
[
{
"node": "New data add using payload",
"type": "main",
"index": 0
}
],
[
{
"node": "Duplicate entry send mail",
"type": "main",
"index": 0
}
]
]
},
"no missing field - new data add using payload 2 ": {
"main": [
[
{
"node": "Append data to sheet",
"type": "main",
"index": 0
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
高级 - 发票处理, AI 摘要总结
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
第一轮 Telegram 和 LinkedIn 快速通道 AI 招聘助手
AI候选人筛选流程:LinkedIn到Telegram,集成Gemini与Apify
If
Set
Code
+15
55 节点Dean Pike
人力资源
竞争对手内容差距分析器:自动化网站主题映射
使用Gemini AI、Apify和Google Sheets分析竞争对手内容差距
If
Set
Code
+10
30 节点Mychel Garzon
杂项
自动化学术论文元数据及变量提取,从Gemini到Google Sheets
自动化学术论文元数据及变量提取,从Gemini到Google Sheets
Set
Code
Wait
+14
39 节点OwenLee
文档提取
电子邮件扫描和Google表格采购订单创建
使用Gemini AI从Gmail提取采购订单并保存至Google表格
If
Set
Code
+8
15 节点Sayone Technologies
文档提取
欺诈预订检测器:使用AI识别可疑旅行交易
欺诈预订检测器:使用Google Gemini识别可疑旅行交易
If
Set
Code
+8
20 节点Oneclick AI Squad
安全运维
选题捕手模板
使用Gemini分析Reddit、YouTube和X生成内容策略报告
If
Set
Code
+14
34 节点Sheryl
市场调研