The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "DocFlow 01 - Gmail Intake",
"nodes": [
{
"parameters": {
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"filters": {
"q": "has:attachment filename:(pdf OR docx) -in:trash"
},
"options": {
"downloadAttachments": true
}
},
"id": "trigger-01",
"name": "Gmail Trigger",
"type": "n8n-nodes-base.gmailTrigger",
"typeVersion": 1.2,
"position": [
240,
300
],
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "strict",
"leftValue": ""
},
"conditions": [
{
"id": "has-binary",
"leftValue": "={{ Object.keys($binary || {}).length }}",
"rightValue": 0,
"operator": {
"type": "number",
"operation": "gt"
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "filter-01",
"name": "Has Attachment?",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
460,
300
]
},
{
"parameters": {
"operation": "extractFromFile",
"binaryPropertyName": "={{ Object.keys($binary)[0] }}",
"options": {}
},
"id": "extract-01",
"name": "Extract Text",
"type": "n8n-nodes-base.extractFromFile",
"typeVersion": 1,
"position": [
680,
300
]
},
{
"parameters": {
"jsCode": "const item = $input.first();\nconst meta = $('Gmail Trigger').first().json;\nconst binaryKey = Object.keys(item.binary || {})[0];\nconst binMeta = item.binary?.[binaryKey] || {};\nconst raw_text = item.json.text || item.json.data || '';\n\n// Load client config from a static file via Code-node fs is not available; in production, fetch from a Workflow Variable or external store.\n// For now, load a default config inline. Replace with your client config loader.\nconst clientConfig = {\n client_id: 'moamen',\n thresholds: { min_text_length: 50, classify_min_confidence: 0.7, extract_min_confidence: 0.8 },\n destinations: { invoices: { spreadsheet_id: '1JxBDiQbPqP4_9VYIatAhNldQX30Hpz_rwjr7BfK9Odo', tab: 'invoices', review_tab: 'review_queue' }, contracts: { database_id: '096266c29be944d5958fc59e08c99605' } },\n forms: { destination: { kind: 'sheets', spreadsheet_id: '1JxBDiQbPqP4_9VYIatAhNldQX30Hpz_rwjr7BfK9Odo', tab: 'forms' }, fields: [] },\n telegram: { chat_id: 'REPLACE_WITH_TELEGRAM_CHAT_ID' }\n};\n\nconst envelope = {\n doc_id: crypto.randomUUID(),\n received_at: new Date().toISOString(),\n source: 'gmail',\n source_meta: {\n email_id: meta.id || '',\n email_from: meta.from || meta.headers?.from || '',\n filename: binMeta.fileName || '',\n drive_file_link: ''\n },\n client_id: clientConfig.client_id,\n client_config: clientConfig,\n raw_text\n};\nreturn [{ json: envelope }];"
},
"id": "build-env-01",
"name": "Build Envelope",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
900,
300
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "strict",
"leftValue": ""
},
"conditions": [
{
"id": "text-len-gate",
"leftValue": "={{ ($json.raw_text || '').length }}",
"rightValue": "={{ $json.client_config?.thresholds?.min_text_length ?? 50 }}",
"operator": {
"type": "number",
"operation": "gte"
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "len-gate-01",
"name": "Text Length Gate",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
1120,
300
]
},
{
"parameters": {
"workflowId": {
"__rl": true,
"value": "REPLACE_WITH_WORKFLOW_03_ID",
"mode": "id"
},
"options": {}
},
"id": "call-03",
"name": "Call Classifier",
"type": "n8n-nodes-base.executeWorkflow",
"typeVersion": 1.2,
"position": [
1340,
200
]
},
{
"parameters": {
"jsCode": "const env = $input.first().json;\nenv.review_reason = 'low_text';\nreturn [{ json: env }];"
},
"id": "tag-low-text-01",
"name": "Tag Low Text",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1340,
400
]
},
{
"parameters": {
"workflowId": {
"__rl": true,
"value": "REPLACE_WITH_WORKFLOW_07_ID",
"mode": "id"
},
"options": {}
},
"id": "call-07-from-01",
"name": "Route to Review",
"type": "n8n-nodes-base.executeWorkflow",
"typeVersion": 1.2,
"position": [
1560,
400
]
}
],
"connections": {
"Gmail Trigger": {
"main": [
[
{
"node": "Has Attachment?",
"type": "main",
"index": 0
}
]
]
},
"Has Attachment?": {
"main": [
[
{
"node": "Extract Text",
"type": "main",
"index": 0
}
],
[]
]
},
"Extract Text": {
"main": [
[
{
"node": "Build Envelope",
"type": "main",
"index": 0
}
]
]
},
"Build Envelope": {
"main": [
[
{
"node": "Text Length Gate",
"type": "main",
"index": 0
}
]
]
},
"Text Length Gate": {
"main": [
[
{
"node": "Call Classifier",
"type": "main",
"index": 0
}
],
[
{
"node": "Tag Low Text",
"type": "main",
"index": 0
}
]
]
},
"Tag Low Text": {
"main": [
[
{
"node": "Route to Review",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"tags": [
{
"name": "docflow"
}
]
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
gmailOAuth2
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
DocFlow 01 - Gmail Intake. Uses gmailTrigger. Event-driven trigger; 8 nodes.
Source: https://github.com/Moamen-Elsharkawy/docflow-ai/blob/main/n8n-exports/01-gmail-intake.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
2025-12-03 fix JS code in node
Receive any business document via email. The attachment is automatically classified (Invoice, Contract, or Purchase Order) using easybits Extractor, then routed down the correct path where a second Ex
The goal is to reduce inbox noise and automatically organize repetitive types of emails so that imprtant messages remain visible while unsolicited or promotional emails are handled automatically. When
This workflow monitors Gmail for invoice emails with PDF attachments, sends PDFs to Parseur for data extraction, checks and creates vendor bills in Zoho Books to prevent duplicates, and archives the o
This template is built to be customized for your specific needs. This template has the core logic and n8n node specific references sorted to work with dynamic file names throughout the workflow. Store