{
  "id": "NUv3LSEJTx53Gsm6",
  "name": "\ud83d\udd04 Auto Backup \u2192 GitHub (daily + /backup)",
  "tags": [],
  "nodes": [
    {
      "id": "8aa6b20c-9590-488a-a0b1-61cc57b6f501",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        0
      ],
      "parameters": {
        "width": 480,
        "height": 864,
        "content": "## \ud83d\udd04 Auto Backup \u2192 GitHub (daily + /backup)\n\n### How it works\n\nThis workflow automatically backs up all n8n workflows to GitHub once per day and can also be triggered manually with a Telegram /backup command. It gathers the workflow definitions, builds a backup file, then checks GitHub to decide whether to update an existing file or create a new one. After the GitHub write finishes, it sends a Telegram confirmation message.\n\n### Setup steps\n\n- Configure the Schedule Trigger timezone so the daily 03:00 run happens at the intended local time.\n- Set up Telegram credentials for both the trigger and notification node, including the bot token and target chat details.\n- Configure the n8n credential or API access used by the Get All Workflows node so it can read all workflows.\n- Configure GitHub credentials and set the repository, branch, file path, and commit details for the check, update, and create file nodes.\n- Verify the Telegram filter matches the exact manual command you want to use, such as /backup.\n\n### Customization\n\nYou can change the backup frequency, Telegram command, GitHub repository or file path, backup filename format, and notification message to match your operational needs."
      },
      "typeVersion": 1
    },
    {
      "id": "1d33c7bc-81b4-403d-a5ea-a54e39257c2c",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        560,
        16
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 528,
        "content": "## Backup entry points\n\nStarts the backup either on the daily 03:00 schedule or from a Telegram command, then filters Telegram messages so only /backup continues."
      },
      "typeVersion": 1
    },
    {
      "id": "23303610-2513-49ea-8d97-366e97f84b72",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1024,
        112
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 320,
        "content": "## Build backup payload\n\nFetches all n8n workflows and uses code to package them into the backup file content that will be stored in GitHub."
      },
      "typeVersion": 1
    },
    {
      "id": "2d6808d4-b2b2-4af8-bdf2-31ab89f120e9",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1472,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 656,
        "height": 528,
        "content": "## Save and notify\n\nChecks whether the backup file already exists in GitHub, updates or creates it accordingly, and sends a Telegram notification after the save completes."
      },
      "typeVersion": 1
    },
    {
      "id": "e3ac6ca5-adea-48bf-a3ba-66fb1598c1fe",
      "name": "When Daily at 3 AM",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        608,
        176
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 3 * * *"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "ea36083d-dd3c-4655-b007-24d4f0274970",
      "name": "Telegram /backup Command Trigger",
      "type": "n8n-nodes-base.telegramTrigger",
      "position": [
        608,
        384
      ],
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "db28c8bc-b5c2-42bc-8011-9bfdad89ec7f",
      "name": "Filter for Backup Command",
      "type": "n8n-nodes-base.filter",
      "position": [
        832,
        384
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "c1",
              "operator": {
                "type": "string",
                "operation": "startsWith"
              },
              "leftValue": "={{ $json.message.text }}",
              "rightValue": "/backup"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "b09fbeea-1c43-4c57-8d6a-8ed9d5346780",
      "name": "Fetch All Workflows",
      "type": "n8n-nodes-base.n8n",
      "position": [
        1072,
        272
      ],
      "parameters": {
        "filters": {},
        "requestOptions": {}
      },
      "credentials": {
        "n8nApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "237887b6-2416-4701-b92a-c087cd0039e9",
      "name": "Build Backup File",
      "type": "n8n-nodes-base.code",
      "position": [
        1296,
        272
      ],
      "parameters": {
        "jsCode": "const date = new Date().toISOString().slice(0,10);\nconst all = $input.all().map(i => i.json);\n\n// chat \u0434\u043b\u044f \u0430\u0432\u0442\u043e-\u0431\u0435\u043a\u0430\u043f\u0443 \u043e 03:00 (\u0433\u0440\u0443\u043f\u0430 Business Atlas)\nconst ADMIN_CHAT_ID = '-1+1234567890';\n\nlet chatId = ADMIN_CHAT_ID;\nlet source = 'scheduled';\ntry {\n  const tg = $('Telegram /backup Command Trigger').first();\n  const cid = tg && tg.json && tg.json.message && tg.json.message.chat && tg.json.message.chat.id;\n  if (cid) { chatId = cid; source = 'manual'; }\n} catch (e) {}\n\nreturn [{ json: {\n  filePath: `backups/${date}/workflows.json`,\n  fileContent: JSON.stringify(all, null, 2),\n  count: all.length,\n  date,\n  chatId,\n  source\n} }];"
      },
      "typeVersion": 2
    },
    {
      "id": "cf09c835-88b4-4900-ab8d-1154a77b2ead",
      "name": "Check File Existence in GitHub",
      "type": "n8n-nodes-base.github",
      "onError": "continueErrorOutput",
      "position": [
        1520,
        272
      ],
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "omarechkoy-ai"
        },
        "filePath": "={{ $('Build Backup File').item.json.filePath }}",
        "resource": "file",
        "operation": "get",
        "repository": {
          "__rl": true,
          "mode": "name",
          "value": "main-n8n-backup"
        },
        "asBinaryProperty": false,
        "additionalParameters": {}
      },
      "credentials": {
        "githubApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "df6fb2b6-f640-41c6-8921-63405dd60217",
      "name": "Update File on GitHub",
      "type": "n8n-nodes-base.github",
      "position": [
        1744,
        160
      ],
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "omarechkoy-ai"
        },
        "filePath": "={{ $('Build Backup File').item.json.filePath }}",
        "resource": "file",
        "operation": "edit",
        "repository": {
          "__rl": true,
          "mode": "name",
          "value": "main-n8n-backup"
        },
        "fileContent": "={{ $('Build Backup File').item.json.fileContent }}",
        "commitMessage": "=n8n backup {{ $('Build Backup File').item.json.date }} ({{ $('Build Backup File').item.json.count }} workflows) [overwrite]"
      },
      "credentials": {
        "githubApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "78e99ed4-a3bb-46f5-b5bf-445e7ded54d2",
      "name": "Create File on GitHub",
      "type": "n8n-nodes-base.github",
      "position": [
        1744,
        368
      ],
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "omarechkoy-ai"
        },
        "filePath": "={{ $('Build Backup File').item.json.filePath }}",
        "resource": "file",
        "repository": {
          "__rl": true,
          "mode": "name",
          "value": "main-n8n-backup"
        },
        "fileContent": "={{ $('Build Backup File').item.json.fileContent }}",
        "commitMessage": "=n8n backup {{ $('Build Backup File').item.json.date }} ({{ $('Build Backup File').item.json.count }} workflows)"
      },
      "credentials": {
        "githubApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "1d17b6f1-0f57-40bd-88e5-d6b613d832af",
      "name": "Notify via Telegram",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1984,
        272
      ],
      "parameters": {
        "text": "=\u2705 n8n backup ({{ $('Build Backup File').item.json.source }})\n{{ $('Build Backup File').item.json.date }} \u2014 {{ $('Build Backup File').item.json.count }} workflows\n{{ $json.commit && $json.commit.html_url ? $json.commit.html_url : ($json.content && $json.content.html_url ? $json.content.html_url : '') }}",
        "chatId": "={{ $('Build Backup File').item.json.chatId }}",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "91c7823e-f7c5-4a3b-a63c-2dbb3076c63f",
  "nodeGroups": [],
  "connections": {
    "Build Backup File": {
      "main": [
        [
          {
            "node": "Check File Existence in GitHub",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When Daily at 3 AM": {
      "main": [
        [
          {
            "node": "Fetch All Workflows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch All Workflows": {
      "main": [
        [
          {
            "node": "Build Backup File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create File on GitHub": {
      "main": [
        [
          {
            "node": "Notify via Telegram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update File on GitHub": {
      "main": [
        [
          {
            "node": "Notify via Telegram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter for Backup Command": {
      "main": [
        [
          {
            "node": "Fetch All Workflows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check File Existence in GitHub": {
      "main": [
        [
          {
            "node": "Update File on GitHub",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Create File on GitHub",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Telegram /backup Command Trigger": {
      "main": [
        [
          {
            "node": "Filter for Backup Command",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}