This workflow follows the Google Drive → HTTP Request 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": "Media Sync (Local HDD \u2192 Google Drive)",
"nodes": [
{
"parameters": {
"triggerOn": "specificFolder",
"path": "/data/media",
"event": "add",
"options": {
"usePolling": true,
"pollTimes": {
"item": [
{
"mode": "everyMinute",
"minute": 5
}
]
}
}
},
"id": "ms100001-0001-4000-8000-000000000001",
"name": "Watch Folder \u2014 /data/media",
"type": "n8n-nodes-base.localFileTrigger",
"typeVersion": 1,
"position": [
0,
300
]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "cfg-drive-folder",
"name": "google_drive_folder_id",
"value": "YOUR_GOOGLE_DRIVE_SHARED_FOLDER_ID",
"type": "string"
},
{
"id": "cfg-bot-token",
"name": "telegram_bot_token",
"value": "YOUR_TELEGRAM_BOT_TOKEN",
"type": "string"
},
{
"id": "cfg-admin-chat",
"name": "telegram_admin_chat_id",
"value": "YOUR_ADMIN_TELEGRAM_CHAT_ID",
"type": "string"
},
{
"id": "cfg-max-size-mb",
"name": "max_file_size_mb",
"value": "500",
"type": "string"
}
]
},
"options": {}
},
"id": "ms100001-0001-4000-8000-000000000002",
"name": "Config",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
220,
300
]
},
{
"parameters": {
"jsCode": "const event = $('Watch Folder \u2014 /data/media').item.json;\nconst config = $('Config').item.json;\n\nconst filePath = event.path || event.filePath || '';\nconst fileName = filePath.split('/').pop() || filePath.split('\\\\').pop() || 'unknown';\nconst fileExt = fileName.split('.').pop()?.toLowerCase() || '';\n\n// Valid media extensions\nconst validExts = ['mp4', 'mov', 'avi', 'mkv', 'webm', 'jpg', 'jpeg', 'png', 'gif', 'pdf'];\n\nif (!validExts.includes(fileExt)) {\n return { json: { skip: true, reason: `Unsupported file type: .${fileExt}` } };\n}\n\n// Check file size if available\nconst fileSizeBytes = event.size || event.stats?.size || 0;\nconst fileSizeMB = fileSizeBytes / (1024 * 1024);\nconst maxSizeMB = Number(config.max_file_size_mb) || 500;\n\nif (fileSizeMB > maxSizeMB) {\n return { json: { skip: true, reason: `File too large: ${fileSizeMB.toFixed(1)}MB (max ${maxSizeMB}MB)` } };\n}\n\n// Determine subfolder based on file extension\nlet mediaType = 'other';\nif (['mp4', 'mov', 'avi', 'mkv', 'webm'].includes(fileExt)) mediaType = 'video';\nelse if (['jpg', 'jpeg', 'png', 'gif'].includes(fileExt)) mediaType = 'photo';\nelse if (fileExt === 'pdf') mediaType = 'document';\n\nreturn {\n json: {\n skip: false,\n filePath,\n fileName,\n fileExt,\n fileSizeMB: fileSizeMB.toFixed(1),\n mediaType,\n uploadDate: new Date().toISOString().split('T')[0]\n }\n};"
},
"id": "ms100001-0001-4000-8000-000000000003",
"name": "Validate File",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
440,
300
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true
},
"conditions": [
{
"id": "check-skip",
"leftValue": "={{ $json.skip }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "notEquals"
}
}
]
},
"options": {}
},
"id": "ms100001-0001-4000-8000-000000000004",
"name": "Valid File?",
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
660,
300
]
},
{
"parameters": {
"filePath": "={{ $('Validate File').item.json.filePath }}",
"options": {}
},
"id": "ms100001-0001-4000-8000-000000000005",
"name": "Read Binary File",
"type": "n8n-nodes-base.readWriteFile",
"typeVersion": 1,
"position": [
880,
180
]
},
{
"parameters": {
"operation": "upload",
"name": "={{ $('Validate File').item.json.fileName }}",
"folderId": "={{ $('Config').item.json.google_drive_folder_id }}",
"options": {}
},
"id": "ms100001-0001-4000-8000-000000000006",
"name": "Upload to Google Drive",
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
1100,
180
],
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"continueOnFail": true
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "check-upload",
"leftValue": "={{ $json.id }}",
"rightValue": "",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "ms100001-0001-4000-8000-000000000007",
"name": "Upload OK?",
"type": "n8n-nodes-base.if",
"typeVersion": 2.3,
"position": [
1320,
180
]
},
{
"parameters": {
"method": "POST",
"url": "=https://api.telegram.org/bot{{ $('Config').item.json.telegram_bot_token }}/sendMessage",
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={{ JSON.stringify({ chat_id: $('Config').item.json.telegram_admin_chat_id, text: '\ud83d\udcc1 <b>Media uploaded to Drive</b>\\n\\nFile: ' + $('Validate File').item.json.fileName + '\\nSize: ' + $('Validate File').item.json.fileSizeMB + ' MB\\nType: ' + $('Validate File').item.json.mediaType + '\\nDrive ID: ' + $json.id, parse_mode: 'HTML' }) }}",
"options": {}
},
"id": "ms100001-0001-4000-8000-000000000008",
"name": "Notify Admin \u2014 Success",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1540,
60
],
"continueOnFail": true
},
{
"parameters": {
"method": "POST",
"url": "=https://api.telegram.org/bot{{ $('Config').item.json.telegram_bot_token }}/sendMessage",
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={{ JSON.stringify({ chat_id: $('Config').item.json.telegram_admin_chat_id, text: '\u26a0\ufe0f <b>Media upload FAILED</b>\\n\\nFile: ' + $('Validate File').item.json.fileName + '\\nError: Upload to Google Drive failed. Check n8n logs.', parse_mode: 'HTML' }) }}",
"options": {}
},
"id": "ms100001-0001-4000-8000-000000000009",
"name": "Notify Admin \u2014 Failed",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1540,
300
],
"continueOnFail": true
}
],
"connections": {
"Watch Folder \u2014 /data/media": {
"main": [
[
{
"node": "Config",
"type": "main",
"index": 0
}
]
]
},
"Config": {
"main": [
[
{
"node": "Validate File",
"type": "main",
"index": 0
}
]
]
},
"Validate File": {
"main": [
[
{
"node": "Valid File?",
"type": "main",
"index": 0
}
]
]
},
"Valid File?": {
"main": [
[
{
"node": "Read Binary File",
"type": "main",
"index": 0
}
],
[]
]
},
"Read Binary File": {
"main": [
[
{
"node": "Upload to Google Drive",
"type": "main",
"index": 0
}
]
]
},
"Upload to Google Drive": {
"main": [
[
{
"node": "Upload OK?",
"type": "main",
"index": 0
}
]
]
},
"Upload OK?": {
"main": [
[
{
"node": "Notify Admin \u2014 Success",
"type": "main",
"index": 0
}
],
[
{
"node": "Notify Admin \u2014 Failed",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"tags": [
{
"name": "Media"
},
{
"name": "Google Drive"
},
{
"name": "Automation"
}
]
}
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.
googleDriveOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Media Sync (Local HDD → Google Drive). Uses localFileTrigger, readWriteFile, googleDrive, httpRequest. Event-driven trigger; 9 nodes.
Source: https://github.com/hasancoded/n8n-workflow-templates/blob/main/media-sync-drive.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.
Product - Google Search Console API Examples. Uses httpRequest. Event-driven trigger; 36 nodes.
AutoQoutesV2_template. Uses manualTrigger, httpRequest, stickyNote, googleSheets. Event-driven trigger; 28 nodes.
Remove Video Background & Compose on Custom Image Background with Google Drive. Uses httpRequest, googleDrive. Webhook trigger; 25 nodes.
AutoClip – Automatically Generate Video Clips and Upload to YouTube. Uses manualTrigger, googleSheets, googleDrive, stickyNote. Event-driven trigger; 23 nodes.
backup. Uses googleDrive, httpRequest. Scheduled trigger; 15 nodes.