This workflow follows the Emailreadimap → Emailsend recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "Invoice Processing Automation",
"nodes": [
{
"parameters": {
"mailbox": "INBOX",
"subject": "Invoice",
"format": "raw",
"downloadAttachments": true,
"options": {}
},
"id": "inv1a2b3c-1111-2222-3333-444455556666",
"name": "Email Trigger",
"type": "n8n-nodes-base.emailReadImap",
"typeVersion": 2,
"position": [
250,
300
]
},
{
"parameters": {
"operation": "upload",
"driveId": {
"__rl": true,
"value": "YOUR_GOOGLE_DRIVE_ID",
"mode": "id"
},
"folderId": {
"__rl": true,
"value": "YOUR_INVOICES_FOLDER_ID",
"mode": "id"
},
"fileName": "={{ $binary.attachment.fileName }}",
"inputDataFieldName": "attachment",
"options": {}
},
"id": "inv2b3c4d-2222-3333-4444-555566667777",
"name": "Save to Google Drive",
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
480,
300
]
},
{
"parameters": {
"modelId": {
"__rl": true,
"value": "gpt-4-vision-preview",
"mode": "id"
},
"messages": {
"values": [
{
"content": "=Extract invoice information from this document:\n\nInvoice Image:\n{{ $binary.attachment.data }}\n\nExtract and return JSON with:\n- invoice_number (string)\n- invoice_date (YYYY-MM-DD format)\n- due_date (YYYY-MM-DD format)\n- vendor_name (string)\n- vendor_address (string)\n- vendor_tax_id (string)\n- subtotal (number)\n- tax_amount (number)\n- tax_percentage (number)\n- total_amount (number)\n- currency (string)\n- line_items (array of objects with: description, quantity, unit_price, total)\n- payment_terms (string)\n- purchase_order_number (string if mentioned)\n- notes (any additional notes)\n- confidence_score (0-100)\n\nReturn only valid JSON."
}
]
},
"options": {
"temperature": 0.2
}
},
"id": "inv3c4d5e-3333-4444-5555-666677778888",
"name": "OCR Invoice Extraction",
"type": "@n8n/n8n-nodes-langchain.openAi",
"typeVersion": 1.3,
"position": [
710,
300
]
},
{
"parameters": {
"operation": "getAll",
"documentId": {
"__rl": true,
"value": "YOUR_GOOGLE_SHEET_ID",
"mode": "id"
},
"sheetName": {
"__rl": true,
"value": "PurchaseOrders",
"mode": "name"
},
"options": {}
},
"id": "inv4d5e6f-4444-5555-6666-777788889999",
"name": "Fetch Purchase Orders",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4,
"position": [
940,
200
]
},
{
"parameters": {
"jsCode": "// Match Invoice with Purchase Order\nconst invoiceData = JSON.parse($input.first().json.message.content);\nconst purchaseOrders = $('Fetch Purchase Orders').all().map(item => item.json);\n\n// Find matching PO\nlet matchedPO = null;\nlet matchScore = 0;\n\nif (invoiceData.purchase_order_number) {\n matchedPO = purchaseOrders.find(po => \n po.po_number === invoiceData.purchase_order_number\n );\n}\n\n// Calculate match score\nif (matchedPO) {\n const amountMatch = Math.abs(matchedPO.total_amount - invoiceData.total_amount) < 1;\n const vendorMatch = matchedPO.vendor_name.toLowerCase() === invoiceData.vendor_name.toLowerCase();\n \n if (amountMatch && vendorMatch) {\n matchScore = 100;\n } else if (amountMatch || vendorMatch) {\n matchScore = 70;\n } else {\n matchScore = 50;\n }\n}\n\n// Determine status\nlet status = 'pending_review';\nlet requires_approval = true;\n\nif (matchScore === 100 && invoiceData.confidence_score >= 90) {\n status = 'auto_approved';\n requires_approval = false;\n} else if (matchScore >= 70) {\n status = 'pending_manual_review';\n} else {\n status = 'pending_review';\n}\n\n// Prepare invoice record\nconst invoiceRecord = {\n invoice_id: 'INV-' + Date.now(),\n invoice_number: invoiceData.invoice_number,\n invoice_date: invoiceData.invoice_date,\n due_date: invoiceData.due_date,\n vendor_name: invoiceData.vendor_name,\n vendor_address: invoiceData.vendor_address,\n vendor_tax_id: invoiceData.vendor_tax_id,\n subtotal: invoiceData.subtotal,\n tax_amount: invoiceData.tax_amount,\n tax_percentage: invoiceData.tax_percentage,\n total_amount: invoiceData.total_amount,\n currency: invoiceData.currency,\n line_items: JSON.stringify(invoiceData.line_items),\n payment_terms: invoiceData.payment_terms,\n purchase_order_number: invoiceData.purchase_order_number,\n matched_po: matchedPO ? matchedPO.po_number : null,\n match_score: matchScore,\n confidence_score: invoiceData.confidence_score,\n status: status,\n requires_approval: requires_approval,\n drive_url: $('Save to Google Drive').item.json.webViewLink,\n received_at: $now.toISO(),\n processed_at: $now.toISO()\n};\n\nreturn [{ json: invoiceRecord }];"
},
"id": "inv5e6f7a-5555-6666-7777-888899990000",
"name": "Match with PO",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1170,
300
]
},
{
"parameters": {
"operation": "append",
"documentId": {
"__rl": true,
"value": "YOUR_GOOGLE_SHEET_ID",
"mode": "id"
},
"sheetName": {
"__rl": true,
"value": "InvoiceLog",
"mode": "name"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"invoice_id": "={{ $json.invoice_id }}",
"invoice_number": "={{ $json.invoice_number }}",
"invoice_date": "={{ $json.invoice_date }}",
"due_date": "={{ $json.due_date }}",
"vendor_name": "={{ $json.vendor_name }}",
"total_amount": "={{ $json.total_amount }}",
"currency": "={{ $json.currency }}",
"matched_po": "={{ $json.matched_po }}",
"match_score": "={{ $json.match_score }}",
"confidence_score": "={{ $json.confidence_score }}",
"status": "={{ $json.status }}",
"requires_approval": "={{ $json.requires_approval }}",
"drive_url": "={{ $json.drive_url }}",
"received_at": "={{ $json.received_at }}",
"processed_at": "={{ $json.processed_at }}"
},
"schema": []
},
"options": {}
},
"id": "inv6f7a8b-6666-7777-8888-999900001111",
"name": "Log Invoice",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4,
"position": [
1400,
300
]
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"boolean": [
{
"value1": "={{ $json.requires_approval }}",
"value2": true
}
]
},
"outputKey": "needs_approval"
}
]
},
"fallbackOutputKey": "auto_approved"
},
"id": "inv7a8b9c-7777-8888-9999-000011112222",
"name": "Check Approval Required",
"type": "n8n-nodes-base.switch",
"typeVersion": 3,
"position": [
1630,
300
]
},
{
"parameters": {
"fromEmail": "finance@yourcompany.com",
"toEmail": "finance-manager@yourcompany.com",
"subject": "=Invoice Approval Required - {{ $json.invoice_number }}",
"emailType": "text",
"message": "=Dear Finance Manager,\n\nA new invoice requires your approval.\n\nINVOICE DETAILS:\n- Invoice ID: {{ $json.invoice_id }}\n- Invoice Number: {{ $json.invoice_number }}\n- Invoice Date: {{ $json.invoice_date }}\n- Due Date: {{ $json.due_date }}\n- Vendor: {{ $json.vendor_name }}\n- Total Amount: {{ $json.currency }} {{ $json.total_amount }}\n\nMATCHING INFORMATION:\n- Purchase Order: {{ $json.matched_po || 'Not Found' }}\n- Match Score: {{ $json.match_score }}%\n- OCR Confidence: {{ $json.confidence_score }}%\n\nDOCUMENT:\n- Drive Link: {{ $json.drive_url }}\n\nPlease review and approve or reject this invoice.\n\nBest regards,\nInvoice Processing System",
"options": {}
},
"id": "inv8b9c0d-8888-9999-0000-111122223333",
"name": "Request Approval",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 2,
"position": [
1860,
200
]
},
{
"parameters": {
"channel": "#finance-notifications",
"text": "=\u2705 Invoice Auto-Approved\n\nInvoice: {{ $json.invoice_number }}\nVendor: {{ $json.vendor_name }}\nAmount: {{ $json.currency }} {{ $json.total_amount }}\nDue Date: {{ $json.due_date }}\nMatch Score: {{ $json.match_score }}%\n\nDocument: {{ $json.drive_url }}",
"additionalFields": {
"parse_mode": "Markdown"
}
},
"id": "inv9c0d1e-9999-0000-1111-222233334444",
"name": "Notify Auto-Approval",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.1,
"position": [
1860,
400
]
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 9 * * *"
}
]
}
},
"id": "inv0d1e2f-0000-1111-2222-333344445555",
"name": "Daily Payment Check",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.1,
"position": [
250,
600
]
},
{
"parameters": {
"operation": "getAll",
"documentId": {
"__rl": true,
"value": "YOUR_GOOGLE_SHEET_ID",
"mode": "id"
},
"sheetName": {
"__rl": true,
"value": "InvoiceLog",
"mode": "name"
},
"options": {}
},
"id": "inv1e2f3a-1111-2222-3333-444455556666",
"name": "Fetch All Invoices",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4,
"position": [
480,
600
]
},
{
"parameters": {
"jsCode": "// Check for upcoming and overdue payments\nconst invoices = $input.all().map(item => item.json);\nconst today = new Date();\nconst in3Days = new Date(today.getTime() + 3 * 24 * 60 * 60 * 1000);\n\nconst upcomingPayments = [];\nconst overduePayments = [];\n\ninvoices.forEach(invoice => {\n if (invoice.status === 'approved' || invoice.status === 'auto_approved') {\n const dueDate = new Date(invoice.due_date);\n \n if (dueDate < today) {\n overduePayments.push(invoice);\n } else if (dueDate <= in3Days) {\n upcomingPayments.push(invoice);\n }\n }\n});\n\nreturn [{\n json: {\n upcoming_payments: upcomingPayments,\n overdue_payments: overduePayments,\n check_date: today.toISOString()\n }\n}];"
},
"id": "inv2f3a4b-2222-3333-4444-555566667777",
"name": "Check Payment Due Dates",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
710,
600
]
},
{
"parameters": {
"fromEmail": "finance@yourcompany.com",
"toEmail": "finance-team@yourcompany.com",
"subject": "=\u26a0\ufe0f Payment Reminders - {{ $now.toFormat('yyyy-MM-dd') }}",
"emailType": "text",
"message": "=Dear Finance Team,\n\nPlease find the payment reminders for today:\n\n\ud83d\udd34 OVERDUE PAYMENTS ({{ $json.overdue_payments.length }}):\n{{ $json.overdue_payments.map(inv => `- ${inv.invoice_number} - ${inv.vendor_name} - ${inv.currency} ${inv.total_amount} (Due: ${inv.due_date})`).join('\\n') }}\n\n\ud83d\udfe1 UPCOMING PAYMENTS (Next 3 Days) ({{ $json.upcoming_payments.length }}):\n{{ $json.upcoming_payments.map(inv => `- ${inv.invoice_number} - ${inv.vendor_name} - ${inv.currency} ${inv.total_amount} (Due: ${inv.due_date})`).join('\\n') }}\n\nPlease process these payments as soon as possible.\n\nBest regards,\nInvoice Processing System",
"options": {}
},
"id": "inv3a4b5c-3333-4444-5555-666677778888",
"name": "Send Payment Reminders",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 2,
"position": [
940,
600
]
}
],
"connections": {
"Email Trigger": {
"main": [
[
{
"node": "Save to Google Drive",
"type": "main",
"index": 0
}
]
]
},
"Save to Google Drive": {
"main": [
[
{
"node": "OCR Invoice Extraction",
"type": "main",
"index": 0
}
]
]
},
"OCR Invoice Extraction": {
"main": [
[
{
"node": "Fetch Purchase Orders",
"type": "main",
"index": 0
}
]
]
},
"Fetch Purchase Orders": {
"main": [
[
{
"node": "Match with PO",
"type": "main",
"index": 0
}
]
]
},
"Match with PO": {
"main": [
[
{
"node": "Log Invoice",
"type": "main",
"index": 0
}
]
]
},
"Log Invoice": {
"main": [
[
{
"node": "Check Approval Required",
"type": "main",
"index": 0
}
]
]
},
"Check Approval Required": {
"main": [
[
{
"node": "Request Approval",
"type": "main",
"index": 0
}
],
[
{
"node": "Notify Auto-Approval",
"type": "main",
"index": 0
}
]
]
},
"Daily Payment Check": {
"main": [
[
{
"node": "Fetch All Invoices",
"type": "main",
"index": 0
}
]
]
},
"Fetch All Invoices": {
"main": [
[
{
"node": "Check Payment Due Dates",
"type": "main",
"index": 0
}
]
]
},
"Check Payment Due Dates": {
"main": [
[
{
"node": "Send Payment Reminders",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Invoice Processing Automation. Uses emailReadImap, googleDrive, openAi, googleSheets. Scheduled trigger; 13 nodes.
Source: https://github.com/kooroosh1363/agentic-automation-lab/blob/main/12-invoice-processing-automation/workflow.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Smart Contract Management. Uses emailReadImap, googleDrive, openAi, slack. Manual trigger; 9 nodes.
This workflow polls an IMAP inbox, uses OpenAI to classify each email by urgency, and then routes it to Slack, Google Sheets, Google Drive, or Gmail based on category and confidence, while logging eve
Smart Customer Success & Churn Prevention. Uses googleSheets, openAi, slack, emailSend. Scheduled trigger; 14 nodes.
Data Analytics Dashboard with AI Insights. Uses googleSheets, httpRequest, openAi, telegram. Scheduled trigger; 11 nodes.
Smart Supply Chain & Inventory Management. Uses googleSheets, openAi, emailSend, slack. Scheduled trigger; 8 nodes.