ZZentralit
n8nintermediateWorkflowUpdated 22 Jan 2025

Google Drive folder → Airtable records

Watch a Drive folder, parse uploaded invoices with an OCR node, then create matching Airtable records with the file attached.

#n8n#google-drive#airtable#ocr#invoices

What this does

Finance drops invoice PDFs into a shared Google Drive folder. n8n picks them up, runs OCR to extract the vendor, amount, and due date, and creates a new Invoices record in Airtable with the file attached. Nothing is deleted — the original stays in Drive as the source of truth.

Nodes

  1. Google Drive Trigger — polls folder every 5 min, fileCreated event
  2. Google Drive → Download File — grabs the binary
  3. HTTP Request → OCR service — send the PDF to an OCR endpoint (Azure Document Intelligence, Mindee, or your own)
  4. Set — normalise the OCR output to {vendor, total, currency, dueDate}
  5. Airtable → Create Record — writes to Invoices with the PDF as an attachment field
  6. IF — did any required field fail to parse?
  7. Slack → Send Message on failures, to #finance-ops

Wire-up

Drive Trigger ──► Download ──► OCR (HTTP) ──► Set ──► IF
                                                     ├─► Airtable ──► done
                                                     └─► Slack (needs review)

OCR call shape

Using Mindee as an example — any provider with a similar JSON response works.

POST https://api.mindee.net/v1/products/mindee/invoices/v4/predict
Headers:
  Authorization: Token {{ $env.MINDEE_TOKEN }}
Body (multipart/form-data):
  document: <binary from previous node>

Field mapping (Set node)

{
  vendor:   $json.document.inference.prediction.supplier_name?.value ?? null,
  total:    $json.document.inference.prediction.total_amount?.value ?? null,
  currency: $json.document.inference.prediction.locale?.currency ?? "CHF",
  dueDate:  $json.document.inference.prediction.due_date?.value ?? null,
  fileId:   $("Google Drive Trigger").item.json.id,
  fileName: $("Google Drive Trigger").item.json.name,
}

Airtable create record

Airtable fieldSource
Vendor{{ $json.vendor }}
Amount{{ $json.total }}
Currency{{ $json.currency }}
Due date{{ $json.dueDate }}
PDFBinary from Download File
Source filehttps://drive.google.com/file/d/{{ $json.fileId }}
Statusliteral "Needs review"

The IF check

{{ $json.vendor && $json.total && $json.dueDate }}

If any of those are missing, send a Slack message instead of writing a half-baked record:

:warning: Invoice *{{ $json.fileName }}* couldn&apos;t be fully parsed.
Missing: {{ [!$json.vendor && 'vendor', !$json.total && 'total', !$json.dueDate && 'dueDate'].filter(Boolean).join(', ') }}
Open in Drive: https://drive.google.com/file/d/{{ $json.fileId }}

Why not just use a Zapier template?

  • OCR calls are cheap but not free. Having the node in your own n8n means you can add a cache (IF fileId already processed → skip) without paying Zapier task-per-step.
  • You can point the same workflow at multiple folders (one per legal entity) by changing a single folderId variable.

Importable JSON

Export the workflow and save it as public/flows-assets/n8n-drive-to-airtable.json. Import into your n8n instance and re-bind Google, Airtable, OCR, and Slack credentials.

Extensions

  • Duplicate detection. Query Airtable by filename + size before creating.
  • Auto-approval. If total < 500 CHF and vendor is in an allow-list, flip status to Approved and skip manual review.
  • Monthly roll-up. A second workflow runs on the 1st and emails a totals-per-vendor report out of Airtable.