PDFベクトル、Google Drive、データベースを使用した領秤データの抽出と保存

上級

これはInvoice Processing, AI Summarization, Multimodal AI分野の自動化ワークフローで、26個のノードを含みます。主にIf, Code, Slack, Webhook, Postgresなどのノードを使用。 PDFベクトル、Google Drive、データベースを使って領収書データを抽出・保存する

前提条件
  • Slack Bot Token または Webhook URL
  • HTTP Webhookエンドポイント(n8nが自動生成)
  • PostgreSQLデータベース接続情報
  • Google Drive API認証情報
ワークフロープレビュー
ノード接続関係を可視化、ズームとパンをサポート
ワークフローをエクスポート
以下のJSON設定をn8nにインポートして、このワークフローを使用できます
{
  "meta": {
    "instanceId": "placeholder"
  },
  "nodes": [
    {
      "id": "overview-note",
      "name": "ワークフロー概要",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        50,
        50
      ],
      "parameters": {
        "color": 5,
        "width": 350,
        "height": 200,
        "content": "## 📋 Invoice Processing Pipeline\n\nThis enterprise-grade workflow automates your entire accounts payable process:\n• **Monitors** multiple sources every 5 minutes\n• **Extracts** data using AI (30+ fields)\n• **Validates** vendors and calculations\n• **Routes** for approval based on amount\n• **Integrates** with your ERP system"
      },
      "typeVersion": 1
    },
    {
      "id": "setup-note",
      "name": "セットアップガイド",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        50,
        270
      ],
      "parameters": {
        "color": 4,
        "width": 300,
        "height": 180,
        "content": "## ⚙️ Initial Setup Required\n\n1. **Google Drive**: Create folder & set ID\n2. **Database**: Run schema creation script\n3. **PDF Vector**: Add API key in credentials\n4. **Slack/Email**: Configure notifications\n5. **ERP**: Set up API connection"
      },
      "typeVersion": 1
    },
    {
      "id": "step1-note",
      "name": "ステップ1: 収集",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        250,
        450
      ],
      "parameters": {
        "width": 280,
        "height": 160,
        "content": "## 1️⃣ Invoice Collection\n\nSchedule trigger runs every 5 minutes to:\n• Check Google Drive folder\n• Filter already processed files\n• Download new invoices only\n\n💡 Prevents duplicate processing"
      },
      "typeVersion": 1
    },
    {
      "id": "step2-note",
      "name": "ステップ2: 抽出",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1050,
        450
      ],
      "parameters": {
        "width": 280,
        "height": 180,
        "content": "## 2️⃣ AI Data Extraction\n\nPDF Vector extracts:\n• Vendor details & Tax ID\n• Line items with SKUs\n• Tax calculations\n• Payment terms\n• Bank details\n\n✨ Handles any format!"
      },
      "typeVersion": 1
    },
    {
      "id": "step3-note",
      "name": "ステップ3: ベンダー",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1550,
        450
      ],
      "parameters": {
        "width": 280,
        "height": 160,
        "content": "## 3️⃣ Vendor Management\n\n• Looks up vendor in database\n• Creates new vendor if needed\n• Validates vendor status\n• Flags for review if new\n\n🔍 Maintains clean vendor data"
      },
      "typeVersion": 1
    },
    {
      "id": "step4-note",
      "name": "ステップ4: 検証",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2050,
        450
      ],
      "parameters": {
        "width": 280,
        "height": 200,
        "content": "## 4️⃣ Validation & Approval\n\n**Validates:**\n• Math calculations\n• Duplicate invoices\n• PO matching\n\n**Routes based on:**\n• >$10k → CFO\n• >$5k → Dept Head\n• >$1k → Manager"
      },
      "typeVersion": 1
    },
    {
      "id": "step5-note",
      "name": "ステップ5: 統合",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2550,
        450
      ],
      "parameters": {
        "color": 6,
        "width": 280,
        "height": 160,
        "content": "## 5️⃣ ERP Integration\n\nApproved invoices:\n• Save to database\n• Sync with QuickBooks/SAP\n• Update dashboards\n• Send confirmations\n\n✅ Fully automated!"
      },
      "typeVersion": 1
    },
    {
      "id": "schedule-trigger",
      "name": "5分毎に確認",
      "type": "n8n-nodes-base.scheduleTrigger",
      "notes": "Monitor for new invoices",
      "position": [
        250,
        300
      ],
      "parameters": {
        "unit": "minutes",
        "value": 5,
        "events": [
          "workflowActivate"
        ]
      },
      "typeVersion": 1.1
    },
    {
      "id": "google-drive-list",
      "name": "新規請求書一覧",
      "type": "n8n-nodes-base.googleDrive",
      "notes": "Get unprocessed invoices",
      "position": [
        450,
        300
      ],
      "parameters": {
        "options": {
          "fields": [
            "id",
            "name",
            "mimeType",
            "createdTime"
          ]
        },
        "folderId": "={{ $json.invoiceFolderId }}",
        "resource": "file",
        "operation": "list"
      },
      "typeVersion": 3
    },
    {
      "id": "check-processed",
      "name": "処理済みチェック",
      "type": "n8n-nodes-base.postgres",
      "notes": "Avoid reprocessing",
      "position": [
        650,
        300
      ],
      "parameters": {
        "query": "SELECT file_id FROM processed_invoices WHERE file_id IN ({{ $json.files.map(f => `'${f.id}'`).join(',') }})",
        "operation": "executeQuery"
      },
      "typeVersion": 2.4
    },
    {
      "id": "filter-new",
      "name": "新規ファイルフィルタリング",
      "type": "n8n-nodes-base.code",
      "position": [
        850,
        300
      ],
      "parameters": {
        "jsCode": "// Filter out already processed files\nconst files = $node['List New Invoices'].json.files;\nconst processedIds = $node['Check Already Processed'].json.map(row => row.file_id);\n\nconst newFiles = files.filter(file => !processedIds.includes(file.id));\n\nreturn newFiles.map(file => ({ json: file }));"
      },
      "typeVersion": 2
    },
    {
      "id": "google-drive-download",
      "name": "請求書ダウンロード",
      "type": "n8n-nodes-base.googleDrive",
      "notes": "Get file content",
      "position": [
        1050,
        300
      ],
      "parameters": {
        "fileId": "={{ $json.id }}",
        "operation": "download"
      },
      "typeVersion": 3
    },
    {
      "id": "pdfvector-extract",
      "name": "請求書データ抽出",
      "type": "n8n-nodes-pdfvector.pdfVector",
      "notes": "AI extraction",
      "position": [
        1250,
        300
      ],
      "parameters": {
        "prompt": "Extract comprehensive invoice details including invoice number, date, vendor details (name, address, tax ID, contact), customer info, PO number if present, all line items with item codes/SKUs, descriptions, quantities, unit prices, amounts, tax details by type, payment terms, bank details, and any special instructions. Handle multi-page invoices and various formats.",
        "schema": "{\"type\":\"object\",\"properties\":{\"invoiceNumber\":{\"type\":\"string\"},\"invoiceDate\":{\"type\":\"string\"},\"dueDate\":{\"type\":\"string\"},\"poNumber\":{\"type\":\"string\"},\"vendor\":{\"type\":\"object\",\"properties\":{\"name\":{\"type\":\"string\"},\"address\":{\"type\":\"string\"},\"city\":{\"type\":\"string\"},\"state\":{\"type\":\"string\"},\"postalCode\":{\"type\":\"string\"},\"country\":{\"type\":\"string\"},\"taxId\":{\"type\":\"string\"},\"email\":{\"type\":\"string\"},\"phone\":{\"type\":\"string\"}}},\"customer\":{\"type\":\"object\",\"properties\":{\"name\":{\"type\":\"string\"},\"address\":{\"type\":\"string\"},\"department\":{\"type\":\"string\"}}},\"lineItems\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"itemCode\":{\"type\":\"string\"},\"description\":{\"type\":\"string\"},\"quantity\":{\"type\":\"number\"},\"unitPrice\":{\"type\":\"number\"},\"amount\":{\"type\":\"number\"},\"taxRate\":{\"type\":\"number\"}}}},\"subtotal\":{\"type\":\"number\"},\"taxDetails\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"type\":{\"type\":\"string\"},\"rate\":{\"type\":\"number\"},\"amount\":{\"type\":\"number\"}}}},\"total\":{\"type\":\"number\"},\"currency\":{\"type\":\"string\"},\"paymentTerms\":{\"type\":\"string\"},\"bankDetails\":{\"type\":\"object\",\"properties\":{\"bankName\":{\"type\":\"string\"},\"accountNumber\":{\"type\":\"string\"},\"routingNumber\":{\"type\":\"string\"}}},\"notes\":{\"type\":\"string\"}},\"required\":[\"invoiceNumber\",\"vendor\",\"total\"],\"additionalProperties\":false}",
        "resource": "document",
        "inputType": "file",
        "operation": "extract",
        "binaryPropertyName": "data"
      },
      "typeVersion": 1
    },
    {
      "id": "lookup-vendor",
      "name": "ベンダー検索",
      "type": "n8n-nodes-base.postgres",
      "notes": "Check vendor database",
      "position": [
        1450,
        300
      ],
      "parameters": {
        "query": "SELECT * FROM vendor_master WHERE LOWER(name) = LOWER('{{ $json.data.vendor.name }}') OR tax_id = '{{ $json.data.vendor.taxId }}' LIMIT 1",
        "operation": "executeQuery"
      },
      "typeVersion": 2.4
    },
    {
      "id": "vendor-exists",
      "name": "ベンダー存在確認",
      "type": "n8n-nodes-base.if",
      "position": [
        1650,
        300
      ],
      "parameters": {
        "conditions": {
          "boolean": [
            {
              "value1": "={{ $json.length > 0 }}",
              "value2": true
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "create-vendor",
      "name": "新規ベンダー作成",
      "type": "n8n-nodes-base.postgres",
      "notes": "Add to vendor master",
      "position": [
        1850,
        400
      ],
      "parameters": {
        "query": "INSERT INTO vendor_master (name, address, city, state, postal_code, country, tax_id, email, phone, status, created_at) VALUES ('{{ $node['Extract Invoice Data'].json.data.vendor.name }}', '{{ $node['Extract Invoice Data'].json.data.vendor.address }}', '{{ $node['Extract Invoice Data'].json.data.vendor.city }}', '{{ $node['Extract Invoice Data'].json.data.vendor.state }}', '{{ $node['Extract Invoice Data'].json.data.vendor.postalCode }}', '{{ $node['Extract Invoice Data'].json.data.vendor.country }}', '{{ $node['Extract Invoice Data'].json.data.vendor.taxId }}', '{{ $node['Extract Invoice Data'].json.data.vendor.email }}', '{{ $node['Extract Invoice Data'].json.data.vendor.phone }}', 'pending_review', NOW()) RETURNING vendor_id",
        "operation": "executeQuery"
      },
      "typeVersion": 2.4
    },
    {
      "id": "validate-invoice",
      "name": "請求書検証・情報付加",
      "type": "n8n-nodes-base.code",
      "notes": "Complex validation logic",
      "position": [
        2050,
        300
      ],
      "parameters": {
        "jsCode": "// Comprehensive invoice validation\nconst invoice = $node['Extract Invoice Data'].json.data;\nconst vendor = $node['Lookup Vendor'].json[0] || $node['Create New Vendor'].json[0];\nlet validationResult = {\n  invoice: invoice,\n  vendorId: vendor.vendor_id,\n  vendorStatus: vendor.status,\n  errors: [],\n  warnings: [],\n  requiresApproval: false,\n  approvalLevel: 0\n};\n\n// Validate calculations\nif (invoice.lineItems && invoice.lineItems.length > 0) {\n  const calculatedSubtotal = invoice.lineItems.reduce((sum, item) => sum + (item.amount || 0), 0);\n  if (Math.abs(calculatedSubtotal - invoice.subtotal) > 0.01) {\n    validationResult.errors.push(`Line items total (${calculatedSubtotal}) doesn't match subtotal (${invoice.subtotal})`);\n  }\n}\n\n// Validate tax calculations\nconst totalTax = invoice.taxDetails ? invoice.taxDetails.reduce((sum, tax) => sum + tax.amount, 0) : 0;\nconst calculatedTotal = (invoice.subtotal || 0) + totalTax;\nif (Math.abs(calculatedTotal - invoice.total) > 0.01) {\n  validationResult.errors.push(`Calculated total (${calculatedTotal}) doesn't match invoice total (${invoice.total})`);\n}\n\n// Check duplicate invoice\nconst duplicateCheck = await $node['Check Duplicate'].json;\nif (duplicateCheck.length > 0) {\n  validationResult.errors.push('Duplicate invoice detected');\n}\n\n// Determine approval requirements\nif (invoice.total > 10000) {\n  validationResult.requiresApproval = true;\n  validationResult.approvalLevel = 3; // CFO\n} else if (invoice.total > 5000) {\n  validationResult.requiresApproval = true;\n  validationResult.approvalLevel = 2; // Department Head\n} else if (invoice.total > 1000 || vendor.status === 'pending_review') {\n  validationResult.requiresApproval = true;\n  validationResult.approvalLevel = 1; // Manager\n}\n\n// Check PO if provided\nif (invoice.poNumber) {\n  const poCheck = await $node['Check PO'].json;\n  if (poCheck.length === 0) {\n    validationResult.warnings.push('PO number not found in system');\n  } else {\n    const po = poCheck[0];\n    if (invoice.total > po.remaining_amount) {\n      validationResult.errors.push('Invoice amount exceeds PO remaining balance');\n    }\n  }\n}\n\nvalidationResult.isValid = validationResult.errors.length === 0;\n\nreturn [{ json: validationResult }];"
      },
      "typeVersion": 2
    },
    {
      "id": "check-duplicate",
      "name": "重複チェック",
      "type": "n8n-nodes-base.postgres",
      "notes": "Prevent double payment",
      "position": [
        1850,
        200
      ],
      "parameters": {
        "query": "SELECT invoice_id FROM invoices WHERE vendor_id = {{ $json.vendorId }} AND invoice_number = '{{ $json.invoice.invoiceNumber }}' LIMIT 1",
        "operation": "executeQuery"
      },
      "typeVersion": 2.4
    },
    {
      "id": "check-po",
      "name": "発注書チェック",
      "type": "n8n-nodes-base.postgres",
      "notes": "3-way matching",
      "position": [
        1850,
        100
      ],
      "parameters": {
        "query": "SELECT po_number, total_amount, used_amount, (total_amount - used_amount) as remaining_amount FROM purchase_orders WHERE po_number = '{{ $node['Extract Invoice Data'].json.data.poNumber }}' AND status = 'active'",
        "operation": "executeQuery"
      },
      "typeVersion": 2.4
    },
    {
      "id": "needs-approval",
      "name": "承認必要?",
      "type": "n8n-nodes-base.if",
      "position": [
        2250,
        300
      ],
      "parameters": {
        "conditions": {
          "boolean": [
            {
              "value1": "={{ $json.requiresApproval }}",
              "value2": true
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "send-approval",
      "name": "承認リクエスト送信",
      "type": "n8n-nodes-base.slack",
      "notes": "Notify approvers",
      "position": [
        2450,
        400
      ],
      "parameters": {
        "text": "New invoice requires approval:\n*Vendor:* {{ $json.invoice.vendor.name }}\n*Invoice #:* {{ $json.invoice.invoiceNumber }}\n*Amount:* {{ $json.invoice.currency }} {{ $json.invoice.total }}\n*Approval Level:* {{ $json.approvalLevel }}\n\n<{{ $node['Generate Approval Link'].json.approvalUrl }}|Click here to review and approve>",
        "channel": "#invoice-approvals",
        "attachments": [
          {
            "color": "#ff6d5a",
            "fields": {
              "item": [
                {
                  "short": true,
                  "title": "Due Date",
                  "value": "{{ $json.invoice.dueDate }}"
                },
                {
                  "short": true,
                  "title": "Payment Terms",
                  "value": "{{ $json.invoice.paymentTerms }}"
                }
              ]
            }
          }
        ]
      },
      "typeVersion": 2.1
    },
    {
      "id": "generate-approval-link",
      "name": "承認リンク生成",
      "type": "n8n-nodes-base.code",
      "notes": "Create secure link",
      "position": [
        2450,
        500
      ],
      "parameters": {
        "jsCode": "// Generate secure approval link\nconst baseUrl = 'https://your-domain.com/approve';\nconst token = require('crypto').randomBytes(32).toString('hex');\nconst approvalData = {\n  invoiceId: $json.invoice.invoiceNumber,\n  vendorId: $json.vendorId,\n  amount: $json.invoice.total,\n  token: token,\n  expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString()\n};\n\n// Store approval token in DB (not shown)\nconst approvalUrl = `${baseUrl}?token=${token}`;\n\nreturn [{ json: { ...approvalData, approvalUrl } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "save-invoice",
      "name": "請求書保存",
      "type": "n8n-nodes-base.postgres",
      "notes": "Store in database",
      "position": [
        2650,
        300
      ],
      "parameters": {
        "query": "INSERT INTO invoices (invoice_number, vendor_id, invoice_date, due_date, subtotal, tax_amount, total_amount, currency, status, po_number, raw_data, created_at) VALUES ('{{ $json.invoice.invoiceNumber }}', {{ $json.vendorId }}, '{{ $json.invoice.invoiceDate }}', '{{ $json.invoice.dueDate }}', {{ $json.invoice.subtotal }}, {{ $json.invoice.taxDetails.reduce((sum, t) => sum + t.amount, 0) }}, {{ $json.invoice.total }}, '{{ $json.invoice.currency }}', '{{ $json.requiresApproval ? \"pending_approval\" : \"approved\" }}', '{{ $json.invoice.poNumber }}', '{{ JSON.stringify($json.invoice) }}', NOW())",
        "operation": "executeQuery"
      },
      "typeVersion": 2.4
    },
    {
      "id": "quickbooks-create",
      "name": "QuickBooks作成",
      "type": "n8n-nodes-base.quickbooks",
      "notes": "ERP integration",
      "position": [
        2650,
        200
      ],
      "parameters": {
        "resource": "invoice",
        "operation": "create",
        "authentication": "oAuth2",
        "additionalFields": {
          "line": "={{ $json.invoice.lineItems }}",
          "dueDate": "={{ $json.invoice.dueDate }}",
          "txnDate": "={{ $json.invoice.invoiceDate }}",
          "vendorRef": {
            "value": "={{ $json.vendorId }}"
          },
          "customerMemo": "={{ $json.invoice.notes }}",
          "invoiceNumber": "={{ $json.invoice.invoiceNumber }}"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "mark-processed",
      "name": "処理済みマーク",
      "type": "n8n-nodes-base.postgres",
      "notes": "Track processed files",
      "position": [
        2850,
        300
      ],
      "parameters": {
        "query": "INSERT INTO processed_invoices (file_id, invoice_id) VALUES ('{{ $node['Download Invoice'].json.id }}', '{{ $node['Save Invoice'].json.invoice_id }}')",
        "operation": "executeQuery"
      },
      "typeVersion": 2.4
    },
    {
      "id": "update-dashboard",
      "name": "分析ダッシュボード更新",
      "type": "n8n-nodes-base.webhook",
      "notes": "Real-time metrics",
      "position": [
        3050,
        300
      ],
      "parameters": {
        "dashboardUrl": "https://your-analytics.com/embed",
        "updateFrequency": "realtime"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "save-invoice": {
      "main": [
        [
          {
            "node": "quickbooks-create",
            "type": "main",
            "index": 0
          },
          {
            "node": "mark-processed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "lookup-vendor": {
      "main": [
        [
          {
            "node": "vendor-exists",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "vendor-exists": {
      "main": [
        [
          {
            "node": "validate-invoice",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "create-vendor",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "needs-approval": {
      "main": [
        [
          {
            "node": "generate-approval-link",
            "type": "main",
            "index": 0
          },
          {
            "node": "save-invoice",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "save-invoice",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "google-drive-download": {
      "main": [
        [
          {
            "node": "pdfvector-extract",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "filter-new": {
      "main": [
        [
          {
            "node": "google-drive-download",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "create-vendor": {
      "main": [
        [
          {
            "node": "validate-invoice",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "google-drive-list": {
      "main": [
        [
          {
            "node": "check-processed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "mark-processed": {
      "main": [
        [
          {
            "node": "update-dashboard",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "pdfvector-extract": {
      "main": [
        [
          {
            "node": "lookup-vendor",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "schedule-trigger": {
      "main": [
        [
          {
            "node": "google-drive-list",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "generate-approval-link": {
      "main": [
        [
          {
            "node": "send-approval",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "check-processed": {
      "main": [
        [
          {
            "node": "filter-new",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "validate-invoice": {
      "main": [
        [
          {
            "node": "check-duplicate",
            "type": "main",
            "index": 0
          },
          {
            "node": "check-po",
            "type": "main",
            "index": 0
          },
          {
            "node": "needs-approval",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
よくある質問

このワークフローの使い方は?

上記のJSON設定コードをコピーし、n8nインスタンスで新しいワークフローを作成して「JSONからインポート」を選択、設定を貼り付けて認証情報を必要に応じて変更してください。

このワークフローはどんな場面に適していますか?

上級 - 請求書処理, AI要約, マルチモーダルAI

有料ですか?

このワークフローは完全無料です。ただし、ワークフローで使用するサードパーティサービス(OpenAI APIなど)は別途料金が発生する場合があります。

ワークフロー情報
難易度
上級
ノード数26
カテゴリー3
ノードタイプ10
難易度説明

上級者向け、16ノード以上の複雑なワークフロー

作成者
PDF Vector

PDF Vector

@pdfvector

A fully featured PDF APIs for developers - Parse any PDF or Word document, extract structured data, and access millions of academic papers - all through simple APIs.

外部リンク
n8n.ioで表示

このワークフローを共有

カテゴリー

カテゴリー: 34