This workflow corresponds to n8n.io template #10235 — we link there as the canonical source.
This workflow follows the Google Drive → Telegram 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 →
{
"id": "j3J585fxGRgcKKEG",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Notion Backup into Google Drive",
"tags": [],
"nodes": [
{
"id": "8d1050f1-d77f-4074-8592-e338511c0465",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
208,
-400
],
"parameters": {
"width": 463,
"height": 955,
"content": "## Notion Backup to Google Drive\n\n**Automatically backup all your Notion databases to Google Drive with version control and automatic cleanup.**\n\n### How it works\n\n1. **Trigger**: Runs manually or on schedule\n2. **Configuration**: Sets backup format, retention policy, and notification settings\n3. **Backup**: Creates timestamped folder in Google Drive\n4. **Export**: Loops through each Notion database and exports pages as JSON\n5. **Metadata**: Generates summary file with backup statistics\n6. **Cleanup**: Automatically deletes backups older than retention period\n7. **Notification**: Sends Telegram message with backup status and link\n\n### Setup steps\n\n1. Connect your **Notion** account (requires workspace integration)\n2. Connect **Google Drive** with folder creation permissions\n3. Create a **Telegram bot** and get your chat ID\n4. Update **Configuration Settings** node:\n - Set `parent_folder_id` (your Google Drive folder)\n - Set `telegram_chat_id` (your Telegram chat ID)\n - Configure `retention_days` (0 = keep all backups)\n5. Test with \"Execute workflow\" button\n6. (Optional) Replace Manual Trigger with Schedule Trigger for automation\n\n### Customization\n\n- **Backup format**: Currently JSON, can be extended to markdown or HTML\n- **Retention policy**: Set `retention_days` to auto-delete old backups\n- **Notification**: Disable Telegram and use email instead\n- **Filters**: Modify to backup only specific databases"
},
"typeVersion": 1
},
{
"id": "eb45df90-2c6d-4863-8b31-0af3bec64117",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
736,
288
],
"parameters": {
"color": 7,
"width": 440,
"height": 256,
"content": "## 1. Initialize\n\nTriggers the backup process and loads configuration settings"
},
"typeVersion": 1
},
{
"id": "66c6c6ea-7fe8-49d4-a40b-0f855bf6668d",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1248,
288
],
"parameters": {
"color": 6,
"width": 496,
"height": 256,
"content": "## 2. Prepare Backup\n\nCreates timestamped folder and retrieves all Notion databases"
},
"typeVersion": 1
},
{
"id": "e0ec8ea0-8130-40dd-ac86-36c2c77a1d94",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1792,
256
],
"parameters": {
"color": 7,
"width": 1120,
"height": 448,
"content": "## 3. Process Databases\n\nLoops through each database, exports all pages, and uploads to Google Drive"
},
"typeVersion": 1
},
{
"id": "5843c38d-eaf3-410d-87f2-7a671a97ce99",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
2960,
272
],
"parameters": {
"color": 6,
"width": 528,
"height": 256,
"content": "## 4. Finalize & Metadata\n\nGenerates backup summary with statistics and success/failure details"
},
"typeVersion": 1
},
{
"id": "10c67ac0-47bc-49c6-9a2f-b3cf58a0dec9",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
3536,
112
],
"parameters": {
"color": 7,
"width": 1136,
"height": 416,
"content": "## 5. Cleanup Old Backups\n\nAutomatically deletes backups older than retention period (if enabled)"
},
"typeVersion": 1
},
{
"id": "d95e0e72-8fac-4703-928a-f4c61c962ff3",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
4816,
288
],
"parameters": {
"color": 6,
"width": 576,
"height": 288,
"content": "## 6. Send Notification\n\nFormats and sends Telegram notification with backup results"
},
"typeVersion": 1
},
{
"id": "e105d43a-8c22-4aee-9022-d0bff1cfb8dd",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
736,
16
],
"parameters": {
"color": 3,
"width": 256,
"height": 240,
"content": "\u26a0\ufe0f **CRITICAL SETUP**\n\nBefore first run, update the **Configuration Settings** node with:\n- Your Google Drive parent folder ID\n- Your Telegram bot chat ID\n\nWithout these, the workflow will fail!"
},
"typeVersion": 1
},
{
"id": "df9f37f5-d06d-44d5-8574-2ce1822791af",
"name": "Manual Trigger",
"type": "n8n-nodes-base.manualTrigger",
"position": [
800,
384
],
"parameters": {},
"typeVersion": 1
},
{
"id": "6bd07d17-fa58-44ee-ac35-b4c733686434",
"name": "Configuration Settings",
"type": "n8n-nodes-base.set",
"position": [
1024,
384
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "backup-format",
"name": "backup_format",
"type": "string",
"value": "json"
},
{
"id": "retention-days",
"name": "retention_days",
"type": "number",
"value": 5
},
{
"id": "enable-cleanup",
"name": "enable_cleanup",
"type": "boolean",
"value": true
},
{
"id": "parent-folder-id",
"name": "parent_folder_id",
"type": "string",
"value": "YOUR_GOOGLE_DRIVE_PARENT_FOLDER_ID"
},
{
"id": "telegram-chat-id",
"name": "telegram_chat_id",
"type": "string",
"value": "YOUR_TELEGRAM_CHAT_ID"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "fd6bafaa-3a25-4b54-8bff-c088f2e5aa8b",
"name": "Create Backup Folder",
"type": "n8n-nodes-base.googleDrive",
"position": [
1328,
384
],
"parameters": {
"name": "=Notion_Backup_V2_{{ $now.format('yyyy-MM-dd_HHmmss') }}",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive",
"cachedResultUrl": "https://drive.google.com/drive/my-drive",
"cachedResultName": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.parent_folder_id }}"
},
"resource": "folder"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"executeOnce": true,
"typeVersion": 3
},
{
"id": "81915f5d-ba74-484f-b15e-dea36385e349",
"name": "Get All Databases",
"type": "n8n-nodes-base.notion",
"position": [
1584,
384
],
"parameters": {
"resource": "database",
"operation": "getAll",
"returnAll": true
},
"credentials": {
"notionApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "1c114eb9-55e2-49cd-9266-993e7eb79f2d",
"name": "Initialize Tracking",
"type": "n8n-nodes-base.code",
"position": [
1840,
384
],
"parameters": {
"jsCode": "// Initialize backup tracking\nconst databases = $input.all();\nconst backupStartTime = new Date().toISOString();\nconst folderId = $('Create Backup Folder').first().json.id;\nconst folderName = $('Create Backup Folder').first().json.name;\n\n// Prepare databases with tracking info\nconst processedDatabases = databases.map((item, index) => {\n const db = item.json;\n const dbName = db.title?.[0]?.plain_text || `Database_${index + 1}`;\n \n return {\n json: {\n database_id: db.id,\n database_name: dbName,\n database_title: db.title,\n created_time: db.created_time,\n last_edited_time: db.last_edited_time,\n backup_folder_id: folderId,\n backup_folder_name: folderName,\n backup_start_time: backupStartTime,\n index: index + 1,\n total_databases: databases.length,\n status: 'pending'\n }\n };\n});\n\nreturn processedDatabases;"
},
"typeVersion": 2
},
{
"id": "e92528b1-5f8d-4f4c-a796-823a22c4d32d",
"name": "Loop Databases",
"type": "n8n-nodes-base.splitInBatches",
"position": [
2048,
384
],
"parameters": {
"options": {
"reset": false
}
},
"typeVersion": 3
},
{
"id": "f41e87bd-aecd-41dd-a015-162e0ba6a0c0",
"name": "Get Database Pages",
"type": "n8n-nodes-base.notion",
"position": [
2272,
480
],
"parameters": {
"simple": false,
"options": {},
"resource": "databasePage",
"operation": "getAll",
"returnAll": true,
"databaseId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.database_id }}"
}
},
"credentials": {
"notionApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.2,
"continueOnFail": true
},
{
"id": "fd168167-7255-4d14-8903-432f6e16219b",
"name": "Create Backup File",
"type": "n8n-nodes-base.code",
"position": [
2496,
480
],
"parameters": {
"jsCode": "// Get database info from loop\nconst dbInfo = $('Loop Databases').first().json;\nconst dbName = dbInfo.database_name;\nconst dbId = dbInfo.database_id;\nconst backupTime = new Date().toISOString();\n\n// Check if pages were retrieved successfully\nconst pagesNode = $input.first();\nlet pages = [];\nlet status = 'success';\nlet errorMessage = null;\n\ntry {\n if (pagesNode.error) {\n status = 'error';\n errorMessage = pagesNode.error.message || 'Unknown error';\n } else {\n pages = $input.all().map(item => item.json);\n }\n} catch (error) {\n status = 'error';\n errorMessage = error.message;\n}\n\n// Create backup structure\nconst backup = {\n metadata: {\n database_id: dbId,\n database_name: dbName,\n database_title: dbInfo.database_title,\n backup_timestamp: backupTime,\n backup_date: new Date().toISOString().split('T')[0],\n total_pages: pages.length,\n created_time: dbInfo.created_time,\n last_edited_time: dbInfo.last_edited_time,\n backup_status: status,\n error_message: errorMessage\n },\n pages: pages\n};\n\n// Create safe filename\nconst safeFileName = dbName.replace(/[^a-z0-9]/gi, '_').toLowerCase();\nconst timestamp = new Date().toISOString().replace(/[:.]/g, '-').split('T')[0];\nconst fileName = `${safeFileName}_${timestamp}.json`;\n\n// Convert to JSON and then to binary\nconst jsonContent = JSON.stringify(backup, null, 2);\nconst base64Content = Buffer.from(jsonContent, 'utf8').toString('base64');\n\nreturn {\n json: {\n database_name: dbName,\n database_id: dbId,\n file_name: fileName,\n pages_count: pages.length,\n backup_size_bytes: Buffer.byteLength(jsonContent, 'utf8'),\n status: status,\n error_message: errorMessage,\n backup_timestamp: backupTime\n },\n binary: {\n data: {\n data: base64Content,\n mimeType: 'application/json',\n fileName: fileName\n }\n }\n};"
},
"typeVersion": 2,
"alwaysOutputData": true
},
{
"id": "c33cb193-4439-48d7-90cf-c894db4c4e95",
"name": "Upload Backup File",
"type": "n8n-nodes-base.googleDrive",
"position": [
2704,
480
],
"parameters": {
"name": "={{ $json.file_name }}",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Create Backup Folder').first().json.id }}"
}
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "a70580ca-1883-4c3c-9276-8ca581754457",
"name": "Generate Metadata",
"type": "n8n-nodes-base.code",
"position": [
3072,
368
],
"parameters": {
"jsCode": "// Collect all backup results\nconst allBackups = $input.all();\nconst config = $('Configuration Settings').first().json;\nconst folderInfo = $('Create Backup Folder').first().json;\n\n// Calculate statistics\nconst successfulBackups = allBackups.filter(b => b.json.status === 'success');\nconst failedBackups = allBackups.filter(b => b.json.status === 'error');\nconst totalPages = successfulBackups.reduce((sum, b) => sum + b.json.pages_count, 0);\nconst totalSize = allBackups.reduce((sum, b) => sum + (b.json.backup_size_bytes || 0), 0);\n\n// Format size\nconst formatSize = (bytes) => {\n if (bytes < 1024) return bytes + ' B';\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + ' KB';\n return (bytes / (1024 * 1024)).toFixed(2) + ' MB';\n};\n\n// Create metadata\nconst metadata = {\n backup_info: {\n backup_date: new Date().toISOString().split('T')[0],\n backup_timestamp: new Date().toISOString(),\n folder_name: folderInfo.name,\n folder_id: folderInfo.id,\n folder_url: folderInfo.webViewLink\n },\n summary: {\n total_databases: allBackups.length,\n successful_backups: successfulBackups.length,\n failed_backups: failedBackups.length,\n total_pages_backed_up: totalPages,\n total_size: formatSize(totalSize),\n total_size_bytes: totalSize\n },\n successful_databases: successfulBackups.map(b => ({\n name: b.json.database_name,\n id: b.json.database_id,\n pages_count: b.json.pages_count,\n file_name: b.json.file_name,\n size: formatSize(b.json.backup_size_bytes)\n })),\n failed_databases: failedBackups.map(b => ({\n name: b.json.database_name,\n id: b.json.database_id,\n error: b.json.error_message\n })),\n configuration: {\n retention_days: config.retention_days,\n backup_format: config.backup_format,\n cleanup_enabled: config.enable_cleanup\n }\n};\n\n// Create metadata file\nconst metadataJson = JSON.stringify(metadata, null, 2);\nconst base64Metadata = Buffer.from(metadataJson, 'utf8').toString('base64');\n\nreturn {\n json: {\n ...metadata.summary,\n folder_url: folderInfo.webViewLink,\n successful_databases: successfulBackups.map(b => b.json.database_name),\n failed_databases: failedBackups.map(b => b.json.database_name),\n has_failures: failedBackups.length > 0\n },\n binary: {\n data: {\n data: base64Metadata,\n mimeType: 'application/json',\n fileName: 'backup_metadata.json'\n }\n }\n};"
},
"typeVersion": 2
},
{
"id": "aefb78d9-6495-44c9-af95-56b9cf95a538",
"name": "Upload Metadata",
"type": "n8n-nodes-base.googleDrive",
"position": [
3296,
368
],
"parameters": {
"name": "backup_metadata.json",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Create Backup Folder').first().json.id }}"
}
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "026072e9-0525-4510-8c15-bbd9e2303d0e",
"name": "Should Cleanup?",
"type": "n8n-nodes-base.if",
"position": [
3600,
368
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "cleanup-enabled",
"operator": {
"type": "boolean",
"operation": "true"
},
"leftValue": "={{ $('Configuration Settings').first().json.enable_cleanup }}",
"rightValue": true
}
]
}
},
"typeVersion": 2.2
},
{
"id": "fed62555-581b-4070-ac4a-fb691ee88673",
"name": "List Old Backups",
"type": "n8n-nodes-base.googleDrive",
"position": [
3824,
256
],
"parameters": {
"filter": {
"folderId": {
"mode": "list",
"value": "root",
"cachedResultName": "/ (Root folder)"
}
},
"options": {},
"resource": "fileFolder",
"returnAll": true,
"queryString": "Notion_Backup_"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "814bf4bb-c1cb-4abc-b7f5-80c205836aad",
"name": "Filter Old Backups",
"type": "n8n-nodes-base.code",
"position": [
4032,
256
],
"parameters": {
"jsCode": "// Get retention days from config\nconst retentionDays = $('Configuration Settings').first().json.retention_days;\nconst currentFolderId = $('Create Backup Folder').first().json.id;\n\n// Get all backup folders\nconst allFolders = $input.all();\n\n// Si no hay carpetas, retornar false flag\nif (!allFolders || allFolders.length === 0) {\n console.log('No folders received from previous node');\n return [{\n json: {\n has_folders: false,\n message: 'No backup folders found'\n }\n }];\n}\n\n// Calculate cutoff date\nconst cutoffDate = new Date();\ncutoffDate.setDate(cutoffDate.getDate() - retentionDays);\n\nconsole.log('=== DEBUG FILTER ===');\nconsole.log('Retention days:', retentionDays);\nconsole.log('Cutoff date:', cutoffDate.toISOString());\nconsole.log('Current folder ID:', currentFolderId);\nconsole.log('Total folders found:', allFolders.length);\n\n// Filter folders older than retention period\nconst foldersToDelete = allFolders.filter(item => {\n const folder = item.json;\n \n // Don't delete the current backup\n if (folder.id === currentFolderId) {\n console.log('Skipping current backup:', folder.name);\n return false;\n }\n \n // Parse folder name to get date\n // Match both formats: Notion_Backup_2025-01-15 and Notion_Backup_V2_2025-01-15\n const match = folder.name.match(/Notion_Backup(?:_V\\d+)?_(\\d{4}-\\d{2}-\\d{2})/);\n \n if (!match) {\n console.log('No date match for:', folder.name);\n return false;\n }\n \n const folderDate = new Date(match[1]);\n const shouldDelete = folderDate < cutoffDate;\n \n console.log(`Folder: ${folder.name}, Date: ${match[1]}, Should delete: ${shouldDelete}`);\n \n return shouldDelete;\n});\n\nconsole.log('Folders to delete:', foldersToDelete.length);\n\n// Si no hay carpetas para eliminar, retornar false flag\nif (foldersToDelete.length === 0) {\n console.log('No folders to delete');\n return [{\n json: {\n has_folders: false,\n message: 'No old folders to delete'\n }\n }];\n}\n\n// Si hay carpetas para eliminar, agregarles el flag\nreturn foldersToDelete.map(item => ({\n json: {\n ...item.json,\n has_folders: true\n }\n}));"
},
"typeVersion": 2,
"alwaysOutputData": false
},
{
"id": "208eecf9-6cff-42db-a8b4-d19817ae1bbb",
"name": "Delete Old Backup",
"type": "n8n-nodes-base.googleDrive",
"position": [
4512,
176
],
"parameters": {
"options": {},
"resource": "folder",
"operation": "deleteFolder",
"folderNoRootId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.id }}"
}
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "57526f8a-9ee1-4d12-a9c4-a3b636f18e50",
"name": "Format Notification",
"type": "n8n-nodes-base.code",
"position": [
4944,
384
],
"parameters": {
"jsCode": "// Get summary data\nconst summary = $('Generate Metadata').first().json;\nconst config = $('Configuration Settings').first().json;\n\n// Check if cleanup ran and if there were deletions\nlet cleanupInfo = '';\nif (config.enable_cleanup) {\n try {\n // Try to access Delete Old Backup node\n const deletedFolders = $('Delete Old Backup').all();\n \n if (deletedFolders && deletedFolders.length > 0) {\n // Check if it actually deleted folders (not just the false flag)\n const actualDeletions = deletedFolders.filter(item => item.json.has_folders !== false);\n if (actualDeletions.length > 0) {\n cleanupInfo = `\\n\ud83d\uddd1\ufe0f *Cleanup:* ${actualDeletions.length} old backup(s) deleted (>${config.retention_days} days)`;\n } else {\n cleanupInfo = `\\n\u2705 *Cleanup:* No old backups to delete`;\n }\n } else {\n cleanupInfo = `\\n\u2705 *Cleanup:* No old backups to delete`;\n }\n } catch (error) {\n // Node wasn't executed (no old folders to delete)\n cleanupInfo = `\\n\u2705 *Cleanup:* No old backups to delete`;\n }\n} else {\n cleanupInfo = '';\n}\n\n// Build status emoji\nconst statusEmoji = summary.has_failures ? '\u26a0\ufe0f' : '\u2705';\n\n// Build message\nlet message = `${statusEmoji} *Notion Backup Complete*\\n\\n`;\nmessage += `\ud83d\udcca *Summary:*\\n`;\nmessage += `\u2022 Total Databases: ${summary.total_databases}\\n`;\nmessage += `\u2022 Successful: ${summary.successful_backups} \u2705\\n`;\n\nif (summary.failed_backups > 0) {\n message += `\u2022 Failed: ${summary.failed_backups} \u274c\\n`;\n}\n\nmessage += `\u2022 Total Pages: ${summary.total_pages_backed_up}\\n`;\nmessage += `\u2022 Total Size: ${summary.total_size}\\n`;\nmessage += cleanupInfo;\nmessage += `\\n\ud83d\udcc1 [Open Backup Folder](${summary.folder_url})`;\n\nif (summary.has_failures) {\n message += `\\n\\n\u274c *Failed Databases:*\\n`;\n summary.failed_databases.forEach(db => {\n message += `\u2022 ${db}\\n`;\n });\n}\n\nreturn {\n message: message,\n chat_id: config.telegram_chat_id,\n parse_mode: 'Markdown'\n};"
},
"typeVersion": 2
},
{
"id": "78461e9b-f611-4aa2-ae2c-300055b28d6f",
"name": "Send Telegram Notification",
"type": "n8n-nodes-base.telegram",
"position": [
5168,
384
],
"parameters": {
"text": "={{ $json.message }}",
"chatId": "={{ $json.chat_id }}",
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "636274ad-9ffb-4113-a13d-a62a5be7c6d9",
"name": "If",
"type": "n8n-nodes-base.if",
"position": [
4224,
256
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "d7bbc942-9e79-4e2c-968d-ac83d2cc6e64",
"operator": {
"type": "boolean",
"operation": "equals"
},
"leftValue": "={{ $json.has_folders }}",
"rightValue": true
}
]
}
},
"typeVersion": 2.3
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "2fc1e480-5ac9-4a21-baf3-08f8defe252a",
"connections": {
"If": {
"main": [
[
{
"node": "Delete Old Backup",
"type": "main",
"index": 0
}
],
[
{
"node": "Format Notification",
"type": "main",
"index": 0
}
]
]
},
"Loop Databases": {
"main": [
[
{
"node": "Generate Metadata",
"type": "main",
"index": 0
}
],
[
{
"node": "Get Database Pages",
"type": "main",
"index": 0
}
]
]
},
"Manual Trigger": {
"main": [
[
{
"node": "Configuration Settings",
"type": "main",
"index": 0
}
]
]
},
"Should Cleanup?": {
"main": [
[
{
"node": "List Old Backups",
"type": "main",
"index": 0
}
],
[
{
"node": "Format Notification",
"type": "main",
"index": 0
}
]
]
},
"Upload Metadata": {
"main": [
[
{
"node": "Should Cleanup?",
"type": "main",
"index": 0
}
]
]
},
"List Old Backups": {
"main": [
[
{
"node": "Filter Old Backups",
"type": "main",
"index": 0
}
]
]
},
"Delete Old Backup": {
"main": [
[
{
"node": "Format Notification",
"type": "main",
"index": 0
}
]
]
},
"Generate Metadata": {
"main": [
[
{
"node": "Upload Metadata",
"type": "main",
"index": 0
}
]
]
},
"Get All Databases": {
"main": [
[
{
"node": "Initialize Tracking",
"type": "main",
"index": 0
}
]
]
},
"Create Backup File": {
"main": [
[
{
"node": "Upload Backup File",
"type": "main",
"index": 0
}
]
]
},
"Filter Old Backups": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"Get Database Pages": {
"main": [
[
{
"node": "Create Backup File",
"type": "main",
"index": 0
}
]
]
},
"Upload Backup File": {
"main": [
[
{
"node": "Loop Databases",
"type": "main",
"index": 0
}
]
]
},
"Format Notification": {
"main": [
[
{
"node": "Send Telegram Notification",
"type": "main",
"index": 0
}
]
]
},
"Initialize Tracking": {
"main": [
[
{
"node": "Loop Databases",
"type": "main",
"index": 0
}
]
]
},
"Create Backup Folder": {
"main": [
[
{
"node": "Get All Databases",
"type": "main",
"index": 0
}
]
]
},
"Configuration Settings": {
"main": [
[
{
"node": "Create Backup Folder",
"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.
googleDriveOAuth2ApinotionApitelegramApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow automatically saves copies of all your Notion databases to Google Drive. It's like creating a safety backup of your important Notion information, similar to saving important documents in a filing cabinet.
Source: https://n8n.io/workflows/10235/ — 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 template monitors Google Drive folder for new files, extracts text from PDFs, images, text files, CSVs, and Google Docs., reads images with meta/llama-3.2-11b-vision-instruct, structures the resu
This n8n workflow receives files sent in a Telegram chat, uploads them to Google Drive, extracts text using OCR (for images and PDFs), and stores the extracted content in Airtable for quick search and
This workflow is an AI-assisted clean plate and object removal pipeline built for modern VFX production environments. It transforms a single plate image and removal brief into multiple high-quality cl
Secure your n8n automations with this comprehensive template that automates periodic backups to Telegram for instant access while enabling flexible restores from Google Drive links or direct file uplo
Automatically transform any website URL into a complete portfolio entry with professional screenshots and AI-generated Upwork project descriptions. Freelancers building their Upwork/portfolio from pas