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
- Google Drive Trigger — polls folder every 5 min,
fileCreatedevent - Google Drive → Download File — grabs the binary
- HTTP Request → OCR service — send the PDF to an OCR endpoint (Azure Document Intelligence, Mindee, or your own)
- Set — normalise the OCR output to
{vendor, total, currency, dueDate} - Airtable → Create Record — writes to
Invoiceswith the PDF as an attachment field - IF — did any required field fail to parse?
- 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 field | Source |
|---|---|
| Vendor | {{ $json.vendor }} |
| Amount | {{ $json.total }} |
| Currency | {{ $json.currency }} |
| Due date | {{ $json.dueDate }} |
| Binary from Download File | |
| Source file | https://drive.google.com/file/d/{{ $json.fileId }} |
| Status | literal "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'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
fileIdalready 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
folderIdvariable.
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 CHFand vendor is in an allow-list, flip status toApprovedand skip manual review. - Monthly roll-up. A second workflow runs on the 1st and emails a totals-per-vendor report out of Airtable.