AutomationFlowsAI & RAG › Invoice Processing Automation

Invoice Processing Automation

Invoice Processing Automation. Uses emailReadImap, googleDrive, openAi, googleSheets. Scheduled trigger; 13 nodes.

Cron / scheduled trigger★★★★☆ complexityAI-powered13 nodesEmail Read ImapGoogle DriveOpenAIGoogle SheetsEmail SendSlack
AI & RAG Trigger: Cron / scheduled Nodes: 13 Complexity: ★★★★☆ AI nodes: yes Added:

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 →

Download .json
{
  "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"
  }
}
Pro

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 →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Smart Contract Management. Uses emailReadImap, googleDrive, openAi, slack. Manual trigger; 9 nodes.

Email Read Imap, Google Drive, OpenAI +3
AI & RAG

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

Email Read Imap, OpenAI, Slack +3
AI & RAG

Smart Customer Success & Churn Prevention. Uses googleSheets, openAi, slack, emailSend. Scheduled trigger; 14 nodes.

Google Sheets, OpenAI, Slack +1
AI & RAG

Data Analytics Dashboard with AI Insights. Uses googleSheets, httpRequest, openAi, telegram. Scheduled trigger; 11 nodes.

Google Sheets, HTTP Request, OpenAI +3
AI & RAG

Smart Supply Chain & Inventory Management. Uses googleSheets, openAi, emailSend, slack. Scheduled trigger; 8 nodes.

Google Sheets, OpenAI, Email Send +1