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 collects event reservations via an n8n form, checks capacity against n8n Data Tables, generates a ticket and QR code, emails an e-ticket with Gmail, and posts updates to Discord, includi
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