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 →
{
"nodes": [
{
"parameters": {},
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
80,
80
],
"id": "9792d966-129f-4a4e-9396-931c19a77617",
"name": "When clicking 'Execute workflow'"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "label-input",
"name": "processLabel",
"value": "=GdriveFiled",
"type": "string"
},
{
"id": "ca5e7a2f-fc00-482f-816f-cb0eb6871ad4",
"name": "email_whitelist",
"value": "[\"payments-noreply@google.com\",\n\"invoice+statements@mail.anthropic.com\",\n\"uniqued4ve@gmail.com\"]",
"type": "array"
},
{
"id": "batch-mode-field",
"name": "batch_mode",
"value": "date",
"type": "string"
},
{
"id": "email-limit-field",
"name": "email_limit",
"value": 500,
"type": "number"
},
{
"id": "lookback-days-field",
"name": "lookback_days",
"value": 1,
"type": "number"
},
{
"id": "interval-days-field",
"name": "interval_days",
"value": 3,
"type": "number"
}
]
},
"options": {}
},
"id": "b6b6bb48-5366-4f71-aebb-fc26a4096600",
"name": "Set Label Variable",
"type": "n8n-nodes-base.set",
"typeVersion": 3.3,
"position": [
304,
80
]
},
{
"parameters": {
"resource": "label",
"operation": "create",
"name": "={{ $json.processLabel }}",
"options": {}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
528,
80
],
"id": "b01b4398-2f2b-4be9-ab1d-2138c224de61",
"name": "Create a label",
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"onError": "continueRegularOutput"
},
{
"parameters": {
"resource": "label"
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
752,
80
],
"id": "daf15002-9965-465f-be6a-bd6df342fbb8",
"name": "Get many labels",
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "99f03dda-f6ac-4bf7-9e50-0fdfd8814215",
"leftValue": "={{ $json.name }}",
"rightValue": "={{ $('Set Label Variable').item.json.processLabel }}",
"operator": {
"type": "string",
"operation": "equals",
"name": "filter.operator.equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.filter",
"typeVersion": 2.2,
"position": [
960,
80
],
"id": "b8111a4f-4448-4f2f-8dba-a2b170c09f27",
"name": "Filter"
},
{
"parameters": {
"jsCode": "// Read config from Set Label Variable node\nconst config = $('Set Label Variable').first().json;\nconst batchMode = config.batch_mode || 'date';\nconst emailLimit = config.email_limit ?? 500;\nconst lookbackDays = config.lookback_days ?? 1;\nconst intervalDays = config.interval_days ?? 3;\n\n// Dry run: 0 = don't process anything\nif (emailLimit === 0) return [];\n\nconst daysAgo = days => new Date(Date.now() - days * 86400000).toISOString().split('T')[0];\nconst todayDate = new Date($today);\ntodayDate.setDate(todayDate.getDate() + 1);\nconst endDate = todayDate.toISOString().split('T')[0];\n\n// Size mode: single wide interval, email_limit caps the fetch\nif (batchMode === 'size') {\n return [{ json: { start: '2000-01-01', end: endDate } }];\n}\n\n// Date mode: chunked intervals\nconst startDate = daysAgo(lookbackDays);\nconst intervals = [];\nlet current = new Date(startDate);\nconst end = new Date(endDate);\n\nwhile (current < end) {\n const intervalEnd = new Date(current);\n intervalEnd.setDate(intervalEnd.getDate() + intervalDays);\n intervals.push({\n json: {\n start: current.toISOString().split('T')[0],\n end: intervalEnd > end ? end.toISOString().split('T')[0] : intervalEnd.toISOString().split('T')[0]\n }\n });\n current = intervalEnd;\n}\nreturn intervals;"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
80,
320
],
"id": "8af55391-257f-47bc-a540-f35e3d28dabd",
"name": "Set Date-Range to process"
},
{
"parameters": {
"options": {}
},
"type": "n8n-nodes-base.splitInBatches",
"typeVersion": 3,
"position": [
304,
320
],
"id": "dbccc65c-81fe-45dc-8bc1-1ef7771197a0",
"name": "Loop Over Items2"
},
{
"parameters": {
"operation": "getAll",
"limit": "={{ $('Set Label Variable').item.json.email_limit }}",
"filters": {
"receivedAfter": "={{ $json.start }}",
"receivedBefore": "={{ $json.end }}"
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
528,
320
],
"id": "3ad587f5-4982-4980-83a4-607b86395e0d",
"name": "Get many messages",
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"options": {}
},
"type": "n8n-nodes-base.splitInBatches",
"typeVersion": 3,
"position": [
752,
320
],
"id": "119b10a1-3c56-4205-857c-e1838c00ce45",
"name": "Loop Over Items"
},
{
"parameters": {
"operation": "get",
"messageId": "={{ $json.id }}",
"simple": false,
"options": {
"dataPropertyAttachmentsPrefixName": "attachment_",
"downloadAttachments": true
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
960,
320
],
"id": "19a851f7-6a46-4dab-9fcf-fc6debb034cb",
"name": "Gmail",
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "9cde5ab0-1774-4855-99e9-999efcba6b12",
"name": "id",
"value": "={{ $('Loop Over Items').item.json.id }}",
"type": "string"
},
{
"id": "2a4a8528-47ef-4d35-a522-a0991eabb7af",
"name": "from-address",
"value": "={{ $input.item.json.From?.match(/<(.+?)>/)?.[1] || $input.item.json.from?.value?.[0]?.address || \"ERROR_in_EMAILs\" }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1184,
320
],
"id": "30a0f040-94ef-4892-ae36-b3d40a10284a",
"name": "Edit Fields"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "loose",
"version": 2
},
"conditions": [
{
"id": "c9f0b3eb-8520-414e-8ba9-3bb5a319c09e",
"leftValue": "={{ $('Set Label Variable').item.json.email_whitelist }}",
"rightValue": "={{ $json['from-address'] }}",
"operator": {
"type": "array",
"operation": "contains",
"rightType": "any"
}
}
],
"combinator": "and"
},
"looseTypeValidation": true,
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
1408,
320
],
"id": "0934bf87-dcac-4137-bf5e-574d4723256f",
"name": "If"
},
{
"parameters": {
"workflowId": {
"__rl": true,
"value": "lRCrJIj1AEsuNxts",
"mode": "list",
"cachedResultUrl": "/workflow/lRCrJIj1AEsuNxts",
"cachedResultName": "9_inbox_classifier_main"
},
"workflowInputs": {
"mappingMode": "defineBelow",
"value": {},
"matchingColumns": [],
"schema": [],
"attemptToConvertTypes": false,
"convertFieldsToString": true
},
"options": {
"waitForSubWorkflow": true
}
},
"type": "n8n-nodes-base.executeWorkflow",
"typeVersion": 1.2,
"position": [
1632,
320
],
"id": "ec45c843-296d-4b18-ae6b-565c9af7f522",
"name": "Analyze file",
"alwaysOutputData": true
},
{
"parameters": {
"operation": "addLabels",
"messageId": "={{ $('Edit Fields').item.json.id }}",
"labelIds": "={{ $('Filter').item.json.id }}"
},
"id": "e14e5c6d-a4ee-4342-8b0c-dc111fe6ec5a",
"name": "Mark as Processed",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
1840,
320
],
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"disabled": true
},
{
"parameters": {
"operation": "removeLabels",
"messageId": "={{ $('Edit Fields').item.json.id }}",
"labelIds": "={{ $('Filter').item.json.id }}"
},
"id": "ce0f5ccd-f19c-4ece-b07e-d191b8a41628",
"name": "Remove label from message",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
2064,
320
],
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"disabled": true
},
{
"parameters": {
"content": "## Configuration (Set Label Variable node)\n\nAll settings are in the first Set node \u2014 edit them like cells in a spreadsheet.\n\n| Field | What it does | Default |\n|-------|-------------|--------|\n| `batch_mode` | `date` = scan by date chunks, `size` = fetch newest N emails | `date` |\n| `email_limit` | Max emails to fetch. **0 = dry run** | `500` |\n| `lookback_days` | How many days back to scan (date mode) | `1` |\n| `interval_days` | Days per batch chunk (date mode) | `3` |\n\n### Quick-start test\n1. Send yourself 1-2 emails with a PDF attachment\n2. Add your email address to `email_whitelist`\n3. Set `email_limit` to `2`, `lookback_days` to `1`\n4. Execute workflow, click each node to inspect output\n\n### Second test: process all your test emails\nSet `batch_mode` to `size`, `email_limit` to `50` \u2014 fetches up to 50 newest emails regardless of date.\n\n### Clean up\nEnable **Remove label from message** node and re-run, or remove `GdriveFiled` label manually in Gmail.\n\nFull guide: `docs/testing-gmail-processor.md`",
"height": 480,
"width": 700
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
1120,
-16
],
"id": "aa55c017-a560-4c7e-9585-356aa99f6d59",
"name": "Sticky Note"
},
{
"parameters": {
"content": "### Label nodes (both disabled)\nThe main workflow (inbox-attachment-organizer)\nnow handles all Gmail labeling:\n`inProgress` \u2192 `n8n` / `gdr`.\n\nThese nodes are disabled to avoid\nredundant `GdriveFiled` labels.",
"height": 332,
"width": 398,
"color": 4
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
1792,
112
],
"id": "504eafb5-6389-449d-a21f-c9f08aca179d",
"name": "Sticky Note1"
}
],
"connections": {
"When clicking 'Execute workflow'": {
"main": [
[
{
"node": "Set Label Variable",
"type": "main",
"index": 0
}
]
]
},
"Set Label Variable": {
"main": [
[
{
"node": "Create a label",
"type": "main",
"index": 0
}
]
]
},
"Create a label": {
"main": [
[
{
"node": "Get many labels",
"type": "main",
"index": 0
}
]
]
},
"Get many labels": {
"main": [
[
{
"node": "Filter",
"type": "main",
"index": 0
}
]
]
},
"Filter": {
"main": [
[
{
"node": "Set Date-Range to process",
"type": "main",
"index": 0
}
]
]
},
"Set Date-Range to process": {
"main": [
[
{
"node": "Loop Over Items2",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items2": {
"main": [
[],
[
{
"node": "Get many messages",
"type": "main",
"index": 0
}
]
]
},
"Get many messages": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[
{
"node": "Loop Over Items2",
"type": "main",
"index": 0
}
],
[
{
"node": "Gmail",
"type": "main",
"index": 0
}
]
]
},
"Gmail": {
"main": [
[
{
"node": "Edit Fields",
"type": "main",
"index": 0
}
]
]
},
"Edit Fields": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"If": {
"main": [
[
{
"node": "Analyze file",
"type": "main",
"index": 0
}
],
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Analyze file": {
"main": [
[
{
"node": "Mark as Processed",
"type": "main",
"index": 0
}
]
]
},
"Mark as Processed": {
"main": [
[
{
"node": "Remove label from message",
"type": "main",
"index": 0
}
]
]
},
"Remove label from message": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
}
}
}
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
Gmail-Processor-Datesize. Uses gmail. Event-driven trigger; 17 nodes.
Source: https://github.com/runfish5/micro-services/blob/main/projects/n8n/04_inbox-attachment-organizer/workflows/subworkflows/gmail-processor-datesize.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.
This workflow runs every Monday at 8 AM and automatically monitors your Jira project, measures progress against the active sprint, and delivers a structured report to stakeholders — with zero manual e
2025-12-03 fix JS code in node
Fetches all open sprint tickets daily from your Jira project Analyzes each ticket for overdue days and blocked status Routes to the right escalation level: assignee email → team Google Chat alert → ma
This workflow listens for Stripe payment failures, looks up the customer in HighLevel, logs or updates the failure in an n8n Data Table, and—when not recently automated—creates a Stripe coupon and ema
This n8n template demonstrates how to triage tenant maintenance requests automatically; matching each ticket to the right contractor by category and postcode area, dispatching the job by email and SMS