This workflow corresponds to n8n.io template #16812 — we link there as the canonical source.
This workflow follows the Google Drive → Google Drive 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": "Auto-file Google Drive inbox files into dated folders by filename rules",
"tags": [],
"nodes": [
{
"name": "Watch Inbox Folder",
"type": "n8n-nodes-base.googleDriveTrigger",
"position": [
-160,
544
],
"parameters": {
"event": "fileCreated",
"options": {
"fileType": "all"
},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"triggerOn": "specificFolder",
"folderToWatch": {
"__rl": true,
"mode": "list",
"value": ""
},
"authentication": "oAuth2"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"name": "Plan Destination From Rules",
"type": "n8n-nodes-base.code",
"onError": "continueErrorOutput",
"position": [
224,
544
],
"parameters": {
"mode": "runOnceForAllItems",
"jsCode": "// ====================================================================\n// EDIT HERE: FILENAME RULES (the only block most people change)\n// Each rule maps a filename pattern to a destination Type (folder name).\n// Patterns are case-insensitive regular expressions, checked top to bottom,\n// and the FIRST match wins, so put more specific rules higher.\n// Add, remove, or reorder lines to match how you file documents.\n// Files that match no rule are filed under FALLBACK_TYPE.\n// ====================================================================\nconst RULES = [\n { pattern: 'contract|agreement', type: 'Contracts' },\n { pattern: 'invoice|inv[ _-]?[0-9]|receipt|bill', type: 'Invoices' },\n { pattern: 'scan|scanned|camscanner|img[ _-]?[0-9]', type: 'Scans' },\n { pattern: 'report|summary|q[1-4]|monthly|weekly|forecast', type: 'Reports' },\n];\nconst FALLBACK_TYPE = '_Unsorted';\n\n// Drive folder ID that holds the dated archive tree. Use a folder that is NOT\n// the watched inbox, so filed documents are not picked up again. Copy the ID\n// from the folder URL: drive.google.com/drive/folders/THIS_PART\nconst FILED_ROOT_FOLDER_ID = 'PASTE_YOUR_FILED_ROOT_FOLDER_ID_HERE';\n// ====================================================================\n// No need to edit below this line.\n// ====================================================================\n\nconst out = [];\nconst inputItems = $input.all();\nfor (let i = 0; i < inputItems.length; i++) {\n const file = inputItems[i].json;\n const filename = String(file.name || '');\n let type = FALLBACK_TYPE;\n let matchedRule = '';\n for (const rule of RULES) {\n let re;\n try { re = new RegExp(rule.pattern, 'i'); } catch (err) { continue; }\n if (re.test(filename)) { type = rule.type; matchedRule = rule.pattern; break; }\n }\n const rawCreated = file.createdTime ? new Date(file.createdTime) : new Date();\n const created = isNaN(rawCreated.getTime()) ? new Date() : rawCreated;\n const year = String(created.getFullYear());\n const month = String(created.getMonth() + 1).padStart(2, '0');\n out.push({\n json: {\n fileId: String(file.id || ''),\n originalFilename: filename,\n mimeType: String(file.mimeType || ''),\n matchedRule: matchedRule,\n matched: matchedRule !== '',\n type: type,\n year: year,\n month: month,\n destinationPath: year + '/' + month + '/' + type,\n filedRootFolderId: FILED_ROOT_FOLDER_ID,\n loggedAt: new Date().toISOString(),\n },\n pairedItem: { item: i },\n });\n}\nreturn out;\n",
"language": "javaScript"
},
"typeVersion": 2
},
{
"name": "Route By Document Type",
"type": "n8n-nodes-base.switch",
"position": [
512,
480
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "Contracts",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": false,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.type }}",
"rightValue": "Contracts"
}
]
},
"renameOutput": true
},
{
"outputKey": "Invoices",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": false,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.type }}",
"rightValue": "Invoices"
}
]
},
"renameOutput": true
},
{
"outputKey": "Scans",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": false,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.type }}",
"rightValue": "Scans"
}
]
},
"renameOutput": true
},
{
"outputKey": "Reports",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": false,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.type }}",
"rightValue": "Reports"
}
]
},
"renameOutput": true
}
]
},
"options": {
"fallbackOutput": "extra",
"renameFallbackOutput": "Unsorted / Needs Review"
}
},
"typeVersion": 3.4
},
{
"name": "Find Year Folder",
"type": "n8n-nodes-base.googleDrive",
"onError": "continueErrorOutput",
"maxTries": 3,
"position": [
784,
704
],
"parameters": {
"limit": 1,
"filter": {},
"options": {
"fields": [
"id",
"name"
]
},
"resource": "fileFolder",
"operation": "search",
"returnAll": false,
"queryString": "=name='{{ $('Plan Destination From Rules').item.json.year }}' and '{{ $('Plan Destination From Rules').item.json.filedRootFolderId }}' in parents and mimeType='application/vnd.google-apps.folder' and trashed=false",
"searchMethod": "query",
"authentication": "oAuth2"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"retryOnFail": true,
"typeVersion": 3,
"alwaysOutputData": true,
"waitBetweenTries": 5000
},
{
"name": "Year Folder Exists?",
"type": "n8n-nodes-base.if",
"position": [
992,
688
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json.id }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.3
},
{
"name": "Create Year Folder",
"type": "n8n-nodes-base.googleDrive",
"onError": "continueErrorOutput",
"maxTries": 3,
"position": [
1200,
704
],
"parameters": {
"name": "={{ $('Plan Destination From Rules').item.json.year }}",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"options": {
"simplifyOutput": true
},
"folderId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Plan Destination From Rules').item.json.filedRootFolderId }}"
},
"resource": "folder",
"operation": "create",
"authentication": "oAuth2"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"retryOnFail": true,
"typeVersion": 3,
"waitBetweenTries": 5000
},
{
"name": "Find Month Folder",
"type": "n8n-nodes-base.googleDrive",
"onError": "continueErrorOutput",
"maxTries": 3,
"position": [
1376,
432
],
"parameters": {
"limit": 1,
"filter": {},
"options": {
"fields": [
"id",
"name"
]
},
"resource": "fileFolder",
"operation": "search",
"returnAll": false,
"queryString": "=name='{{ $('Plan Destination From Rules').item.json.month }}' and '{{ $json.id }}' in parents and mimeType='application/vnd.google-apps.folder' and trashed=false",
"searchMethod": "query",
"authentication": "oAuth2"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"retryOnFail": true,
"typeVersion": 3,
"alwaysOutputData": true,
"waitBetweenTries": 5000
},
{
"name": "Month Folder Exists?",
"type": "n8n-nodes-base.if",
"position": [
1584,
416
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json.id }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.3
},
{
"name": "Create Month Folder",
"type": "n8n-nodes-base.googleDrive",
"onError": "continueErrorOutput",
"maxTries": 3,
"position": [
1744,
560
],
"parameters": {
"name": "={{ $('Plan Destination From Rules').item.json.month }}",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"options": {
"simplifyOutput": true
},
"folderId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Find Year Folder').item.json.id || $('Create Year Folder').item.json.id }}"
},
"resource": "folder",
"operation": "create",
"authentication": "oAuth2"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"retryOnFail": true,
"typeVersion": 3,
"waitBetweenTries": 5000
},
{
"name": "Find Type Folder",
"type": "n8n-nodes-base.googleDrive",
"onError": "continueErrorOutput",
"maxTries": 3,
"position": [
1888,
400
],
"parameters": {
"limit": 1,
"filter": {},
"options": {
"fields": [
"id",
"name"
]
},
"resource": "fileFolder",
"operation": "search",
"returnAll": false,
"queryString": "=name='{{ $('Plan Destination From Rules').item.json.type }}' and '{{ $json.id }}' in parents and mimeType='application/vnd.google-apps.folder' and trashed=false",
"searchMethod": "query",
"authentication": "oAuth2"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"retryOnFail": true,
"typeVersion": 3,
"alwaysOutputData": true,
"waitBetweenTries": 5000
},
{
"name": "Type Folder Exists?",
"type": "n8n-nodes-base.if",
"position": [
2096,
384
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json.id }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.3
},
{
"name": "Create Type Folder",
"type": "n8n-nodes-base.googleDrive",
"onError": "continueErrorOutput",
"maxTries": 3,
"position": [
2320,
400
],
"parameters": {
"name": "={{ $('Plan Destination From Rules').item.json.type }}",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"options": {
"simplifyOutput": true
},
"folderId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Find Month Folder').item.json.id || $('Create Month Folder').item.json.id }}"
},
"resource": "folder",
"operation": "create",
"authentication": "oAuth2"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"retryOnFail": true,
"typeVersion": 3,
"waitBetweenTries": 5000
},
{
"name": "Move File Into Folder",
"type": "n8n-nodes-base.googleDrive",
"onError": "continueErrorOutput",
"maxTries": 3,
"position": [
2496,
288
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Plan Destination From Rules').item.json.fileId }}"
},
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"folderId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.id }}"
},
"resource": "file",
"operation": "move",
"authentication": "oAuth2"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"retryOnFail": true,
"typeVersion": 3,
"waitBetweenTries": 5000
},
{
"name": "Append Audit Row",
"type": "n8n-nodes-base.googleSheets",
"onError": "continueErrorOutput",
"maxTries": 3,
"position": [
2784,
448
],
"parameters": {
"columns": {
"value": {
"Type": "={{ $('Plan Destination From Rules').item.json.type }}",
"Notes": "",
"Status": "Filed",
"File ID": "={{ $('Plan Destination From Rules').item.json.fileId }}",
"Timestamp": "={{ $('Plan Destination From Rules').item.json.loggedAt }}",
"Matched Rule": "={{ $('Plan Destination From Rules').item.json.matchedRule }}",
"Destination Path": "={{ $('Plan Destination From Rules').item.json.destinationPath }}",
"Original Filename": "={{ $('Plan Destination From Rules').item.json.originalFilename }}"
},
"schema": [
{
"id": "Timestamp",
"type": "string",
"display": true,
"required": false,
"displayName": "Timestamp",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Original Filename",
"type": "string",
"display": true,
"required": false,
"displayName": "Original Filename",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Matched Rule",
"type": "string",
"display": true,
"required": false,
"displayName": "Matched Rule",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Type",
"type": "string",
"display": true,
"required": false,
"displayName": "Type",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Destination Path",
"type": "string",
"display": true,
"required": false,
"displayName": "Destination Path",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "File ID",
"type": "string",
"display": true,
"required": false,
"displayName": "File ID",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Status",
"type": "string",
"display": true,
"required": false,
"displayName": "Status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Notes",
"type": "string",
"display": true,
"required": false,
"displayName": "Notes",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"resource": "sheet",
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": ""
},
"documentId": {
"__rl": true,
"mode": "list",
"value": ""
},
"authentication": "oAuth2"
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"retryOnFail": true,
"typeVersion": 4.7,
"waitBetweenTries": 5000
},
{
"name": "Log Filing Failure",
"type": "n8n-nodes-base.googleSheets",
"position": [
3008,
640
],
"parameters": {
"columns": {
"value": {
"Type": "={{ $json.type || '' }}",
"Notes": "={{ $json.error?.message || 'Filing step failed, see execution log' }}",
"Status": "Failed",
"File ID": "={{ $json.fileId || $json.id || '' }}",
"Timestamp": "={{ $now.toISO() }}",
"Matched Rule": "={{ $json.matchedRule || '' }}",
"Destination Path": "={{ $json.destinationPath || '' }}",
"Original Filename": "={{ $json.originalFilename || $json.name || 'unknown' }}"
},
"schema": [
{
"id": "Timestamp",
"type": "string",
"display": true,
"required": false,
"displayName": "Timestamp",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Original Filename",
"type": "string",
"display": true,
"required": false,
"displayName": "Original Filename",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Matched Rule",
"type": "string",
"display": true,
"required": false,
"displayName": "Matched Rule",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Type",
"type": "string",
"display": true,
"required": false,
"displayName": "Type",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Destination Path",
"type": "string",
"display": true,
"required": false,
"displayName": "Destination Path",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "File ID",
"type": "string",
"display": true,
"required": false,
"displayName": "File ID",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Status",
"type": "string",
"display": true,
"required": false,
"displayName": "Status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Notes",
"type": "string",
"display": true,
"required": false,
"displayName": "Notes",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"resource": "sheet",
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": ""
},
"documentId": {
"__rl": true,
"mode": "list",
"value": ""
},
"authentication": "oAuth2"
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"name": "Sticky Note de7e10e6",
"type": "n8n-nodes-base.stickyNote",
"position": [
-272,
-368
],
"parameters": {
"width": 1508,
"height": 584,
"content": "## Drive Auto-Filer\n\nWatches one Google Drive inbox folder and files every new document into a dated Year/Month/Type folder tree, then records each move in a Google Sheet. No AI, fully rule based.\n\n### How it works\n1. The Google Drive trigger fires when a new file appears in the inbox folder.\n2. A Code node reads the file name against an editable rules table and works out the document Type (Contracts, Invoices, Scans, Reports, or _Unsorted) plus the destination path, for example 2026/06/Contracts.\n3. A Switch routes the file by Type. Each missing folder level (year, then month, then type) is found or created on the fly.\n4. The file is moved into the leaf folder and one audit row is appended to the Google Sheet.\n\n### Setup\n1. Connect Google Drive and Google Sheets credentials (the same Google account works for both).\n2. In the trigger, pick the inbox folder to watch.\n3. In the Plan Destination From Rules node, edit the rules table and paste your archive root folder ID.\n4. In the two Google Sheets nodes, pick your audit spreadsheet and tab.\n\n### Customize\nEdit the rules table to add document types, change folder names, or reorder matching. A bad file is logged and skipped, so one failure never stops the run."
},
"typeVersion": 1
},
{
"name": "Sticky Note 98813566",
"type": "n8n-nodes-base.stickyNote",
"position": [
96,
304
],
"parameters": {
"color": 7,
"width": 346,
"height": 434,
"content": "## Editable rules table\nOpen this node and edit the RULES block at the top. Each line maps a filename pattern (case-insensitive regex) to a Type folder. First match wins. Files matching nothing go to _Unsorted."
},
"typeVersion": 1
},
{
"name": "Sticky Note 96d66081",
"type": "n8n-nodes-base.stickyNote",
"position": [
720,
240
],
"parameters": {
"color": 7,
"width": 1944,
"height": 642,
"content": "## Find or create the Year/Month/Type tree\nEach level is searched under its parent. A missing level is created, an existing one is reused, so no duplicate folders build up. The file is then moved into the leaf folder."
},
"typeVersion": 1
},
{
"name": "Sticky Note ecc6f80e",
"type": "n8n-nodes-base.stickyNote",
"position": [
2704,
240
],
"parameters": {
"color": 7,
"width": 528,
"height": 572,
"content": "## Audit log\nEvery move appends one row: Timestamp, Original Filename, Matched Rule, Type, Destination Path, File ID, Status, Notes. Failures are logged with Status Failed so nothing is lost silently. Add these headers to row 1 of your sheet."
},
"typeVersion": 1
},
{
"name": "Sticky Note eff0ab00",
"type": "n8n-nodes-base.stickyNote",
"position": [
-272,
304
],
"parameters": {
"color": 3,
"width": 340,
"height": 438,
"content": "## Keep the archive root separate\nThe archive root folder (set in the rules node) must NOT be the watched inbox folder, or filed documents could be picked up again. Use a different folder."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"connections": {
"Append Audit Row": {
"main": [
[],
[
{
"node": "Log Filing Failure",
"type": "main",
"index": 0
}
]
]
},
"Find Type Folder": {
"main": [
[
{
"node": "Type Folder Exists?",
"type": "main",
"index": 0
}
],
[
{
"node": "Log Filing Failure",
"type": "main",
"index": 0
}
]
]
},
"Find Year Folder": {
"main": [
[
{
"node": "Year Folder Exists?",
"type": "main",
"index": 0
}
],
[
{
"node": "Log Filing Failure",
"type": "main",
"index": 0
}
]
]
},
"Find Month Folder": {
"main": [
[
{
"node": "Month Folder Exists?",
"type": "main",
"index": 0
}
],
[
{
"node": "Log Filing Failure",
"type": "main",
"index": 0
}
]
]
},
"Create Type Folder": {
"main": [
[
{
"node": "Move File Into Folder",
"type": "main",
"index": 0
}
],
[
{
"node": "Log Filing Failure",
"type": "main",
"index": 0
}
]
]
},
"Create Year Folder": {
"main": [
[
{
"node": "Find Month Folder",
"type": "main",
"index": 0
}
],
[
{
"node": "Log Filing Failure",
"type": "main",
"index": 0
}
]
]
},
"Watch Inbox Folder": {
"main": [
[
{
"node": "Plan Destination From Rules",
"type": "main",
"index": 0
}
]
]
},
"Create Month Folder": {
"main": [
[
{
"node": "Find Type Folder",
"type": "main",
"index": 0
}
],
[
{
"node": "Log Filing Failure",
"type": "main",
"index": 0
}
]
]
},
"Type Folder Exists?": {
"main": [
[
{
"node": "Move File Into Folder",
"type": "main",
"index": 0
}
],
[
{
"node": "Create Type Folder",
"type": "main",
"index": 0
}
]
]
},
"Year Folder Exists?": {
"main": [
[
{
"node": "Find Month Folder",
"type": "main",
"index": 0
}
],
[
{
"node": "Create Year Folder",
"type": "main",
"index": 0
}
]
]
},
"Month Folder Exists?": {
"main": [
[
{
"node": "Find Type Folder",
"type": "main",
"index": 0
}
],
[
{
"node": "Create Month Folder",
"type": "main",
"index": 0
}
]
]
},
"Move File Into Folder": {
"main": [
[
{
"node": "Append Audit Row",
"type": "main",
"index": 0
}
],
[
{
"node": "Log Filing Failure",
"type": "main",
"index": 0
}
]
]
},
"Route By Document Type": {
"main": [
[
{
"node": "Find Year Folder",
"type": "main",
"index": 0
}
],
[
{
"node": "Find Year Folder",
"type": "main",
"index": 0
}
],
[
{
"node": "Find Year Folder",
"type": "main",
"index": 0
}
],
[
{
"node": "Find Year Folder",
"type": "main",
"index": 0
}
],
[
{
"node": "Find Year Folder",
"type": "main",
"index": 0
}
]
]
},
"Plan Destination From Rules": {
"main": [
[
{
"node": "Route By Document Type",
"type": "main",
"index": 0
}
],
[
{
"node": "Log Filing Failure",
"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.
googleDriveOAuth2ApigoogleSheetsOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow monitors a Google Drive inbox folder for new files, classifies them by filename regex rules, files them into a Year/Month/Type folder structure in Google Drive, and logs each success or failure to a Google Sheets audit log. Triggers every minute when a new file is…
Source: https://n8n.io/workflows/16812/ — 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.
Automatically process invoices and receipts using Gemini OCR, extracting data directly into Google Sheets from multiple sources including Google Drive, Gmail, and Telegram. This powerful workflow ensu
Drop a contract (PDF, JPG, PNG) into a watched Google Drive folder. easybits Extractor classifies it (SaaS / Lease / Service / Insurance / Other) and pulls every renewal-relevant field in a single cal
This workflow watches a Google Drive folder for new audio files, sends them to Gladia for asynchronous transcription, saves the resulting Markdown transcript back to Google Drive, and appends a succes
Sales and marketing teams seeking efficient, hands‑free generation of personalized slide decks for each prospect from CSV lead lists.
OCR receipts from Google Drive. Uses httpRequest, googleDriveTrigger, googleDrive, googleSheets. Event-driven trigger; 10 nodes.