Axion/n8n-workflows/receipt-ocr-workflow.json
2025-12-07 12:14:33 -04:00

229 lines
6.9 KiB
JSON

{
"name": "Receipt OCR Analysis",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "receipt-upload",
"responseMode": "responseNode",
"options": {}
},
"id": "webhook-receipt-upload",
"name": "Webhook - Receipt Upload",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [250, 300],
"webhookId": "receipt-upload-webhook"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "extract-image",
"name": "image",
"value": "={{ $json.body.image }}",
"type": "string"
},
{
"id": "extract-user-id",
"name": "userId",
"value": "={{ $json.body.userId }}",
"type": "string"
}
]
},
"options": {}
},
"id": "extract-data",
"name": "Extract Receipt Data",
"type": "n8n-nodes-base.set",
"typeVersion": 1,
"position": [450, 300]
},
{
"parameters": {
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"httpHeaderAuth": {
"name": "Authorization",
"value": "Bearer {{ $env.OCR_API_KEY }}"
},
"requestMethod": "POST",
"url": "https://api.ocr.space/parse/image",
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "apikey",
"value": "={{ $env.OCR_API_KEY }}"
},
{
"name": "base64Image",
"value": "={{ $json.image }}"
},
{
"name": "language",
"value": "eng"
},
{
"name": "isOverlayRequired",
"value": "false"
}
]
},
"options": {}
},
"id": "ocr-api-call",
"name": "OCR API Call",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 1,
"position": [650, 300]
},
{
"parameters": {
"jsCode": "// Extract text from OCR response\nconst ocrResponse = $input.item.json;\nconst parsedText = ocrResponse.ParsedResults?.[0]?.ParsedText || '';\n\n// Regular expressions to extract receipt data\nconst amountRegex = /(?:total|amount|sum|\\$|€|£)\\s*:?\\s*([\\d,]+\\.[\\d]{2})/i;\nconst dateRegex = /(\\d{1,2}[\\/\\-]\\d{1,2}[\\/\\-]\\d{2,4})/;\nconst vendorRegex = /^([A-Z][A-Za-z\\s&]+?)(?:\\s|$)/m;\nconst taxRegex = /(?:tax|vat|gst)\\s*:?\\s*([\\d,]+\\.[\\d]{2})/i;\n\n// Extract amount\nlet amount = null;\nconst amountMatch = parsedText.match(amountRegex);\nif (amountMatch) {\n amount = parseFloat(amountMatch[1].replace(/,/g, ''));\n}\n\n// Extract date\nlet date = null;\nconst dateMatch = parsedText.match(dateRegex);\nif (dateMatch) {\n date = dateMatch[1];\n}\n\n// Extract vendor (first line or company name)\nlet vendor = null;\nconst vendorMatch = parsedText.match(vendorRegex);\nif (vendorMatch) {\n vendor = vendorMatch[1].trim();\n}\n\n// Extract tax\nlet tax = null;\nconst taxMatch = parsedText.match(taxRegex);\nif (taxMatch) {\n tax = parseFloat(taxMatch[1].replace(/,/g, ''));\n}\n\n// Calculate confidence score based on extracted data\nlet confidence = 0;\nif (amount) confidence += 0.4;\nif (date) confidence += 0.2;\nif (vendor) confidence += 0.2;\nif (tax) confidence += 0.2;\n\nreturn {\n json: {\n userId: $input.item.json.userId,\n originalImage: $input.item.json.image,\n extractedText: parsedText,\n amount: amount,\n date: date,\n vendor: vendor,\n tax: tax || 0,\n confidence: confidence,\n status: confidence >= 0.6 ? 'needs_review' : 'pending',\n ocrRawResponse: ocrResponse\n }\n};"
},
"id": "parse-receipt-data",
"name": "Parse Receipt Data",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [850, 300]
},
{
"parameters": {
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"httpHeaderAuth": {
"name": "Authorization",
"value": "Bearer {{ $env.BACKEND_API_KEY }}"
},
"requestMethod": "POST",
"url": "={{ $env.BACKEND_API_URL }}/api/receipts",
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "userId",
"value": "={{ $json.userId }}"
},
{
"name": "amount",
"value": "={{ $json.amount }}"
},
{
"name": "date",
"value": "={{ $json.date }}"
},
{
"name": "vendor",
"value": "={{ $json.vendor }}"
},
{
"name": "tax",
"value": "={{ $json.tax }}"
},
{
"name": "confidence",
"value": "={{ $json.confidence }}"
},
{
"name": "status",
"value": "={{ $json.status }}"
},
{
"name": "extractedText",
"value": "={{ $json.extractedText }}"
}
]
},
"options": {}
},
"id": "save-to-backend",
"name": "Save to Backend",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 1,
"position": [1050, 300]
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ { \"success\": true, \"receiptId\": $json.id, \"amount\": $json.amount, \"confidence\": $json.confidence, \"status\": $json.status } }}"
},
"id": "respond-success",
"name": "Respond Success",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [1250, 300]
}
],
"connections": {
"Webhook - Receipt Upload": {
"main": [
[
{
"node": "Extract Receipt Data",
"type": "main",
"index": 0
}
]
]
},
"Extract Receipt Data": {
"main": [
[
{
"node": "OCR API Call",
"type": "main",
"index": 0
}
]
]
},
"OCR API Call": {
"main": [
[
{
"node": "Parse Receipt Data",
"type": "main",
"index": 0
}
]
]
},
"Parse Receipt Data": {
"main": [
[
{
"node": "Save to Backend",
"type": "main",
"index": 0
}
]
]
},
"Save to Backend": {
"main": [
[
{
"node": "Respond Success",
"type": "main",
"index": 0
}
]
]
}
},
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"staticData": null,
"tags": [],
"triggerCount": 1,
"updatedAt": "2024-01-01T00:00:00.000Z",
"versionId": "1"
}