Mi Flujo de Trabajo 2
Este es unInvoice Processing, AI Summarizationflujo de automatización del dominio deautomatización que contiene 18 nodos.Utiliza principalmente nodos como Code, Switch, Webhook, Telegram, HttpRequest. Flujo de trabajo basado en IA para la extracción y aprobación de datos de facturas, integrando ScrapeGraphAI y Telegram
- •Punto final de HTTP Webhook (n8n generará automáticamente)
- •Bot Token de Telegram
- •Pueden requerirse credenciales de autenticación para la API de destino
Nodos utilizados (18)
{
"id": "VhEwspDqzu7ssFVE",
"meta": {
"instanceId": "f4b0efaa33080e7774e0d9285c40c7abcd2c6f7cf1a8b901fa7106170dd4cda3",
"templateCredsSetupCompleted": true
},
"name": "My workflow 2",
"tags": [
{
"id": "DxXGubfBzRKh6L8T",
"name": "Revenue Optimization",
"createdAt": "2025-07-25T16:24:30.370Z",
"updatedAt": "2025-07-25T16:24:30.370Z"
},
{
"id": "IxkcJ2IpYIxivoHV",
"name": "Content Strategy",
"createdAt": "2025-07-25T12:57:37.677Z",
"updatedAt": "2025-07-25T12:57:37.677Z"
},
{
"id": "PAKIJ2Mm9EvRcR3u",
"name": "Trend Monitoring",
"createdAt": "2025-07-25T12:57:37.670Z",
"updatedAt": "2025-07-25T12:57:37.670Z"
},
{
"id": "YtfXmaZk44MYedPO",
"name": "Dynamic Pricing",
"createdAt": "2025-07-25T16:24:30.369Z",
"updatedAt": "2025-07-25T16:24:30.369Z"
},
{
"id": "wJ30mjhtrposO8Qt",
"name": "Simple RAG",
"createdAt": "2025-07-28T12:55:14.424Z",
"updatedAt": "2025-07-28T12:55:14.424Z"
}
],
"nodes": [
{
"id": "4d24fd12-5442-4112-b997-2e6b9ece768c",
"name": "Disparador de Correo Electrónico",
"type": "n8n-nodes-base.emailReadImap",
"position": [
1120,
832
],
"parameters": {
"options": {}
},
"typeVersion": 2
},
{
"id": "b32637a8-8941-4fea-b6cb-b2272d25eaa4",
"name": "File Upload Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
1120,
1008
],
"webhookId": "9588f200-20c0-4f26-81e0-73726abc889a",
"parameters": {
"path": "/invoice-upload",
"options": {
"rawBody": true
},
"responseMode": "responseNode"
},
"typeVersion": 2
},
{
"id": "4197b894-434f-42b6-a728-b6773af9b54a",
"name": "Procesador de Archivos",
"type": "n8n-nodes-base.code",
"position": [
1424,
896
],
"parameters": {
"jsCode": "// Process incoming data from either email or webhook\nconst inputData = $input.all()[0];\nlet invoiceFiles = [];\n\n// Handle email attachments\nif (inputData.json.attachments) {\n invoiceFiles = inputData.json.attachments\n .filter(attachment => {\n const fileName = attachment.filename.toLowerCase();\n return fileName.endsWith('.pdf') || \n fileName.endsWith('.png') || \n fileName.endsWith('.jpg') || \n fileName.endsWith('.jpeg') ||\n fileName.endsWith('.tiff') ||\n fileName.endsWith('.bmp');\n })\n .map(attachment => ({\n filename: attachment.filename,\n content: attachment.content,\n contentType: attachment.contentType,\n source: 'email',\n sender: inputData.json.from?.text || 'unknown',\n subject: inputData.json.subject || 'No subject',\n receivedDate: inputData.json.date || new Date().toISOString()\n }));\n}\n// Handle direct file uploads\nelse if (inputData.binary) {\n Object.keys(inputData.binary).forEach(key => {\n const file = inputData.binary[key];\n invoiceFiles.push({\n filename: file.fileName || `upload_${key}`,\n content: file.data,\n contentType: file.mimeType,\n source: 'upload',\n uploadedDate: new Date().toISOString()\n });\n });\n}\n\n// Return each file as separate execution\nreturn invoiceFiles.map((file, index) => ({\n json: {\n invoice_id: `INV_${Date.now()}_${index}`,\n filename: file.filename,\n source: file.source,\n sender: file.sender || null,\n subject: file.subject || null,\n received_date: file.receivedDate || file.uploadedDate,\n content_type: file.contentType,\n processing_status: 'pending',\n created_at: new Date().toISOString()\n },\n binary: {\n invoice_file: {\n data: file.content,\n mimeType: file.contentType,\n fileName: file.filename\n }\n }\n}));"
},
"typeVersion": 2
},
{
"id": "44e738e0-652a-40ff-8a9b-d4d8381771ef",
"name": "ScrapeGraphAI - Extracto de Facturas",
"type": "n8n-nodes-scrapegraphai.scrapegraphAi",
"position": [
1744,
880
],
"parameters": {
"resource": "scrapeSmartScraper"
},
"typeVersion": 1
},
{
"id": "c891bcd4-df84-4fde-930d-e1eba7f679d0",
"name": "Extractor y Limpiador de Datos",
"type": "n8n-nodes-base.code",
"position": [
2080,
912
],
"parameters": {
"jsCode": "// Enhanced data extraction and cleaning\nconst inputData = $input.all()[0];\nconst extractedData = inputData.json.result?.invoice_data || {};\nconst originalMetadata = inputData.json;\n\nfunction cleanAndValidateData(data) {\n // Clean and standardize extracted data\n const cleaned = {\n // Basic invoice info\n invoice_number: cleanString(data.invoice_number),\n invoice_date: standardizeDate(data.invoice_date),\n due_date: standardizeDate(data.due_date),\n \n // Vendor information\n vendor: {\n name: cleanString(data.vendor_name),\n address: cleanString(data.vendor_address),\n tax_id: cleanString(data.vendor_tax_id || data.vendor_vat || data.tax_id),\n email: cleanEmail(data.vendor_email),\n phone: cleanPhone(data.vendor_phone)\n },\n \n // Bill to information\n bill_to: {\n name: cleanString(data.bill_to_name),\n address: cleanString(data.bill_to_address)\n },\n \n // Financial data\n currency: (data.currency || 'USD').toUpperCase(),\n amounts: {\n subtotal: parseAmount(data.subtotal),\n tax_total: parseAmount(data.tax_total),\n discount_amount: parseAmount(data.discount_amount || '0'),\n shipping_amount: parseAmount(data.shipping_amount || '0'),\n total_amount: parseAmount(data.total_amount)\n },\n \n // Line items\n line_items: cleanLineItems(data.line_items || []),\n \n // Additional info\n payment_terms: cleanString(data.payment_terms),\n purchase_order: cleanString(data.purchase_order),\n notes: cleanString(data.notes),\n \n // Processing metadata\n processing_info: {\n extracted_at: new Date().toISOString(),\n confidence_score: calculateConfidenceScore(data),\n data_completeness: calculateCompleteness(data)\n }\n };\n \n return cleaned;\n}\n\nfunction cleanString(str) {\n if (!str || str === 'null' || str === 'undefined') return null;\n return str.toString().trim().replace(/\\s+/g, ' ');\n}\n\nfunction standardizeDate(dateStr) {\n if (!dateStr || dateStr === 'null') return null;\n try {\n const date = new Date(dateStr);\n return date.toISOString().split('T')[0]; // Return YYYY-MM-DD format\n } catch {\n return dateStr; // Return original if parsing fails\n }\n}\n\nfunction cleanEmail(email) {\n if (!email || email === 'null') return null;\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(email) ? email.toLowerCase() : null;\n}\n\nfunction cleanPhone(phone) {\n if (!phone || phone === 'null') return null;\n return phone.replace(/[^\\d+\\-\\(\\)\\s]/g, '').trim();\n}\n\nfunction parseAmount(amount) {\n if (!amount || amount === 'null') return 0;\n const cleaned = amount.toString().replace(/[^\\d.-]/g, '');\n return parseFloat(cleaned) || 0;\n}\n\nfunction cleanLineItems(items) {\n if (!Array.isArray(items)) return [];\n \n return items.map(item => ({\n description: cleanString(item.description),\n quantity: parseFloat(item.quantity) || 1,\n unit_price: parseAmount(item.unit_price),\n total: parseAmount(item.total),\n tax_rate: cleanString(item.tax_rate),\n tax_amount: parseAmount(item.tax_amount || '0')\n })).filter(item => item.description); // Remove items without description\n}\n\nfunction calculateConfidenceScore(data) {\n let score = 0;\n const requiredFields = ['invoice_number', 'vendor_name', 'total_amount', 'invoice_date'];\n \n requiredFields.forEach(field => {\n if (data[field] && data[field] !== 'null') score += 25;\n });\n \n return score;\n}\n\nfunction calculateCompleteness(data) {\n const allFields = [\n 'invoice_number', 'invoice_date', 'due_date', 'vendor_name', \n 'vendor_address', 'total_amount', 'subtotal', 'line_items'\n ];\n \n const completedFields = allFields.filter(field => \n data[field] && data[field] !== 'null' && \n (Array.isArray(data[field]) ? data[field].length > 0 : true)\n ).length;\n \n return Math.round((completedFields / allFields.length) * 100);\n}\n\nconst cleanedData = cleanAndValidateData(extractedData);\n\nreturn [{\n json: {\n ...originalMetadata,\n extracted_invoice_data: cleanedData,\n processing_status: 'extracted',\n updated_at: new Date().toISOString()\n },\n binary: inputData.binary // Preserve binary data for potential reprocessing\n}];"
},
"typeVersion": 2
},
{
"id": "cc08bf61-cb49-4cb5-be64-a9068c7c0486",
"name": "Motor de Reglas de Validación",
"type": "n8n-nodes-base.code",
"position": [
2400,
944
],
"parameters": {
"jsCode": "// Comprehensive validation rules for invoice data\nconst inputData = $input.all()[0];\nconst invoiceData = inputData.json.extracted_invoice_data;\nconst validationResults = {\n is_valid: true,\n errors: [],\n warnings: [],\n validation_score: 0,\n business_rules: {\n duplicate_check: 'pending',\n amount_threshold: 'pending',\n vendor_verification: 'pending',\n date_validation: 'pending'\n }\n};\n\n// Required field validation\nconst requiredFields = [\n { field: 'invoice_number', message: 'Invoice number is required' },\n { field: 'vendor.name', message: 'Vendor name is required' },\n { field: 'amounts.total_amount', message: 'Total amount is required' },\n { field: 'invoice_date', message: 'Invoice date is required' }\n];\n\nrequiredFields.forEach(({ field, message }) => {\n const value = getNestedValue(invoiceData, field);\n if (!value || value === 0) {\n validationResults.errors.push(message);\n validationResults.is_valid = false;\n } else {\n validationResults.validation_score += 20;\n }\n});\n\n// Date validation\nif (invoiceData.invoice_date && invoiceData.due_date) {\n const invoiceDate = new Date(invoiceData.invoice_date);\n const dueDate = new Date(invoiceData.due_date);\n \n if (dueDate < invoiceDate) {\n validationResults.errors.push('Due date cannot be before invoice date');\n validationResults.is_valid = false;\n } else {\n validationResults.business_rules.date_validation = 'passed';\n }\n} else {\n validationResults.business_rules.date_validation = 'failed';\n}\n\n// Amount validation\nconst amounts = invoiceData.amounts;\nif (amounts) {\n // Check if total matches calculation\n const calculatedTotal = amounts.subtotal + amounts.tax_total + amounts.shipping_amount - amounts.discount_amount;\n const totalDifference = Math.abs(calculatedTotal - amounts.total_amount);\n \n if (totalDifference > 0.01) {\n validationResults.warnings.push(`Total amount mismatch: Expected ${calculatedTotal.toFixed(2)}, got ${amounts.total_amount.toFixed(2)}`);\n }\n \n // Amount threshold check (configurable)\n const amountThreshold = 10000; // $10,000\n if (amounts.total_amount > amountThreshold) {\n validationResults.business_rules.amount_threshold = 'requires_approval';\n validationResults.warnings.push(`High amount invoice requires additional approval: $${amounts.total_amount}`);\n } else {\n validationResults.business_rules.amount_threshold = 'passed';\n }\n} else {\n validationResults.errors.push('Amount information is missing');\n validationResults.is_valid = false;\n}\n\n// Vendor validation\nif (invoiceData.vendor && invoiceData.vendor.name) {\n // Simulate vendor verification (in real scenario, check against approved vendor list)\n const approvedVendors = [\n 'ABC Company Ltd', 'XYZ Corporation', 'Tech Solutions Inc', \n 'Office Supplies Co', 'Consulting Partners LLC'\n ];\n \n const isApprovedVendor = approvedVendors.some(vendor => \n vendor.toLowerCase().includes(invoiceData.vendor.name.toLowerCase()) ||\n invoiceData.vendor.name.toLowerCase().includes(vendor.toLowerCase())\n );\n \n if (isApprovedVendor) {\n validationResults.business_rules.vendor_verification = 'approved';\n validationResults.validation_score += 15;\n } else {\n validationResults.business_rules.vendor_verification = 'new_vendor';\n validationResults.warnings.push('Vendor not in approved list - requires verification');\n }\n}\n\n// Line items validation\nif (invoiceData.line_items && invoiceData.line_items.length > 0) {\n let lineItemErrors = [];\n \n invoiceData.line_items.forEach((item, index) => {\n if (!item.description) {\n lineItemErrors.push(`Line item ${index + 1}: Missing description`);\n }\n if (item.quantity <= 0) {\n lineItemErrors.push(`Line item ${index + 1}: Invalid quantity`);\n }\n if (item.unit_price <= 0) {\n lineItemErrors.push(`Line item ${index + 1}: Invalid unit price`);\n }\n \n // Check line total calculation\n const expectedTotal = item.quantity * item.unit_price;\n if (Math.abs(expectedTotal - item.total) > 0.01) {\n lineItemErrors.push(`Line item ${index + 1}: Total calculation error`);\n }\n });\n \n if (lineItemErrors.length > 0) {\n validationResults.warnings.push(...lineItemErrors);\n } else {\n validationResults.validation_score += 10;\n }\n} else {\n validationResults.warnings.push('No line items found');\n}\n\n// Duplicate invoice check (simulate database lookup)\nif (invoiceData.invoice_number) {\n // In real scenario, check against database\n const existingInvoices = ['INV-001', 'INV-002', 'INV-003']; // Mock data\n \n if (existingInvoices.includes(invoiceData.invoice_number)) {\n validationResults.errors.push('Duplicate invoice number detected');\n validationResults.business_rules.duplicate_check = 'duplicate';\n validationResults.is_valid = false;\n } else {\n validationResults.business_rules.duplicate_check = 'unique';\n validationResults.validation_score += 15;\n }\n}\n\n// Calculate confidence level\nlet confidenceLevel = 'low';\nif (validationResults.validation_score >= 80) confidenceLevel = 'high';\nelse if (validationResults.validation_score >= 60) confidenceLevel = 'medium';\n\n// Determine approval requirements\nlet requiresApproval = false;\nlet approvalReason = [];\n\nif (validationResults.business_rules.amount_threshold === 'requires_approval') {\n requiresApproval = true;\n approvalReason.push('High amount');\n}\n\nif (validationResults.business_rules.vendor_verification === 'new_vendor') {\n requiresApproval = true;\n approvalReason.push('New vendor');\n}\n\nif (validationResults.errors.length > 0) {\n requiresApproval = true;\n approvalReason.push('Validation errors');\n}\n\nfunction getNestedValue(obj, path) {\n return path.split('.').reduce((current, key) => current?.[key], obj);\n}\n\nreturn [{\n json: {\n ...inputData.json,\n validation_results: validationResults,\n confidence_level: confidenceLevel,\n requires_approval: requiresApproval,\n approval_reasons: approvalReason,\n processing_status: validationResults.is_valid ? 'validated' : 'validation_failed',\n validated_at: new Date().toISOString()\n },\n binary: inputData.binary // Preserve binary data\n}];"
},
"typeVersion": 2
},
{
"id": "7980050d-408f-4b3a-8e10-fad41c143eff",
"name": "¿Aprobación Requerida?",
"type": "n8n-nodes-base.switch",
"position": [
2704,
928
],
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "",
"rightValue": ""
}
]
}
}
]
},
"options": {}
},
"typeVersion": 3
},
{
"id": "8d543b5f-9d0a-48b0-9589-d9c9c5a0adb1",
"name": "Generador de Flujo de Aprobación",
"type": "n8n-nodes-base.code",
"position": [
3008,
976
],
"parameters": {
"jsCode": "// Generate approval request with comprehensive details\nconst inputData = $input.all()[0];\nconst invoiceData = inputData.json.extracted_invoice_data;\nconst validation = inputData.json.validation_results;\n\n// Create approval request\nconst approvalRequest = {\n approval_id: `APPR_${inputData.json.invoice_id}_${Date.now()}`,\n invoice_id: inputData.json.invoice_id,\n request_type: 'invoice_approval',\n priority: determinePriority(inputData.json.approval_reasons),\n \n // Invoice summary\n invoice_summary: {\n invoice_number: invoiceData.invoice_number,\n vendor_name: invoiceData.vendor ? invoiceData.vendor.name : 'Unknown',\n total_amount: invoiceData.amounts ? invoiceData.amounts.total_amount : 0,\n currency: invoiceData.currency,\n invoice_date: invoiceData.invoice_date,\n due_date: invoiceData.due_date\n },\n \n // Approval details\n approval_reasons: inputData.json.approval_reasons,\n validation_score: validation.validation_score,\n confidence_level: inputData.json.confidence_level,\n \n // Issues requiring attention\n attention_required: {\n errors: validation.errors,\n warnings: validation.warnings,\n business_rule_flags: Object.entries(validation.business_rules)\n .filter(([key, value]) => value === 'requires_approval' || value === 'failed')\n .map(([key, value]) => ({ rule: key, status: value }))\n },\n \n // Approval workflow\n workflow_steps: generateApprovalSteps(inputData.json.approval_reasons, invoiceData.amounts ? invoiceData.amounts.total_amount : 0),\n \n // Request metadata\n requested_at: new Date().toISOString(),\n requested_by: 'system',\n status: 'pending_approval',\n \n // Generate approval message\n approval_message: generateApprovalMessage(invoiceData, validation, inputData.json.approval_reasons)\n};\n\nfunction determinePriority(reasons) {\n if (reasons.includes('Validation errors')) return 'high';\n if (reasons.includes('High amount')) return 'medium';\n return 'normal';\n}\n\nfunction generateApprovalSteps(reasons, amount) {\n const steps = [];\n \n // Finance team review for high amounts\n if (amount > 10000) {\n steps.push({\n step: 1,\n approver_role: 'finance_manager',\n required: true,\n description: 'Finance manager approval for high-value invoice'\n });\n }\n \n // Procurement review for new vendors\n if (reasons.includes('New vendor')) {\n steps.push({\n step: steps.length + 1,\n approver_role: 'procurement_manager',\n required: true,\n description: 'Procurement verification for new vendor'\n });\n }\n \n // Department head approval\n steps.push({\n step: steps.length + 1,\n approver_role: 'department_head',\n required: true,\n description: 'Department head final approval'\n });\n \n return steps;\n}\n\nfunction generateApprovalMessage(invoiceData, validation, reasons) {\n let message = `🧾 **INVOICE APPROVAL REQUEST**\\n\\n`;\n message += `📋 **Invoice:** ${invoiceData.invoice_number || 'N/A'}\\n`;\n message += `🏢 **Vendor:** ${invoiceData.vendor ? invoiceData.vendor.name : 'Unknown'}\\n`;\n \n const amount = invoiceData.amounts ? invoiceData.amounts.total_amount : 0;\n const currency = invoiceData.currency || 'USD';\n message += `💰 **Amount:** ${currency} ${amount.toLocaleString()}\\n`;\n message += `📅 **Date:** ${invoiceData.invoice_date || 'N/A'}\\n`;\n message += `⏰ **Due:** ${invoiceData.due_date || 'N/A'}\\n\\n`;\n \n message += `🚨 **Approval Required For:**\\n`;\n reasons.forEach(reason => {\n message += `• ${reason}\\n`;\n });\n \n if (validation.errors.length > 0) {\n message += `\\n❌ **Errors:**\\n`;\n validation.errors.forEach(error => {\n message += `• ${error}\\n`;\n });\n }\n \n if (validation.warnings.length > 0) {\n message += `\\n⚠️ **Warnings:**\\n`;\n validation.warnings.forEach(warning => {\n message += `• ${warning}\\n`;\n });\n }\n \n message += `\\n📊 **Validation Score:** ${validation.validation_score}/100\\n`;\n message += `🎯 **Confidence:** ${inputData.json.confidence_level.toUpperCase()}\\n\\n`;\n message += `Please review and approve/reject this invoice.`;\n \n return message;\n}\n\nreturn [{\n json: {\n ...inputData.json,\n approval_request: approvalRequest,\n processing_status: 'pending_approval',\n updated_at: new Date().toISOString()\n },\n binary: inputData.binary // Preserve binary data\n}];"
},
"typeVersion": 2
},
{
"id": "92ee2ffa-df6f-447c-bc74-bc78a40e90bf",
"name": "Notificación de Aprobación",
"type": "n8n-nodes-base.telegram",
"position": [
3360,
912
],
"webhookId": "5075a6ac-bc09-446d-898e-f5bf9b55d10f",
"parameters": {
"text": "={{ $json.approval_request.approval_message }}",
"chatId": "@invoice_approvals",
"additionalFields": {
"parse_mode": "Markdown"
}
},
"typeVersion": 1.2
},
{
"id": "e2f6f5d5-a8b8-41df-8113-f45242fa2c9f",
"name": "Integración con Sistema Contable",
"type": "n8n-nodes-base.httpRequest",
"position": [
3584,
912
],
"parameters": {
"url": "https://your-accounting-system.com/api/invoices",
"options": {},
"sendBody": true,
"sendHeaders": true,
"authentication": "predefinedCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "invoice_data",
"value": "={{ JSON.stringify($json.extracted_invoice_data) }}"
},
{
"name": "validation_results",
"value": "={{ JSON.stringify($json.validation_results) }}"
},
{
"name": "processing_metadata",
"value": "={{ JSON.stringify({ invoice_id: $json.invoice_id, source: $json.source, processed_at: $json.updated_at }) }}"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"nodeCredentialType": "httpHeaderAuth"
},
"typeVersion": 4.2
},
{
"id": "ffadff50-4b5e-4cf0-ad78-3f43b3ab9237",
"name": "Nota Adhesiva - Disparadores",
"type": "n8n-nodes-base.stickyNote",
"position": [
1024,
-32
],
"parameters": {
"color": 2,
"width": 320,
"height": 1202,
"content": "# Step 1: Multi-Input Triggers 📧📁\n\n**Flexible Invoice Reception**\n\nTwo trigger options for maximum flexibility:\n\n## Email Trigger:\n- **Purpose**: Automatic processing of emailed invoices\n- **Supported**: PDF, PNG, JPG, JPEG, TIFF, BMP\n- **Features**: Attachment filtering, sender tracking\n- **Polling**: Every 30 seconds\n\n## File Upload Webhook:\n- **Purpose**: Direct file upload processing\n- **Endpoint**: `/invoice-upload`\n- **Method**: POST with file data\n- **Use Case**: Manual uploads, API integrations\n\n## Benefits:\n- Multiple intake channels\n- Automatic file type detection\n- Metadata preservation\n- Source tracking for audit trails"
},
"typeVersion": 1
},
{
"id": "3a13dfe2-a654-434f-b8e0-91ddb685b7c3",
"name": "Nota Adhesiva - Procesador de Archivos",
"type": "n8n-nodes-base.stickyNote",
"position": [
1344,
-32
],
"parameters": {
"color": 3,
"width": 320,
"height": 1202,
"content": "# Step 2: File Processing 🔄\n\n**Smart File Handler**\n\nProcesses incoming files from multiple sources with intelligent routing.\n\n## Key Features:\n- **Multi-source Support**: Email attachments + direct uploads\n- **File Type Validation**: PDF, images only\n- **Metadata Extraction**: Sender, subject, timestamps\n- **Unique ID Generation**: Trackable invoice IDs\n\n## Processing Logic:\n- Filters supported file types\n- Extracts source information\n- Creates processing metadata\n- Prepares for AI extraction\n\n## Output:\n- Clean file objects\n- Processing metadata\n- Binary file data for AI analysis"
},
"typeVersion": 1
},
{
"id": "74fde2b5-236f-4e42-a98b-d1a7c43bc9ae",
"name": "Nota Adhesiva - Extracción con IA",
"type": "n8n-nodes-base.stickyNote",
"position": [
1664,
-32
],
"parameters": {
"color": 4,
"width": 320,
"height": 1202,
"content": "# Step 3: AI Invoice Extraction 🤖\n\n**ScrapeGraphAI-Powered Data Extraction**\n\nAdvanced AI extraction of invoice data from PDFs and images.\n\n## Extraction Capabilities:\n- **Basic Info**: Invoice #, dates, amounts\n- **Vendor Details**: Name, address, contact info\n- **Line Items**: Description, qty, price, tax\n- **Financial Data**: Subtotals, taxes, totals\n- **Additional**: PO numbers, terms, notes\n\n## AI Features:\n- Multi-format support (PDF, images)\n- OCR for scanned documents\n- Structured JSON output\n- High accuracy extraction\n\n## Benefits:\n- Eliminates manual data entry\n- Handles various invoice formats\n- Consistent data structure\n- Scalable processing"
},
"typeVersion": 1
},
{
"id": "6f42014e-fe4b-4424-9a29-e73f1fc4575f",
"name": "Nota Adhesiva - Limpieza de Datos",
"type": "n8n-nodes-base.stickyNote",
"position": [
1984,
-32
],
"parameters": {
"color": 5,
"width": 320,
"height": 1202,
"content": "# Step 4: Data Cleaning & Enhancement 🧹\n\n**Advanced Data Processing**\n\nCleans and standardizes extracted data for business use.\n\n## Data Cleaning:\n- **Format Standardization**: Dates, amounts, text\n- **Validation**: Email formats, phone numbers\n- **Null Handling**: Missing data management\n- **Type Conversion**: String to numeric conversion\n\n## Enhancement Features:\n- **Confidence Scoring**: Data quality assessment\n- **Completeness Analysis**: Missing field detection\n- **Line Item Processing**: Individual item validation\n- **Metadata Addition**: Processing timestamps\n\n## Quality Assurance:\n- Removes invalid entries\n- Standardizes formats\n- Calculates data reliability\n- Prepares for validation"
},
"typeVersion": 1
},
{
"id": "3950a900-13c8-4aa5-b128-e9397220ab52",
"name": "Nota Adhesiva - Validación",
"type": "n8n-nodes-base.stickyNote",
"position": [
2304,
-32
],
"parameters": {
"color": 6,
"width": 320,
"height": 1202,
"content": "# Step 5: Business Rules Validation ✅\n\n**Comprehensive Validation Engine**\n\nApplies business rules and validation logic to ensure data quality.\n\n## Validation Types:\n- **Required Fields**: Critical data presence\n- **Data Integrity**: Amount calculations, date logic\n- **Business Rules**: Vendor approval, amount thresholds\n- **Duplicate Detection**: Invoice number uniqueness\n\n## Validation Results:\n- **Errors**: Critical issues blocking processing\n- **Warnings**: Non-critical issues requiring attention\n- **Scores**: Overall validation quality (0-100)\n- **Business Flags**: Rule-specific status\n\n## Advanced Features:\n- Configurable thresholds\n- Vendor whitelist checking\n- Amount calculation verification\n- Approval requirement detection"
},
"typeVersion": 1
},
{
"id": "daf3f597-b104-4c4c-abaf-5363f982a7a0",
"name": "Nota Adhesiva - Enrutamiento de Aprobación",
"type": "n8n-nodes-base.stickyNote",
"position": [
2624,
-32
],
"parameters": {
"color": 7,
"width": 320,
"height": 1202,
"content": "# Step 6: Approval Routing 🔀\n\n**Intelligent Decision Engine**\n\nRoutes invoices based on validation results and business rules.\n\n## Routing Logic:\n- **Auto-Process**: Clean invoices → Direct to accounting\n- **Approval Required**: Flagged invoices → Approval workflow\n- **Error Handling**: Invalid invoices → Manual review\n\n## Approval Triggers:\n- High amount thresholds\n- New/unverified vendors\n- Validation errors/warnings\n- Data quality issues\n\n## Benefits:\n- Automated decision making\n- Exception handling\n- Compliance enforcement\n- Workflow optimization\n\n## Efficiency:\n- Reduces manual review\n- Focuses attention on exceptions\n- Maintains audit trails\n- Ensures policy compliance"
},
"typeVersion": 1
},
{
"id": "b0e3beae-27ec-4543-8be6-b68b3c8ef89d",
"name": "Nota Adhesiva - Flujo de Aprobación",
"type": "n8n-nodes-base.stickyNote",
"position": [
2944,
-32
],
"parameters": {
"width": 320,
"height": 1202,
"content": "# Step 7: Approval Workflow 👥\n\n**Multi-Stage Approval Process**\n\nGenerates structured approval requests with comprehensive details.\n\n## Approval Features:\n- **Priority Classification**: High/Medium/Normal\n- **Multi-stage Workflow**: Role-based approvals\n- **Detailed Context**: All validation results\n- **Interactive Notifications**: Telegram with buttons\n\n## Approval Stages:\n1. **Finance Manager**: High-value invoices\n2. **Procurement**: New vendor verification\n3. **Department Head**: Final approval\n\n## Rich Context:\n- Invoice summary\n- Validation issues\n- Business rule flags\n- Approval reasoning\n\n## User Experience:\n- Clear approval messages\n- One-click approve/reject\n- Detailed invoice preview\n- Audit trail maintenance"
},
"typeVersion": 1
},
{
"id": "cd228530-faa8-4685-a2dd-505ca1d2d2ff",
"name": "Nota Adhesiva - Integración de Sistemas",
"type": "n8n-nodes-base.stickyNote",
"position": [
3264,
-32
],
"parameters": {
"color": 4,
"width": 544,
"height": 1202,
"content": "# Step 8: System Integration 🔗\n\n**Seamless Accounting Integration**\n\nDirect integration with accounting systems for automated processing.\n\n## Integration Features:\n- **API-Based**: RESTful API integration\n- **Structured Data**: Clean JSON payload\n- **Metadata Included**: Processing context\n- **Error Handling**: Retry logic and logging\n\n## Data Payload:\n- Complete invoice data\n- Validation results\n- Processing metadata\n- Audit information\n\n## Supported Systems:\n- QuickBooks\n- SAP\n- NetSuite\n- Xero\n- Custom ERP systems\n\n## Benefits:\n- Eliminates double entry\n- Real-time processing\n- Data consistency\n- Automated reconciliation\n- Audit trail preservation"
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "7e6fed6c-3ee0-42af-988e-fb8c404015b5",
"connections": {
"4d24fd12-5442-4112-b997-2e6b9ece768c": {
"main": [
[
{
"node": "4197b894-434f-42b6-a728-b6773af9b54a",
"type": "main",
"index": 0
}
]
]
},
"4197b894-434f-42b6-a728-b6773af9b54a": {
"main": [
[
{
"node": "44e738e0-652a-40ff-8a9b-d4d8381771ef",
"type": "main",
"index": 0
}
]
]
},
"7980050d-408f-4b3a-8e10-fad41c143eff": {
"main": [
[
{
"node": "8d543b5f-9d0a-48b0-9589-d9c9c5a0adb1",
"type": "main",
"index": 0
}
]
]
},
"b32637a8-8941-4fea-b6cb-b2272d25eaa4": {
"main": [
[
{
"node": "4197b894-434f-42b6-a728-b6773af9b54a",
"type": "main",
"index": 0
}
]
]
},
"92ee2ffa-df6f-447c-bc74-bc78a40e90bf": {
"main": [
[
{
"node": "e2f6f5d5-a8b8-41df-8113-f45242fa2c9f",
"type": "main",
"index": 0
}
]
]
},
"cc08bf61-cb49-4cb5-be64-a9068c7c0486": {
"main": [
[
{
"node": "7980050d-408f-4b3a-8e10-fad41c143eff",
"type": "main",
"index": 0
}
]
]
},
"c891bcd4-df84-4fde-930d-e1eba7f679d0": {
"main": [
[
{
"node": "cc08bf61-cb49-4cb5-be64-a9068c7c0486",
"type": "main",
"index": 0
}
]
]
},
"8d543b5f-9d0a-48b0-9589-d9c9c5a0adb1": {
"main": [
[
{
"node": "92ee2ffa-df6f-447c-bc74-bc78a40e90bf",
"type": "main",
"index": 0
}
]
]
},
"44e738e0-652a-40ff-8a9b-d4d8381771ef": {
"main": [
[
{
"node": "c891bcd4-df84-4fde-930d-e1eba7f679d0",
"type": "main",
"index": 0
}
]
]
}
}
}¿Cómo usar este flujo de trabajo?
Copie el código de configuración JSON de arriba, cree un nuevo flujo de trabajo en su instancia de n8n y seleccione "Importar desde JSON", pegue la configuración y luego modifique la configuración de credenciales según sea necesario.
¿En qué escenarios es adecuado este flujo de trabajo?
Avanzado - Procesamiento de facturas, Resumen de IA
¿Es de pago?
Este flujo de trabajo es completamente gratuito, puede importarlo y usarlo directamente. Sin embargo, tenga en cuenta que los servicios de terceros utilizados en el flujo de trabajo (como la API de OpenAI) pueden requerir un pago por su cuenta.
Flujos de trabajo relacionados recomendados
vinci-king-01
@vinci-king-01Compartir este flujo de trabajo