AutomationFlowsAI & RAG › Automate Invoice Processing with Gpt-4o Classification and XML Export to…

Automate Invoice Processing with Gpt-4o Classification and XML Export to…

Original n8n title: Automate Invoice Processing with Gpt-4o Classification and XML Export to Accounting

ByTOMOMITSU ASANO @tomo-0310 on n8n.io

Automated invoice processing pipeline that extracts data from PDF invoices, uses AI Agent for intelligent expense categorization, generates XML for accounting systems, and routes high-value invoices for approval.

Event trigger★★★★☆ complexityAI-powered23 nodesGoogle Drive TriggerGoogle DriveOpenAI ChatAgentXMLGmailSlackGoogle Sheets
AI & RAG Trigger: Event Nodes: 23 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #11911 — we link there as the canonical source.

This workflow follows the Agent → Gmail 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": "Intelligent Invoice Processing with AI Classification and XML Export",
  "nodes": [
    {
      "id": "sticky-overview",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -368,
        288
      ],
      "parameters": {
        "width": 420,
        "height": 752,
        "content": "## Intelligent Invoice Processing with AI Classification and XML Export\n\n### Overview\nAutomated invoice processing pipeline that extracts data from PDF invoices, uses AI for intelligent categorization, and exports to accounting systems via XML format.\n\n### Key Features\n- **PDF Text Extraction**: Parse invoice PDFs automatically\n- **AI-Powered Classification**: Categorize expenses, detect anomalies\n- **XML Export**: Generate accounting-compatible XML files\n- **Human Approval Workflow**: Optional review for high-value invoices\n- **Multi-Channel Notifications**: Slack and Email alerts\n\n### Required Credentials\n- Google Drive OAuth (for PDF source)\n- OpenAI API key\n- Slack Bot Token\n- Google Sheets OAuth\n- Gmail OAuth\n\n### Processing Flow\n1. Detect new PDF invoices\n2. Extract text content\n3. AI analyzes and categorizes\n4. Generate XML for accounting\n5. Route for approval if needed\n6. Archive and notify"
      },
      "typeVersion": 1
    },
    {
      "id": "sticky-step1",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        96,
        640
      ],
      "parameters": {
        "color": 7,
        "width": 260,
        "height": 120,
        "content": "### Step 1: Invoice Detection\n- Monitor Google Drive folder\n- Filter for PDF files only\n- Download invoice content"
      },
      "typeVersion": 1
    },
    {
      "id": "sticky-step2",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        560,
        624
      ],
      "parameters": {
        "color": 7,
        "width": 260,
        "height": 120,
        "content": "### Step 2: Data Extraction\n- Extract text from PDF\n- Parse invoice fields\n- Structure data for AI analysis"
      },
      "typeVersion": 1
    },
    {
      "id": "sticky-step3",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        912,
        608
      ],
      "parameters": {
        "color": 7,
        "width": 260,
        "height": 124,
        "content": "### Step 3: AI Classification\n- AI Agent categorizes expense\n- Detects unusual patterns\n- Suggests GL codes\n- Determines approval needs"
      },
      "typeVersion": 1
    },
    {
      "id": "sticky-step4",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        272,
        1120
      ],
      "parameters": {
        "color": 7,
        "width": 260,
        "height": 140,
        "content": "### Step 4: Export & Archive\n- Convert to XML format\n- Route high-value for approval\n- Archive to Sheets\n- Send notifications"
      },
      "typeVersion": 1
    },
    {
      "id": "drive-trigger",
      "name": "New Invoice Trigger",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "position": [
        112,
        304
      ],
      "parameters": {
        "event": "fileCreated",
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "typeVersion": 1
    },
    {
      "id": "webhook-trigger",
      "name": "Manual Upload Trigger",
      "type": "n8n-nodes-base.webhook",
      "onError": "continueRegularOutput",
      "position": [
        112,
        480
      ],
      "parameters": {
        "path": "process-invoice",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "merge-triggers",
      "name": "Merge Triggers",
      "type": "n8n-nodes-base.merge",
      "position": [
        320,
        384
      ],
      "parameters": {
        "mode": "chooseBranch"
      },
      "typeVersion": 3
    },
    {
      "id": "filter-pdf",
      "name": "Filter PDF Files",
      "type": "n8n-nodes-base.filter",
      "position": [
        528,
        384
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "caseSensitive": false,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "pdf-check",
              "operator": {
                "type": "string",
                "operation": "endsWith"
              },
              "leftValue": "={{ $json.name || $json.fileName || '' }}",
              "rightValue": ".pdf"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "download-pdf",
      "name": "Download Invoice PDF",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        720,
        384
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "options": {},
        "operation": "download"
      },
      "typeVersion": 3
    },
    {
      "id": "extract-pdf",
      "name": "Extract PDF Text",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        928,
        384
      ],
      "parameters": {
        "options": {},
        "operation": "pdf"
      },
      "typeVersion": 1
    },
    {
      "id": "parse-invoice",
      "name": "Parse Invoice Data",
      "type": "n8n-nodes-base.code",
      "position": [
        1120,
        384
      ],
      "parameters": {
        "jsCode": "const item = $input.first();\nconst text = item.json.text || '';\n\nconst patterns = {\n  invoiceNumber: /invoice\\s*#?:?\\s*([A-Z0-9-]+)/i,\n  date: /(\\d{1,2}[\\/\\-]\\d{1,2}[\\/\\-]\\d{2,4})/,\n  total: /total:?\\s*\\$?([\\d,]+\\.?\\d*)/i,\n  vendor: /from:?\\s*([^\\n]+)/i,\n  dueDate: /due\\s*date:?\\s*(\\d{1,2}[\\/\\-]\\d{1,2}[\\/\\-]\\d{2,4})/i\n};\n\nconst extracted = {\n  rawText: text.substring(0, 2000),\n  invoiceNumber: text.match(patterns.invoiceNumber)?.[1] || 'UNKNOWN',\n  invoiceDate: text.match(patterns.date)?.[1] || new Date().toISOString().split('T')[0],\n  totalAmount: parseFloat((text.match(patterns.total)?.[1] || '0').replace(',', '')) || 0,\n  vendorName: text.match(patterns.vendor)?.[1]?.trim() || 'Unknown Vendor',\n  dueDate: text.match(patterns.dueDate)?.[1] || null,\n  fileName: item.json.fileName || 'invoice.pdf',\n  processedAt: new Date().toISOString()\n};\n\nreturn [{ json: extracted }];"
      },
      "typeVersion": 2
    },
    {
      "id": "openai-model",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1264,
        560
      ],
      "parameters": {
        "model": "gpt-4o-mini",
        "options": {
          "temperature": 0.2
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "ai-classifier",
      "name": "AI Invoice Classifier",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1264,
        384
      ],
      "parameters": {
        "text": "=Analyze this invoice and provide classification:\n\nInvoice Number: {{ $json.invoiceNumber }}\nVendor: {{ $json.vendorName }}\nAmount: ${{ $json.totalAmount }}\nDate: {{ $json.invoiceDate }}\n\nRaw Text (excerpt):\n{{ $json.rawText.substring(0, 500) }}\n\nProvide analysis in this exact JSON format:\n{\n  \"category\": \"one of: Office Supplies, Software, Professional Services, Travel, Equipment, Marketing, Utilities, Other\",\n  \"glCode\": \"suggested GL code like 6100, 6200, etc.\",\n  \"confidence\": 0.0 to 1.0,\n  \"requiresApproval\": true/false (true if amount > 5000 or low confidence),\n  \"anomalyDetected\": true/false,\n  \"anomalyReason\": \"explanation if anomaly detected, null otherwise\",\n  \"summary\": \"brief 1-sentence description of this invoice\"\n}",
        "options": {
          "systemMessage": "You are an expert accountant AI assistant specialized in invoice classification and expense categorization. Analyze invoices carefully and provide accurate categorization. Flag any unusual patterns or potential issues."
        }
      },
      "typeVersion": 1.7
    },
    {
      "id": "parse-ai-result",
      "name": "Parse AI Classification",
      "type": "n8n-nodes-base.code",
      "position": [
        160,
        896
      ],
      "parameters": {
        "jsCode": "const item = $input.first();\nconst originalData = $('Parse Invoice Data').first().json;\n\nlet classification;\ntry {\n  const responseText = item.json.output || item.json.text || '';\n  const jsonMatch = responseText.match(/\\{[\\s\\S]*\\}/);\n  classification = jsonMatch ? JSON.parse(jsonMatch[0]) : {\n    category: 'Other',\n    glCode: '6900',\n    confidence: 0.5,\n    requiresApproval: true,\n    anomalyDetected: false,\n    anomalyReason: null,\n    summary: 'Classification failed - manual review required'\n  };\n} catch (e) {\n  classification = {\n    category: 'Other',\n    glCode: '6900',\n    confidence: 0.5,\n    requiresApproval: true,\n    anomalyDetected: false,\n    anomalyReason: null,\n    summary: 'Parse error: ' + e.message\n  };\n}\n\nreturn [{\n  json: {\n    ...originalData,\n    classification: classification,\n    needsApproval: classification.requiresApproval || originalData.totalAmount > 5000,\n    processingStatus: 'classified'\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "convert-xml",
      "name": "Convert to XML",
      "type": "n8n-nodes-base.xml",
      "position": [
        336,
        896
      ],
      "parameters": {
        "mode": "jsonToxml",
        "options": {
          "rootName": "Invoice"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "format-xml-output",
      "name": "Format XML Output",
      "type": "n8n-nodes-base.set",
      "position": [
        528,
        896
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "1",
              "name": "xmlContent",
              "type": "string",
              "value": "={{ $json.data }}"
            },
            {
              "id": "2",
              "name": "fileName",
              "type": "string",
              "value": "=invoice_{{ $('Parse Invoice Data').first().json.invoiceNumber }}_{{ $now.format('yyyyMMdd') }}.xml"
            },
            {
              "id": "3",
              "name": "invoiceData",
              "type": "object",
              "value": "={{ $('Parse AI Classification').first().json }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "check-approval",
      "name": "Needs Approval?",
      "type": "n8n-nodes-base.if",
      "position": [
        736,
        896
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "approval-check",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ $json.invoiceData.needsApproval }}",
              "rightValue": true
            },
            {
              "id": "high-value",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json.invoiceData.totalAmount }}",
              "rightValue": 5000
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "send-approval-email",
      "name": "Request Approval Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        960,
        800
      ],
      "parameters": {
        "sendTo": "user@example.com",
        "message": "=Invoice requires approval:\n\nInvoice #: {{ $json.invoiceData.invoiceNumber }}\nVendor: {{ $json.invoiceData.vendorName }}\nAmount: ${{ $json.invoiceData.totalAmount }}\nCategory: {{ $json.invoiceData.classification.category }}\nGL Code: {{ $json.invoiceData.classification.glCode }}\n\nAI Summary: {{ $json.invoiceData.classification.summary }}\n\nPlease review and approve in the finance system.",
        "options": {},
        "subject": "=Invoice Approval Required: {{ $json.invoiceData.vendorName }} - ${{ $json.invoiceData.totalAmount }}"
      },
      "typeVersion": 2.1
    },
    {
      "id": "send-slack-notification",
      "name": "Slack Notification",
      "type": "n8n-nodes-base.slack",
      "position": [
        960,
        992
      ],
      "parameters": {
        "text": "=Invoice Processed\n\n*Invoice:* {{ $json.invoiceData.invoiceNumber }}\n*Vendor:* {{ $json.invoiceData.vendorName }}\n*Amount:* ${{ $json.invoiceData.totalAmount }}\n*Category:* {{ $json.invoiceData.classification.category }}\n*Status:* {{ $json.invoiceData.needsApproval ? 'Pending Approval' : 'Auto-Approved' }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "name",
          "value": "#finance-notifications"
        },
        "otherOptions": {}
      },
      "typeVersion": 2.2
    },
    {
      "id": "merge-paths",
      "name": "Merge Processing Paths",
      "type": "n8n-nodes-base.merge",
      "position": [
        1168,
        896
      ],
      "parameters": {},
      "typeVersion": 3
    },
    {
      "id": "log-to-sheets",
      "name": "Archive to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1360,
        896
      ],
      "parameters": {
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "respond-webhook",
      "name": "Respond to Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        1568,
        896
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "={{ {success: true, invoiceNumber: $json.invoiceData.invoiceNumber, status: $json.invoiceData.needsApproval ? 'pending_approval' : 'processed'} }}"
      },
      "typeVersion": 1.1
    }
  ],
  "settings": {
    "executionOrder": "v1"
  },
  "connections": {
    "Convert to XML": {
      "main": [
        [
          {
            "node": "Format XML Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Triggers": {
      "main": [
        [
          {
            "node": "Filter PDF Files",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Needs Approval?": {
      "main": [
        [
          {
            "node": "Request Approval Email",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Slack Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract PDF Text": {
      "main": [
        [
          {
            "node": "Parse Invoice Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter PDF Files": {
      "main": [
        [
          {
            "node": "Download Invoice PDF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format XML Output": {
      "main": [
        [
          {
            "node": "Needs Approval?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Invoice Classifier",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Parse Invoice Data": {
      "main": [
        [
          {
            "node": "AI Invoice Classifier",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Slack Notification": {
      "main": [
        [
          {
            "node": "Merge Processing Paths",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "New Invoice Trigger": {
      "main": [
        [
          {
            "node": "Merge Triggers",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Invoice PDF": {
      "main": [
        [
          {
            "node": "Extract PDF Text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Invoice Classifier": {
      "main": [
        [
          {
            "node": "Parse AI Classification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Manual Upload Trigger": {
      "main": [
        [
          {
            "node": "Merge Triggers",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge Processing Paths": {
      "main": [
        [
          {
            "node": "Archive to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Request Approval Email": {
      "main": [
        [
          {
            "node": "Merge Processing Paths",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse AI Classification": {
      "main": [
        [
          {
            "node": "Convert to XML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Archive to Google Sheets": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Automated invoice processing pipeline that extracts data from PDF invoices, uses AI Agent for intelligent expense categorization, generates XML for accounting systems, and routes high-value invoices for approval.

Source: https://n8n.io/workflows/11911/ — 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

This workflow automatically converts unstructured internal documentation into clear, actionable Standard Operating Procedures (SOPs).

Google Drive Trigger, Google Drive, Agent +6
AI & RAG

[](https://www.youtube.com/watch?v=T9gnSsjYfvY) > This workflow automatically processes resumes (PDFs) uploaded or updated in a Google Drive folder. It extracts and structures the candidate’s infor

Output Parser Structured, OpenAI Chat, Agent +4
AI & RAG

Who is this for? This template is perfect for agencies, consultancies, freelancers, and project-based teams who want to eliminate repetitive onboarding tasks. If you're tired of manually creating fold

Google Drive Trigger, Google Drive, Slack +5
AI & RAG

This workflow is ideal for:

OpenAI Chat, Output Parser Structured, Google Drive Trigger +6
AI & RAG

This workflow monitors a Google Drive folder for new files (Google Docs or PDFs), extracts text, summarizes content with OpenAI, and sends results to Slack or Email. Monitors a Google Drive folder for

OpenAI Chat, Google Drive Trigger, Google Docs +4