AutomationFlowsSlack & Telegram › Daily Google Drive Backup at 22:00

Daily Google Drive Backup at 22:00

Original n8n title: Daily Backup (22:00)

20 - Daily Backup (22:00). Uses googleDrive, googleCalendar, telegram. Scheduled trigger; 13 nodes.

Cron / scheduled trigger★★★★☆ complexity13 nodesGoogle DriveGoogle CalendarTelegram
Slack & Telegram Trigger: Cron / scheduled Nodes: 13 Complexity: ★★★★☆ Added:

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 →

Download .json
{
  "name": "20 - Daily Backup (22:00)",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 22,
              "triggerAtMinute": 0
            }
          ]
        }
      },
      "id": "schedule-trigger",
      "name": "Every Day 22:00",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        220,
        300
      ]
    },
    {
      "parameters": {
        "operation": "search",
        "queryString": "=name contains 'Rodopi-Dent-Backup-' or name contains 'calendar-backup-'",
        "returnAll": true,
        "options": {}
      },
      "id": "list-old-backups",
      "name": "List Old Backups",
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        440,
        300
      ],
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "continueOnFail": true
    },
    {
      "parameters": {
        "jsCode": "// Filter backups older than 30 days\nconst items = $input.all();\nconst cutoffDate = new Date();\ncutoffDate.setDate(cutoffDate.getDate() - 30);\n\nconst toDelete = [];\nconst toKeep = [];\n\nfor (const item of items) {\n  const file = item.json;\n  // Skip if no valid file id (e.g. error result)\n  if (!file.id) continue;\n  \n  const createdTime = new Date(file.createdTime || file.createdDate || file.modifiedTime || 0);\n  \n  if (createdTime < cutoffDate) {\n    toDelete.push({\n      json: {\n        id: file.id,\n        name: file.name,\n        createdTime: createdTime.toISOString()\n      }\n    });\n  } else {\n    toKeep.push(file.name);\n  }\n}\n\nconsole.log(`Found ${toDelete.length} old backups to delete, keeping ${toKeep.length}`);\n\n// If nothing to delete, return a marker\nif (toDelete.length === 0) {\n  return [{ json: { noFilesToDelete: true, keptCount: toKeep.length } }];\n}\n\nreturn toDelete;"
      },
      "id": "filter-old-backups",
      "name": "Filter Old (>30 days)",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        660,
        300
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "has-files",
              "leftValue": "={{ $json.noFilesToDelete }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "notTrue"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "check-has-old",
      "name": "Has Old Files?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        880,
        300
      ]
    },
    {
      "parameters": {
        "operation": "delete",
        "fileId": {
          "__rl": true,
          "value": "={{ $json.id }}",
          "mode": "id"
        },
        "options": {}
      },
      "id": "delete-old-backups",
      "name": "Delete Old Backups",
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        1100,
        200
      ],
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "continueOnFail": true
    },
    {
      "parameters": {
        "jsCode": "// Count deleted files\nconst items = $input.all();\nlet deleted = 0;\nfor (const item of items) {\n  if (!item.json.error) deleted++;\n}\nconsole.log(`Deleted ${deleted} old backup files`);\nreturn [{ json: { deletedCount: deleted } }];"
      },
      "id": "log-deleted",
      "name": "Log Deleted",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1320,
        200
      ]
    },
    {
      "parameters": {
        "operation": "copy",
        "fileId": {
          "__rl": true,
          "value": "1hv4XAfHhScA40Bm1kQ3I-Ih4SJuCBpOJxTOYDNb167g",
          "mode": "id"
        },
        "options": {
          "name": "=Rodopi-Dent-Backup-{{ $now.format('yyyy-MM-dd') }}"
        }
      },
      "id": "copy-sheet",
      "name": "Copy Google Sheet",
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        1540,
        300
      ],
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "getAll",
        "calendar": {
          "__rl": true,
          "value": "rodopi.dent@gmail.com",
          "mode": "id"
        },
        "returnAll": true,
        "options": {
          "timeMin": "={{ $now.minus({months: 6}).toISO() }}",
          "timeMax": "={{ $now.plus({months: 6}).toISO() }}",
          "singleEvents": true,
          "orderBy": "startTime"
        }
      },
      "id": "get-calendar-events",
      "name": "Get All Calendar Events",
      "type": "n8n-nodes-base.googleCalendar",
      "typeVersion": 1.2,
      "position": [
        1540,
        500
      ],
      "credentials": {
        "googleCalendarOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Get all calendar events and convert to JSON string\nconst allEvents = $input.all().map(item => item.json);\nconst jsonString = JSON.stringify(allEvents, null, 2);\n\nreturn [{\n  json: {\n    calendarJson: jsonString,\n    eventCount: allEvents.length\n  }\n}];"
      },
      "id": "format-json",
      "name": "Format as JSON",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1760,
        500
      ]
    },
    {
      "parameters": {
        "operation": "text",
        "sourceProperty": "calendarJson",
        "fileName": "=calendar-backup-{{ $now.format('yyyy-MM-dd') }}.json",
        "mimeType": "application/json"
      },
      "id": "create-file",
      "name": "Create JSON File",
      "type": "n8n-nodes-base.convertToFile",
      "typeVersion": 1.1,
      "position": [
        1980,
        500
      ]
    },
    {
      "parameters": {
        "operation": "upload",
        "folderId": {
          "__rl": true,
          "value": "root",
          "mode": "list"
        },
        "options": {
          "name": "=calendar-backup-{{ $now.format('yyyy-MM-dd') }}.json"
        }
      },
      "id": "upload-to-drive",
      "name": "Upload to Google Drive",
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        2200,
        500
      ],
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {},
      "id": "merge-results",
      "name": "Merge Results",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3,
      "position": [
        2200,
        300
      ]
    },
    {
      "parameters": {
        "chatId": "2146283697",
        "text": "=\u2705 **\u0415\u0436\u0435\u0434\u043d\u0435\u0432\u0435\u043d backup \u0437\u0430\u0432\u044a\u0440\u0448\u0435\u043d**\n\n\ud83d\udcca Google Sheet \u043a\u043e\u043f\u0438\u0440\u0430\u043d\n\ud83d\udcc5 \u041a\u0430\u043b\u0435\u043d\u0434\u0430\u0440: {{ $('Get All Calendar Events').all().length }} \u0441\u044a\u0431\u0438\u0442\u0438\u044f\n\ud83d\uddd1\ufe0f \u0418\u0437\u0442\u0440\u0438\u0442\u0438 \u0441\u0442\u0430\u0440\u0438 backup-\u0438: {{ $('Log Deleted').first()?.json?.deletedCount || 0 }}\n\ud83d\udd50 \u0427\u0430\u0441: {{ $now.format('HH:mm') }}",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "id": "notify-telegram",
      "name": "Notify via Telegram",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        2420,
        300
      ],
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Every Day 22:00": {
      "main": [
        [
          {
            "node": "List Old Backups",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "List Old Backups": {
      "main": [
        [
          {
            "node": "Filter Old (>30 days)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Old (>30 days)": {
      "main": [
        [
          {
            "node": "Has Old Files?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has Old Files?": {
      "main": [
        [
          {
            "node": "Delete Old Backups",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Copy Google Sheet",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get All Calendar Events",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Delete Old Backups": {
      "main": [
        [
          {
            "node": "Log Deleted",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Deleted": {
      "main": [
        [
          {
            "node": "Copy Google Sheet",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get All Calendar Events",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Copy Google Sheet": {
      "main": [
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get All Calendar Events": {
      "main": [
        [
          {
            "node": "Format as JSON",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format as JSON": {
      "main": [
        [
          {
            "node": "Create JSON File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create JSON File": {
      "main": [
        [
          {
            "node": "Upload to Google Drive",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload to Google Drive": {
      "main": [
        [
          {
            "node": "Merge Results",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge Results": {
      "main": [
        [
          {
            "node": "Notify via Telegram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "timezone": "Europe/Sofia"
  },
  "staticData": null,
  "tags": [
    {
      "name": "backup"
    },
    {
      "name": "scheduled"
    }
  ]
}

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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

How this works

Secure your essential files and events effortlessly with this workflow, which automatically backs up Google Sheets and Google Calendar data to Google Drive each evening at 22:00, while sending a confirmation via Telegram. It's ideal for individuals or small teams who rely on these tools for productivity and want to avoid data loss without manual effort. The key step involves filtering and deleting backups older than 30 days to keep storage tidy, ensuring you always have the latest copies ready for recovery.

Use this workflow when you need a reliable nightly routine for safeguarding work documents and schedules, particularly if your data changes daily and you value automated notifications. Avoid it for high-volume data sets that might exceed Drive limits or if you prefer real-time backups over scheduled ones. Common variations include adjusting the cron timing for different frequencies or adding email alerts instead of Telegram messages.

About this workflow

20 - Daily Backup (22:00). Uses googleDrive, googleCalendar, telegram. Scheduled trigger; 13 nodes.

Source: https://github.com/Georgi-Piskov/RODOPI-DENT/blob/f071a84326ea5adf54e4eb20a2ba3e34aac5b728/n8n-workflows/20-daily-backup.json — original creator credit. Request a take-down →

More Slack & Telegram workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Slack & Telegram

MindFrame Psychology - FREE Complete Workflow. Uses httpRequest, googleDrive, telegram. Scheduled trigger; 25 nodes.

HTTP Request, Google Drive, Telegram
Slack & Telegram

This n8n template demonstrates how to automatically fetch upcoming movie releases from TMDB and let users add selected movies to their Google Calendar directly from Telegram. On a daily schedule, the

HTTP Request, Data Table, Telegram +2
Slack & Telegram

This workflow automatically sends you a daily message on Telegram summarizing all your meetings and events for the day, straight from your Google Calendar.

Telegram, Google Calendar
Slack & Telegram

Renta Vehículos Workflow. Uses telegram, telegramTrigger, googleDrive, httpRequest. Scheduled trigger; 10 nodes.

Telegram, Telegram Trigger, Google Drive +2
Slack & Telegram

Automatically Send Daily Meeting List to Telegram. Uses googleCalendar, scheduleTrigger, telegram, stickyNote. Scheduled trigger; 8 nodes.

Google Calendar, Telegram