This workflow follows the Gmail → Gmail Trigger recipe pattern — see all workflows that pair these two integrations.
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": "Gmail Attachment by Sender - WORKING",
"nodes": [
{
"parameters": {
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"simple": false,
"filters": {},
"options": {
"downloadAttachments": true
}
},
"type": "n8n-nodes-base.gmailTrigger",
"typeVersion": 1.3,
"position": [
-96,
-112
],
"id": "b6ee9ec3-a7cb-467f-8146-1dd13ba4b45d",
"name": "Gmail Trigger",
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "a7bd38aa-9145-4bd2-82c5-d4da191d7d1d",
"leftValue": "={{ $('Gmail Trigger').item.binary }}",
"rightValue": "",
"operator": {
"type": "object",
"operation": "exists",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.filter",
"typeVersion": 2.2,
"position": [
112,
-112
],
"id": "fbc77f51-1ffa-4a1b-a412-f69bcf5ee062",
"name": "Filter"
},
{
"parameters": {
"operation": "get",
"messageId": "={{ $json.id }}",
"simple": false,
"options": {
"downloadAttachments": true
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
320,
-112
],
"id": "27f0f0b5-7b03-4fcb-936c-988b572a8e52",
"name": "Get a message",
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// Get the email data - it's in the Get a message node output\nconst messageData = $input.item.json;\n\n// Extract sender email from the payload headers\nlet senderEmail = 'unknown';\n\nif (messageData.payload && messageData.payload.headers) {\n // Find the From header\n const fromHeader = messageData.payload.headers.find(h => h.name === 'From');\n \n if (fromHeader && fromHeader.value) {\n const fromValue = fromHeader.value;\n \n // Extract email from formats like:\n // \"Name <email@domain.com>\" or just \"email@domain.com\"\n const emailMatch = fromValue.match(/<([^>]+)>/);\n if (emailMatch) {\n senderEmail = emailMatch[1]; // Extract from <>\n } else if (fromValue.includes('@')) {\n senderEmail = fromValue.trim(); // Plain email\n }\n }\n}\n\n// Create folder name from email (replace @ and special chars)\nconst folderName = senderEmail\n .replace('@', '_at_')\n .replace(/[/\\\\#%&{}<>*?$!'\":+`|=]/g, '_')\n .toLowerCase();\n\nreturn {\n json: {\n message_id: messageData.id || '',\n parent_folder_id: '1U1V3Dp4V_d07nltPhZ9PNd_DvJ8Zuu3E',\n sender_email: senderEmail,\n sender_folder: folderName\n }\n};"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
500,
-112
],
"id": "prepare_sender",
"name": "Prepare sender"
},
{
"parameters": {
"url": "=https://www.googleapis.com/drive/v3/files",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "googleDriveOAuth2Api",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "q",
"value": "=name='{{ $json.sender_folder }}' and mimeType='application/vnd.google-apps.folder' and '{{ $json.parent_folder_id }}' in parents and trashed=false"
},
{
"name": "fields",
"value": "files(id, name)"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
700,
-112
],
"id": "search_sender_folder",
"name": "Search sender folder",
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "folder_check_condition",
"leftValue": "={{ $json.files && $json.files.length > 0 }}",
"rightValue": "",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
900,
-112
],
"id": "if_folder_exists",
"name": "Folder exists?"
},
{
"parameters": {
"resource": "folder",
"operation": "create",
"name": "={{ $('Prepare sender').item.json.sender_folder }}",
"options": {
"folderId": {
"__rl": true,
"value": "={{ $('Prepare sender').item.json.parent_folder_id }}",
"mode": "id"
}
}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
1100,
0
],
"id": "create_sender_folder",
"name": "Create sender folder",
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "folder_id_found",
"name": "sender_folder_id",
"value": "={{ $json.files[0].id }}",
"type": "string"
},
{
"id": "sender_name",
"name": "sender_name",
"value": "={{ $('Prepare sender').item.json.sender_folder }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1100,
-220
],
"id": "use_found_folder",
"name": "Use found folder"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "folder_id_created",
"name": "sender_folder_id",
"value": "={{ $json.id }}",
"type": "string"
},
{
"id": "sender_name_created",
"name": "sender_name",
"value": "={{ $('Prepare sender').item.json.sender_folder }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1300,
0
],
"id": "use_created_folder",
"name": "Use created folder"
},
{
"parameters": {
"mode": "combine",
"combinationMode": "mergeByPosition",
"options": {}
},
"type": "n8n-nodes-base.merge",
"typeVersion": 2.1,
"position": [
1500,
-112
],
"id": "merge_folders",
"name": "Merge folders"
},
{
"parameters": {
"jsCode": "const senderFolderId = $input.item.json.sender_folder_id;\nconst senderName = $input.item.json.sender_name;\nconst binaryData = $('Get a message').item.binary;\nconst outputItems = [];\n\nfor (const key in binaryData) {\n outputItems.push({\n json: {\n sender_folder_id: senderFolderId,\n sender_name: senderName,\n attachment_name: key\n },\n binary: {\n data: binaryData[key]\n }\n });\n}\n\nreturn outputItems;"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1700,
-112
],
"id": "split_with_binary",
"name": "Split with binary"
},
{
"parameters": {
"operation": "upload",
"folderId": {
"__rl": true,
"value": "={{ $json.sender_folder_id }}",
"mode": "id"
},
"name": "={{ $json.attachment_name }}",
"binaryData": true,
"binaryPropertyName": "data",
"options": {}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
1900,
-112
],
"id": "upload_file",
"name": "Upload file",
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
}
}
],
"connections": {
"Gmail Trigger": {
"main": [
[
{
"node": "Filter",
"type": "main",
"index": 0
}
]
]
},
"Filter": {
"main": [
[
{
"node": "Get a message",
"type": "main",
"index": 0
}
]
]
},
"Get a message": {
"main": [
[
{
"node": "Prepare sender",
"type": "main",
"index": 0
}
]
]
},
"Prepare sender": {
"main": [
[
{
"node": "Search sender folder",
"type": "main",
"index": 0
}
]
]
},
"Search sender folder": {
"main": [
[
{
"node": "Folder exists?",
"type": "main",
"index": 0
}
]
]
},
"Folder exists?": {
"main": [
[
{
"node": "Use found folder",
"type": "main",
"index": 0
}
],
[
{
"node": "Create sender folder",
"type": "main",
"index": 0
}
]
]
},
"Create sender folder": {
"main": [
[
{
"node": "Use created folder",
"type": "main",
"index": 0
}
]
]
},
"Use found folder": {
"main": [
[
{
"node": "Merge folders",
"type": "main",
"index": 0
}
]
]
},
"Use created folder": {
"main": [
[
{
"node": "Merge folders",
"type": "main",
"index": 0
}
]
]
},
"Merge folders": {
"main": [
[
{
"node": "Split with binary",
"type": "main",
"index": 0
}
]
]
},
"Split with binary": {
"main": [
[
{
"node": "Upload file",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "4d4eff92-ce8b-4fed-8c00-36844be2edde",
"meta": {
"templateCredsSetupCompleted": true
},
"id": "DIFUbxCTf4T0kflc",
"tags": []
}
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.
gmailOAuth2googleDriveOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Gmail Attachment by Sender - WORKING. Uses gmailTrigger, gmail, httpRequest, googleDrive. Event-driven trigger; 12 nodes.
Source: https://github.com/zxyphoon/projects/blob/9aeec33b0f9ca4d58dc1c28c8469b78d9b144b1b/n8n/idk2.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.
Gmail Attachment Sender Folder - Final Working. Uses gmailTrigger, gmail, httpRequest, googleDrive. Event-driven trigger; 12 nodes.
Attachments Gmail to drive and google sheets. Uses stickyNote, gmailTrigger, httpRequest, googleDrive. Event-driven trigger; 17 nodes.
Automatically process labeled emails with attachments into organized Google Drive folders Teams or Individuals needing to: Automatically sort invoices, receipts, and files. Organize client documents b
AICARE Email Blast System. Uses googleDrive, httpRequest, googleSheets, gmail. Event-driven trigger; 39 nodes.
Client Form → Draft → Approve → Sign → Deliver, fully automated