- Blog
- n8n Hands-On Guide 10: Building an Invoice Processing Bot (Part 2)
n8n Hands-On Guide 10: Building an Invoice Processing Bot (Part 2)
In the previous article, we extracted the invoice information and saved it to Google Sheets. Next, we will send the key information to our email.
https://appstore.lazycat.cloud/#/shop/detail/cloud.lazycat.app.n8n
Extract Email Address
This step requires extracting the email address we entered in the first step. Reference code:
const raw = $('When chat message received').first().json.chatInput|| "";
// Match the first email format
const match = raw.match(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/);
return [
{
json: {
email: match ? match[0] : null
}
}
];
After execution, you can see it extracts correctly.

If Condition
In this step, if an email address was identified and it is not empty, proceed to the next step.

Send Email
Before sending the email, you can rename our previous nodes for easier reference.

Go back to the Google Console. Click on "APIs & Services".

Search for Gmail here.

Enable the API permissions.

Now, go back to n8n and create a new credential. Enter the Client ID and Secret.

A prompt will appear upon successful authorization.

Select "Send" for the operation. The email address is the one we extracted.

Set the message type to HTML. Refer to the code below for the message content.
<div style="font-family: Arial, Helvetica, sans-serif; color:#222; line-height:1.6; max-width:720px; margin:0 auto; border:1px solid #eee; border-radius:8px; overflow:hidden;">
<!-- Header Title -->
<div style="background:#f6f8fa; padding:16px 20px; border-bottom:1px solid #eee;">
<div style="font-size:18px; font-weight:700;">
{{ $('GoogleSheets').first().json["Invoice Title"] || "Invoice" }}
</div>
<div style="font-size:13px; color:#666;">
Invoice Number:{{ $('GoogleSheets').first().json["Invoice Number"] || "" }}
Issue Date:{{ $('GoogleSheets').first().json["Issue Date"] || "" }}
</div>
</div>
<!-- Buyer/Seller -->
<table role="presentation" cellspacing="0" cellpadding="0" style="width:100%; border-collapse:collapse;">
<tr>
<td style="padding:16px 20px; width:50%; vertical-align:top; border-right:1px solid #f0f0f0;">
<div style="font-weight:700; margin-bottom:6px;">Buyer Information</div>
<div>Name:{{ $('GoogleSheets').first().json["Buyer Name"] || "" }}</div>
<div>Tax ID:{{ $('GoogleSheets').first().json["Buyer Tax ID"] || "" }}</div>
<div style="color:#666;">Remarks:{{ $('GoogleSheets').first().json["Buyer Remarks"] || "" }}</div>
</td>
<td style="padding:16px 20px; width:50%; vertical-align:top;">
<div style="font-weight:700; margin-bottom:6px;">Seller Information</div>
<div>Name:{{ $('GoogleSheets').first().json["Seller Name"] || "" }}</div>
<div>Tax ID:{{ $('GoogleSheets').first().json["Seller Tax ID"] || "" }}</div>
</td>
</tr>
</table>
<!-- Line Items -->
<div style="padding:0 20px 16px 20px;">
<div style="font-weight:700; margin:6px 0 8px;">Product / Service Details</div>
<table role="presentation" cellspacing="0" cellpadding="0" style="width:100%; border-collapse:collapse; border:1px solid #eee;">
<thead>
<tr style="background:#fafbfc;">
<th style="text-align:left; padding:10px; border-bottom:1px solid #eee;">Product Name</th>
<th style="text-align:left; padding:10px; border-bottom:1px solid #eee;">Specification Model</th>
<th style="text-align:center; padding:10px; border-bottom:1px solid #eee;">Unit</th>
<th style="text-align:right; padding:10px; border-bottom:1px solid #eee;">Quantity</th>
<th style="text-align:right; padding:10px; border-bottom:1px solid #eee;">Unit Price</th>
<th style="text-align:right; padding:10px; border-bottom:1px solid #eee;">Amount (Excl. Tax)</th>
<th style="text-align:right; padding:10px; border-bottom:1px solid #eee;">Tax Rate</th>
<th style="text-align:right; padding:10px; border-bottom:1px solid #eee;">Tax Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding:10px; border-bottom:1px solid #f5f5f5;">{{ $('GoogleSheets').first().json["Product Name"] || "" }}</td>
<td style="padding:10px; border-bottom:1px solid #f5f5f5;">{{ $('GoogleSheets').first().json["Specification Model"] || "" }}</td>
<td style="padding:10px; text-align:center; border-bottom:1px solid #f5f5f5;">{{ $('GoogleSheets').first().json["Unit"] || "" }}</td>
<td style="padding:10px; text-align:right; border-bottom:1px solid #f5f5f5;">{{ $('GoogleSheets').first().json["Quantity"] || "" }}</td>
<td style="padding:10px; text-align:right; border-bottom:1px solid #f5f5f5;">¥{{ parseFloat($('GoogleSheets').first().json["Unit Price"] || 0).toFixed(2) }}</td>
<td style="padding:10px; text-align:right; border-bottom:1px solid #f5f5f5;">¥{{ parseFloat($('GoogleSheets').first().json["Amount Excl. Tax"] || 0).toFixed(2) }}</td>
<td style="padding:10px; text-align:right; border-bottom:1px solid #f5f5f5;">
{{ $('GoogleSheets').first().json["Tax Rate Display"] || (parseFloat($('GoogleSheets').first().json["Tax Rate"] || 0)*100).toFixed(0) + "%" }}
</td>
<td style="padding:10px; text-align:right; border-bottom:1px solid #f5f5f5;">¥{{ parseFloat($('GoogleSheets').first().json["Tax Amount"] || 0).toFixed(2) }}</td>
</tr>
</tbody>
</table>
</div>
<!-- Total -->
<div style="padding:0 20px 20px 20px;">
<table role="presentation" cellspacing=```html
0" cellpadding="0" style="margin-left:auto; border-collapse:collapse;">
<tr>
<td style="padding:6px 12px; color:#666;">Total Amount (Excluding Tax):</td>
<td style="padding:6px 12px; text-align:right; font-weight:700;">
¥{{ parseFloat($('GoogleSheets').first().json["合计不含税金额"] || 0).toFixed(2) }}
</td>
</tr>
<tr>
<td style="padding:6px 12px; color:#666;">Total Tax Amount:</td>
<td style="padding:6px 12px; text-align:right; font-weight:700;">
¥{{ parseFloat($('GoogleSheets').first().json["合计税额"] || 0).toFixed(2) }}
</td>
</tr>
<tr>
<td style="padding:6px 12px; color:#666;">Total Amount (Including Tax):</td>
<td style="padding:6px 12px; text-align:right; font-weight:700;">
¥{{ parseFloat($('GoogleSheets').first().json["合计价税合计金额"] || 0).toFixed(2) }}
</td>
</tr>
</table>
</div>
<!-- Footer -->
<div style="padding:10px 20px; background:#f9fafb; border-top:1px solid #eee; font-size:13px; color:#555;">
Issued By: {{ $('GoogleSheets').first().json["开票人"] || "" }}
</div>
</div>
Open it to check - if there's no red highlighting and you can see the data, it means everything is working normally.

Click Execute, and the output result is normal.

The email has been received.

Open the email to view the content:

The above is the complete workflow of the invoice processing bot.
If you want to save time, you can directly import my JSON file and then configure your own nodes by referring to the guide.
{
"name": "analyze image and send email",
"nodes": [
{
"parameters": {
"jsCode": "// n8n Code Node - Invoice Data Parsing\n// Get input data (handling possible string format)\nconst inputData = $input.first().json.choices[0].message.content;\n\n// If input is a string, parse it as JSON first\nlet invoiceData;\nif (typeof inputData === 'string') {\n // Remove possible markdown code block markers\n const cleanData = inputData.replace(/^```json\\s*/, '').replace(/\\s*```$/, '').trim();\n invoiceData = JSON.parse(cleanData);\n} else {\n invoiceData = inputData;\n}\n\n// Extract invoice data\nconst invoice = invoiceData.invoice;\n\n// Return flattened JSON data\nreturn [{\n json: {\n title: invoice.title,\n invoiceNumber: invoice.number,\n issueDate: invoice.issue_date,\n currency: invoice.currency,\n issuer: invoice.issuer,\n buyerName: invoice.buyer.name,\n buyerTaxId: invoice.buyer.tax_id,\n buyerNote: invoice.buyer.note,\n sellerName: invoice.seller.name,\n sellerTaxId: invoice.seller.tax_id,\n itemName: invoice.items[0].name,\n itemSpec: invoice.items[0].spec,\n itemUnit: invoice.items[0].unit,\n quantity: invoice.items[0].quantity,\n unitPrice: invoice.items[0].unit_price,\n amountWithoutTax: invoice.items[0].amount_without_tax,\n taxRate: invoice.items[0].tax_rate,\n taxRateDisplay: invoice.items[0].tax_rate_display,\n taxAmount: invoice.items[0].tax_amount,\n subtotal: invoice.totals.amount_without_tax,\n totalTax: invoice.totals.tax_total,\n grandTotal: invoice.totals.amount_with_tax\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
0,
200
],
"id": "70bef82b-f44f-4389-adc2-d1e41a1ef12a",
"name": "Code"
},
{
"parameters": {
"operation": "append",
"documentId": {
"__rl": true,
"value": "1M6GJAC6j3fvzZd2EImGSyugzLRKwa_Ok5ODnL6q4PWo",
"mode": "list",
"cachedResultName": "Invoice",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1M6GJAC6j3fvzZd2EImGSyugzLRKwa_Ok5ODnL6q4PWo/edit?usp=drivesdk"
},
"sheetName": {
"__rl": true,
"value": "gid=0",
"mode": "list",
"cachedResultName": "Sheet1",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1M6GJAC6j3fvzZd2EImGSyugzLRKwa_Ok5ODnL6q4PWo/edit#gid=0"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"Invoice Title": "={{ $json.title }}",
"Invoice Number": "={{ $json.invoiceNumber }}",
"Issue Date": "={{ $json.issueDate }}",
"Buyer Name": "={{ $json.buyerName }}",
"Buyer Tax ID": "={{ $json.buyerTaxId }}",
"Buyer Note": "={{ $json.buyerNote }}",
"Seller Name": "={{ $json.sellerName }}",
"Product Name": "={{ $json.itemName }}",
"Seller Tax ID": "={{ $json.sellerTaxId }}",
"Specification": "={{ $json.itemSpec }}",
"Unit": "={{ $json.itemUnit }}",
"Quantity": "={{ $json.quantity }}",
"Unit Price": "={{ $json.unitPrice }}",
"Amount Without Tax": "={{ $json.amountWithoutTax }}",
"Tax Rate": "={{ $json.taxRate }}",
"Tax Rate Display": "={{ $json.taxRateDisplay }}",
"Tax Amount": "={{ $json.taxAmount }}",
"Subtotal (Excluding Tax)": "={{ $json.subtotal }}",
"Total Tax Amount": "={{ $json.totalTax }}",
"Grand Total (Including Tax)": "={{ $json.grandTotal }}",
"Issued By": "={{ $json.issuer }}"
},
"matchingColumns": [],
"schema": [
{
"id": "Invoice Title",
"displayName": "Invoice Title",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "Invoice Number",
"displayName": "Invoice Number",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "Issue Date",
"displayName": "Issue Date",
"required": false,
"defaultMatch": false,
"display": true,
"type": "s
```tring",
"canBeUsedToMatch": true
},
{
"id": "购方名称",
"displayName": "Buyer Name",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "购方税号",
"displayName": "Buyer Tax ID",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "购方备注",
"displayName": "Buyer Remarks",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "销方名称",
"displayName": "Seller Name",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "销方税号",
"displayName": "Seller Tax ID",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "商品名称",
"displayName": "Product Name",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "规格型号",
"displayName": "Specification Model",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "单位",
"displayName": "Unit",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "数量",
"displayName": "Quantity",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "单价",
"displayName": "Unit Price",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "不含税金额",
"displayName": "Tax-Exclusive Amount",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "税率",
"displayName": "Tax Rate",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "税率显示",
"displayName": "Tax Rate Display",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "税额",
"displayName": "Tax Amount",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "合计不含税金额",
"displayName": "Total Tax-Exclusive Amount",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "合计税额",
"displayName": "Total Tax Amount",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "合计价税合计金额",
"displayName": "Total Amount Including Tax",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "开票人",
"displayName": "Issuer",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {}
},
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.6,
"position": [
260,
80
],
"id": "9a9b3088-7722-4dd5-b2b7-28726fd64f8f",
"name": "Google Sheets",
"credentials": {
"googleSheetsOAuth2Api": {
"id": "jflKNS6HMBOKZok2",
"name": "Google Sheets account"
}
}
},
{
"parameters": {
"jsCode": "const raw = $('When chat message received').first().json.chatInput|| \"\";\n\n// Match the first email format\nconst match = raw.match(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/);\n\nreturn [\n {\n json: {\n email: match ? match[0] : null\n }\n }\n];\n"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
420,
-80
],
"id": "5e71f0be-bebb-42ac-9d64-413d98b4e5db",
"name": "Code1"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "","typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "a44e6c17-4473-4dfe-bab9-5c98caa8fa31",
"leftValue": "={{ $json.email }}",
"rightValue": "",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
640,
-80
],
"id": "e50264b2-51e1-4c2a-bb0d-66447b6f3b0d",
"name": "If"
},
{
"parameters": {
"sendTo": "={{ $json.email }}",
"subject": "Invoice",
"message": "=<div style=\"font-family: Arial, Helvetica, sans-serif; color:#222; line-height:1.6; max-width:720px; margin:0 auto; border:1px solid #eee; border-radius:8px; overflow:hidden;\">\n <!-- Header -->\n <div style=\"background:#f6f8fa; padding:16px 20px; border-bottom:1px solid #eee;\">\n <div style=\"font-size:18px; font-weight:700;\">\n {{ $('Google Sheets').item.json[\"Invoice Title\"] || \"Invoice\" }}\n </div>\n <div style=\"font-size:13px; color:#666;\">\n Invoice Number: {{ $('Google Sheets').item.json[\"Invoice Number\"] || \"\" }} \n Issue Date: {{ $('Google Sheets').item.json[\"Issue Date\"] || \"\" }} \n \n </div>\n </div>\n\n <!-- Buyer/Seller Information -->\n <table role=\"presentation\" cellspacing=\"0\" cellpadding=\"0\" style=\"width:100%; border-collapse:collapse;\">\n <tr>\n <td style=\"padding:16px 20px; width:50%; vertical-align:top; border-right:1px solid #f0f0f0;\">\n <div style=\"font-weight:700; margin-bottom:6px;\">Buyer Information</div>\n <div>Name: {{ $('Google Sheets').item.json[\"Buyer Name\"] || \"\" }}</div>\n <div>Tax ID: {{ $('Google Sheets').item.json[\"Buyer Tax ID\"] || \"\" }}</div>\n <div style=\"color:#666;\">Notes: {{ $('Google Sheets').item.json[\"Buyer Notes\"] || \"\" }}</div>\n </td>\n <td style=\"padding:16px 20px; width:50%; vertical-align:top;\">\n <div style=\"font-weight:700; margin-bottom:6px;\">Seller Information</div>\n <div>Name: {{ $('Google Sheets').item.json[\"Seller Name\"] || \"\" }}</div>\n <div>Tax ID: {{ $('Google Sheets').item.json[\"Seller Tax ID\"] || \"\" }}</div>\n </td>\n </tr>\n </table>\n\n <!-- Line Items -->\n <div style=\"padding:0 20px 16px 20px;\">\n <div style=\"font-weight:700; margin:6px 0 8px;\">Product / Service Details</div>\n <table role=\"presentation\" cellspacing=\"0\" cellpadding=\"0\" style=\"width:100%; border-collapse:collapse; border:1px solid #eee;\">\n <thead>\n <tr style=\"background:#fafbfc;\">\n <th style=\"text-align:left; padding:10px; border-bottom:1px solid #eee;\">Product Name</th>\n <th style=\"text-align:left; padding:10px; border-bottom:1px solid #eee;\">Specification</th>\n <th style=\"text-align:center; padding:10px; border-bottom:1px solid #eee;\">Unit</th>\n <th style=\"text-align:right; padding:10px; border-bottom:1px solid #eee;\">Quantity</th>\n <th style=\"text-align:right; padding:10px; border-bottom:1px solid #eee;\">Unit Price</th>\n <th style=\"text-align:right; padding:10px; border-bottom:1px solid #eee;\">Amount (excl. tax)</th>\n <th style=\"text-align:right; padding:10px; border-bottom:1px solid #eee;\">Tax Rate</th>\n <th style=\"text-align:right; padding:10px; border-bottom:1px solid #eee;\">Tax Amount</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td style=\"padding:10px; border-bottom:1px solid #f5f5f5;\">{{ $('Google Sheets').item.json[\"Product Name\"] || \"\" }}</td>\n <td style=\"padding:10px; border-bottom:1px solid #f5f5f5;\">{{ $('Google Sheets').item.json[\"Specification\"] || \"\" }}</td>\n <td style=\"padding:10px; text-align:center; border-bottom:1px solid #f5f5f5;\">{{ $('Google Sheets').item.json[\"Unit\"] || \"\" }}</td>\n <td style=\"padding:10px; text-align:right; border-bottom:1px solid #f5f5f5;\">{{ $('Google Sheets').item.json[\"Quantity\"] ?? \"\" }}</td>\n <td style=\"padding:10px; text-align:right; border-bottom:1px solid #f5f5f5;\">{{ Number($('Google Sheets').item.json[\"Unit Price\"] ?? 0).toFixed(6) }}</td>\n <td style=\"padding:10px; text-align:right; border-bottom:1px solid #f5f5f5;\">{{ Number($('Google Sheets').item.json[\"Amount (excl. tax)\"] ?? 0).toFixed(2) }}</td>\n <td style=\"padding:10px; text-align:right; border-bottom:1px solid #f5f5f5;\">\n {{ $('Google Sheets').item.json[\"Display Tax Rate\"] || (Number($('Google Sheets').item.json[\"Tax Rate\"] ?? 0)*100).toFixed(0) + \"%\" }}\n </td>\n <td style=\"padding:10px; text-align:right; border-bottom:1px solid #f5f5f5;\">{{ Number($('Google Sheets').item.json[\"Tax Amount\"] ?? 0).toFixed(2) }}</td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <!-- Totals -->\n <div style=\"padding:0 20px 20px 20px;\">\n <table role=\"presentation\" cellspacing=\"0\" cellpadding=\"0\" style=\"margin-left:auto; border-collapse:collapse;\">\n <tr>\n <td style=\"padding:6px 12px; color:#666;\">Total Amount (excl. tax):</td>\n <td style=\"padding:6px 12px; text-align:right; font-weight:700;\">\n {{ Number($('Google Sheets').item.json[\"Total Amount (excl. tax)\"] ?? 0).toFixed(2) }}\n </td>\n </tr>\n <tr>\n <td style=\"padding:6px 12px; color:#666;\">Total Tax Amount:</td>\n <td style=\"padding:6px 12px; text-align:right; font-weight:700;\">\n {{ Number($('Google Sheets').item.json[\"Total Tax Amount\"] ?? 0).toFixed(2) }}\n </td>\n </tr>\n <tr>\n <td style=\"padding:6px 12px; color:#666;\">Total Amount (incl. tax):</td>\n <td style=\"padding:6px 12px; text-align:right; font-weight:700;\">\n {{ Number($('Google Sheets').item.json[\"Total Amount (incl. tax)\"] ?? 0).toFixed(2) }}\n </td>\n </tr>\n </table>\n </div>\n\n <!-- Footer -->\n <div style=\"padding:10px 20px; background:#f9fafb; border-top:1px solid #eee; font-size:13px; color:#555;\">\n Iss```json
{
"parameters": {
"message": "...\n <div>\n Issuer: {{ $('Google Sheets').item.json[\"开票人\"] || \"\" }}\n </div>\n</div>\n",
"options": {}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
1060,
-60
],
"id": "16486451-dabf-48d7-98a9-77851add9d47",
"name": "Gmail",
"webhookId": "7f924497-ae8b-4b4e-8cad-3b4cd7a162d9",
"credentials": {
"gmailOAuth2": {
"id": "lLR0rjkd7MVl0WuY",
"name": "Gmail account"
}
}
},
{
"parameters": {
"options": {
"allowFileUploads": true
}
},
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"typeVersion": 1.1,
"position": [
-760,
200
],
"id": "7e8689a3-250d-466a-a4b1-1e42a8f014d4",
"name": "When chat message received",
"webhookId": "d7c99574-86d3-42f4-adf2-69f9fc1f7d3d"
},
{
"parameters": {
"method": "POST",
"url": "https://api.imgbb.com/1/upload?expiration=6000&key=80ddf220f655b5887b8a5eeee2a3652e",
"sendBody": true,
"contentType": "multipart-form-data",
"bodyParameters": {
"parameters": [
{
"parameterType": "formBinaryData",
"name": "image",
"inputDataFieldName": "data0"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
-560,
200
],
"id": "0849a0c5-dafc-4af7-ac7d-8b463df5abb9",
"name": "IMGBB"
},
{
"parameters": {
"method": "POST",
"url": "https://api.gpt.ge/v1/chat/completions",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"model\": \"gpt-4o\",\n \"messages\": [\n {\n \"role\": \"user\",\n \"content\": [\n {\n \"type\": \"text\",\n \"text\": \"## Role\\nYou are a professional \\\"Invoice Information Extractor\\\". The input is invoice text (possibly from OCR, email body, or chat paste), and the output is strictly valid JSON suitable for direct writing to databases/Google Sheets.\\n## Task\\nIdentify and extract fields from the given invoice text, returning a single JSON object placed within a markdown code block (json ... ). Do not output any explanations, comments, or extra characters.\\n## Output Requirements\\nOutput only one JSON code block without any additional text.\\nUse null for any non-existent or uncertain values.\\nDates should be uniformly formatted as YYYY-MM-DD (ISO 8601).\\nUse number types (not strings) for amount/quantity fields, preserving precision but without currency symbols or thousand separators.\\nUse decimals for tax rates (e.g., 1% → 0.01), and also provide display fields (e.g., \\\"1%\\\").\\nThe items array must exist; if there are no line items, output an empty array [].\\n## Field Definition (Schema)\\n{\\n \\\"invoice\\\": {\\n \\\"title\\\": \\\"string|null\\\",\\n \\\"number\\\": \\\"string|null\\\",\\n \\\"issue_date\\\": \\\"YYYY-MM-DD|null\\\",\\n \\\"currency\\\": \\\"string|null\\\",\\n \\\"buyer\\\": {\\n \\\"name\\\": \\\"string|null\\\",\\n \\\"tax_id\\\": \\\"string|null\\\",\\n \\\"note\\\": \\\"string|null\\\"\\n },\\n \\\"seller\\\": {\\n \\\"name\\\": \\\"string|null\\\",\\n \\\"tax_id\\\": \\\"string|null\\\"\\n },\\n \\\"items\\\": [\\n {\\n \\\"name\\\": \\\"string|null\\\",\\n \\\"spec\\\": \\\"string|null\\\",\\n \\\"unit\\\": \\\"string|null\\\",\\n \\\"quantity\\\": \\\"number|null\\\",\\n \\\"unit_price\\\": \\\"number|null\\\",\\n \\\"amount_without_tax\\\": \\\"number|null\\\",\\n \\\"tax_rate\\\": \\\"number|null\\\",\\n \\\"tax_rate_display\\\": \\\"string|null\\\",\\n \\\"tax_amount\\\": \\\"number|null\\\"\\n }\\n ],\\n \\\"totals\\\": {\\n \\\"amount_without_tax\\\": \\\"number|null\\\",\\n \\\"tax_total\\\": \\\"number|null\\\",\\n \\\"amount_with_tax\\\": \\\"number|null\\\"\\n },\\n \\\"issuer\\\": \\\"string|null\\\"\\n }\\n}\"\n },\n {\n \"type\": \"image_url\",\n \"image_url\": {\n \"url\": \"{{ $json.data.url }}\"\n }\n }\n ]\n }\n ]\n} ",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
-240,
200
],
"id": "24b25ed1-18d8-4c8a-9d2e-d903168e9b8e",
"name": "Identify Image",
"retryOnFail": true,
"credentials": {
"httpHeaderAuth": {
"id": "BKtGro8HEgz5LcZM",
"name": "V3 Header Auth account"
}
}
}
],
"pinData": {},
"connections": {
"Code": {
"main": [
[
{
"node": "Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"Google Sheets": {
"main": [
[
{
"node": "Code1",
"type": "main",
"index": 0
}
]
]
},
"Code1": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"If": {
"main": [
[
{
"node": "Gmail",
"type": "main",
"index": 0
}
]
]
},
"When chat message received": {
"main": [
[
{
"node": "IMGBB",
"type": "main",
"index": 0
}
]
]
},
"IMGBB": {
"main": [
[
{
"node": "Identify Image",
"type": "main",
"index": 0
}
]
]
},
"Identify Image": {
"main": [
[
{
"node": "Code",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "fb865209-ec18-41a
```6-b252-def147580997",
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "3cb07a731a78af260d8c81716bfc0e842ef01e898e945b902a3871e6a1cd0d48"
},
"id": "OWymQVChmL3XifYL",
"tags": []
}
