Skip to content

Automatic Typebot Flows Two-Way Sync with GitHub using Typebot API

Netxsites

Managing chatbot flows across development and production environments can be challenging, especially when multiple team members collaborate.
With automatic two-way synchronization between Typebot and GitHub using the Typebot API, you can ensure your chatbot flows are always up-to-date, versioned, and in sync with your codebase.


✨ What This System Does

  • Syncs Typebot flows automatically with a GitHub repository
  • Supports two-way synchronization: changes in Typebot update GitHub, and vice versa
  • Maintains version control for all chatbot flows
  • Enables collaborative development and workflow management
  • Tracks change history and resolves conflicts automatically
  • Reduces manual updates and potential errors

🧩 Tools & Integrations

  • Typebot API → Access and manage chatbot flows programmatically
  • GitHub → Version control and collaborative repository
  • Automation Platforms → n8n, Zapier, Make.com, or custom scripts
  • Optional Logging → Google Sheets, Airtable, or dashboards to track sync status
  • Notifications → Slack, Teams, or email for sync updates

⚙️ How It Works

1️⃣ Setup GitHub Repository

  • Create a repository to store Typebot flow files
  • Structure repository with folders for different bots or environments

2️⃣ Connect Typebot API

  • Authenticate with Typebot API
  • Access all existing chatbot flows
  • Enable push/pull functionality for GitHub repository

3️⃣ Two-Way Sync Process

  • Typebot → GitHub: New or updated flows in Typebot are committed to the GitHub repository automatically
  • GitHub → Typebot: Changes in GitHub (pull requests, merges, commits) update the corresponding flows in Typebot
  • Handle conflicts with automated merge strategies or alerts

Example Scenario:

  • Developer updates a conversation flow in GitHub
  • Changes are automatically reflected in the Typebot environment
  • Typebot users see the latest version instantly without manual import/export

4️⃣ Logging & Notifications

  • Track all sync activities with timestamps, user info, and flow names
  • Send alerts for failed syncs or conflicts
  • Maintain a clear audit trail for team collaboration

📦 Optional Enhancements

  • Multi-environment support → Sync flows across staging, testing, and production environments
  • Automated testing → Validate flow structure before syncing
  • AI-assisted conflict resolution → Suggest resolutions for merge conflicts
  • Dashboard visualization → Monitor sync status and changes in real time
  • Scheduled sync → Automate periodic updates between Typebot and GitHub

🎯 Benefits

  • Keeps chatbot flows consistent across environments
  • Reduces manual updates and synchronization errors
  • Supports collaborative development and version control
  • Provides clear audit trail and change history
  • Enables fast iteration and deployment of chatbot improvements
  • Ensures your Typebot environment is always aligned with your codebase

There’s nothing you
can’t automate with n8n

Our customer’s words, not ours.
Skeptical? Try it out, and see for yourself.

Use template

{ "meta": { "instanceId": "00e9ec826c332aaa2865e65cdec318b633185c63a1cba1b3a2500858724cc85e", "templateCredsSetupCompleted": true }, "nodes": [ { "id": "e770fbf4-8c4f-4aaa-b722-3140ecec28f2", "name": "On clicking 'execute'", "type": "n8n-nodes-base.manualTrigger", "position": [ 360, 640 ], "parameters": {}, "typeVersion": 1 }, { "id": "49b53bc4-6441-4577-a851-bb7f2c580a39", "name": "Sticky Note1", "type": "n8n-nodes-base.stickyNote", "position": [ -220, 480 ], "parameters": { "color": 4, "width": 371, "height": 601, "content": "## Typebot Backup to GitHub \nThis workflow will backup all instance typebots to GitHub and also deleted it if was deleted in your typebot workspace.\n\nThe files are saved `ID.json` for the filename.\n\n### Setup\nOpen `Globals` node and update the values below 👇\n\n- **repo.owner:** your Github username\n- **repo.name:** the name of your repository\n- **typebot.url:** default url or your self-hosted Typebot url\n- **typebot.workspace.id:** your Typebot workspace id\n\n\nIf your username was `john-doe` and your repository was called `n8n-backups`:\n\n- repo.owner - john-doe\n- repo.name - n8n-backups\n\nFor Typebot see its [documentation](https://docs.typebot.io/api-reference/how-to)\n\nThe workflow calls itself using a subworkflow, to help reduce memory usage." }, "typeVersion": 1 }, { "id": "7dede05f-8c5a-426e-a822-d21b7e50d976", "name": "Execute Workflow Trigger", "type": "n8n-nodes-base.executeWorkflowTrigger", "position": [ -140, 1620 ], "parameters": { "inputSource": "passthrough" }, "typeVersion": 1.1 }, { "id": "7469a576-e3ea-4e55-93f3-7f380f1a57e7", "name": "Sticky Note", "type": "n8n-nodes-base.stickyNote", "position": [ 180, 480 ], "parameters": { "color": 7, "width": 1831, "height": 601, "content": "## Main workflow loop" }, "typeVersion": 1 }, { "id": "acb81c9e-152a-4bf3-ab23-1eb66e8d5510", "name": "Sticky Note2", "type": "n8n-nodes-base.stickyNote", "position": [ -220, 1100 ], "parameters": { "color": 6, "width": 2231, "height": 941, "content": "## Subworkflow" }, "typeVersion": 1 }, { "id": "6df6e830-5721-421f-9b46-f99f9164eb4d", "name": "List Typebots", "type": "n8n-nodes-base.httpRequest", "position": [ 800, 740 ], "parameters": { "url": "={{ $json.typebot.url }}/api/v1/typebots", "options": {}, "sendQuery": true, "authentication": "genericCredentialType", "genericAuthType": "httpBearerAuth", "queryParameters": { "parameters": [ { "name": "workspaceId", "value": "={{ $json.typebot.workspace.id }}" } ] } }, "typeVersion": 4.2 }, { "id": "3d44e0b2-c404-424a-8eba-7ec111738939", "name": "typebot", "type": "n8n-nodes-base.set", "position": [ 1240, 640 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "8fbbf5fa-0455-4066-80e0-1b2885343aea", "name": "typebot.url", "type": "string", "value": "={{ $('Globals').item.json.typebot.url }}" }, { "id": "5e73d2e7-4b1a-4180-8af2-047e52eb8a0a", "name": "repo.owner", "type": "string", "value": "={{ $('Globals').item.json.repo.owner }}" }, { "id": "22445c28-5431-45a5-86ca-0ab2ff26cff5", "name": "repo.name", "type": "string", "value": "={{ $('Globals').item.json.repo.name }}" }, { "id": "232d9947-a43f-48a9-b385-da1aa8f5139e", "name": "origin", "type": "string", "value": "typebot" } ] }, "includeOtherFields": true }, "typeVersion": 3.4 }, { "id": "4be16d80-43fd-4cc1-b79c-11fec3c76829", "name": "Get Typebot", "type": "n8n-nodes-base.httpRequest", "position": [ 300, 1360 ], "parameters": { "url": "={{ $('Switch').item.json.typebot.url }}/api/v1/typebots/{{ $json.id }}", "options": {}, "authentication": "genericCredentialType", "genericAuthType": "httpBearerAuth" }, "typeVersion": 4.2 }, { "id": "952f2ff9-0421-4239-947d-3d8f0b7925fd", "name": "Split Out", "type": "n8n-nodes-base.splitOut", "position": [ 1020, 640 ], "parameters": { "options": {}, "fieldToSplitOut": "typebots" }, "typeVersion": 1 }, { "id": "ef97c1ec-d175-44b7-a462-2c8c2a8221ad", "name": "Edit Fields", "type": "n8n-nodes-base.set", "position": [ 520, 1460 ], "parameters": { "mode": "raw", "options": {}, "jsonOutput": "={{ $json.typebot }}" }, "typeVersion": 3.4 }, { "id": "ef0cd866-afcd-41b9-8fad-15d79a88041e", "name": "Sticky Note4", "type": "n8n-nodes-base.stickyNote", "position": [ 560, 600 ], "parameters": { "color": 4, "width": 150, "height": 80, "content": "## Edit this node 👇" }, "typeVersion": 1 }, { "id": "e68821d5-11ea-4324-9957-303433a8aad7", "name": "Globals", "type": "n8n-nodes-base.set", "position": [ 580, 740 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "45027581-a75b-4375-a0f1-ebfddb0531f7", "name": "typebot.url", "type": "string", "value": "https://typebot.io" }, { "id": "5513c8d4-1aba-45f3-ab8c-498fa36f5f59", "name": "typebot.workspace.id", "type": "string", "value": "xxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, { "id": "6cf546c5-5737-4dbd-851b-17d68e0a3780", "name": "repo.owner", "type": "string", "value": "john-doe" }, { "id": "452efa28-2dc6-4ea3-a7a2-c35d100d0382", "name": "repo.name", "type": "string", "value": "typebot-backup" } ] } }, "typeVersion": 3.4 }, { "id": "3027c8bd-a477-4f47-a2a9-fd952d9f9698", "name": "Schedule Trigger", "type": "n8n-nodes-base.scheduleTrigger", "position": [ 360, 840 ], "parameters": { "rule": { "interval": [ { "triggerAtHour": 7 } ] } }, "typeVersion": 1.2 }, { "id": "caff32a5-6d82-43c9-998c-3258342d66b3", "name": "github", "type": "n8n-nodes-base.set", "position": [ 1240, 840 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "5e73d2e7-4b1a-4180-8af2-047e52eb8a0a", "name": "repo.owner", "type": "string", "value": "={{ $('Globals').item.json.repo.owner }}" }, { "id": "22445c28-5431-45a5-86ca-0ab2ff26cff5", "name": "repo.name", "type": "string", "value": "={{ $('Globals').item.json.repo.name }}" }, { "id": "232d9947-a43f-48a9-b385-da1aa8f5139e", "name": "origin", "type": "string", "value": "github" }, { "id": "456ec816-8c15-498b-bbc5-a96abce95d59", "name": "typebots", "type": "array", "value": "={{ $('List Typebots').item.json.typebots }}" } ] }, "includeOtherFields": true }, "typeVersion": 3.4 }, { "id": "4333f695-81d9-4c87-8d68-9a6245dc12d5", "name": "List files", "type": "n8n-nodes-base.github", "position": [ 1020, 840 ], "webhookId": "244ea8da-851f-4afb-980c-5e5973b6a1af", "parameters": { "owner": { "__rl": true, "mode": "name", "value": "={{ $('Globals').item.json.repo.owner }}" }, "resource": "file", "operation": "list", "repository": { "__rl": true, "mode": "name", "value": "={{ $('Globals').item.json.repo.name }}" }, "authentication": "oAuth2" }, "credentials": { "githubOAuth2Api": { "id": "5UZFyU8iEpfKOIbY", "name": "GitHub marskdev" } }, "executeOnce": true, "typeVersion": 1.1 }, { "id": "7eab3efa-c3e0-420a-9fb8-9cd9ff52f90e", "name": "Get file data", "type": "n8n-nodes-base.github", "position": [ 520, 1260 ], "webhookId": "5cf07ee9-70c6-48bf-b370-534315f2d48e", "parameters": { "owner": { "__rl": true, "mode": "name", "value": "={{ $('Switch').item.json.repo.owner }}" }, "filePath": "={{ $('Switch').item.json.id }}.json", "resource": "file", "operation": "get", "repository": { "__rl": true, "mode": "name", "value": "={{ $('Switch').item.json.repo.name }}" }, "authentication": "oAuth2", "asBinaryProperty": false, "additionalParameters": {} }, "credentials": { "githubOAuth2Api": { "id": "5UZFyU8iEpfKOIbY", "name": "GitHub marskdev" } }, "typeVersion": 1, "continueOnFail": true, "alwaysOutputData": true }, { "id": "5e01d7b1-c09d-494f-8df1-c241db278084", "name": "Create new file", "type": "n8n-nodes-base.github", "position": [ 1620, 1160 ], "webhookId": "93cca36a-a5f4-4919-b655-e0fa2cc2ca36", "parameters": { "owner": { "__rl": true, "mode": "name", "value": "={{ $('Switch').item.json.repo.owner }}" }, "filePath": "={{$('Switch').first().json.id}}.json", "resource": "file", "repository": { "__rl": true, "mode": "name", "value": "={{ $('Switch').item.json.repo.name }}" }, "fileContent": "={{$('isDiffOrNew').item.json[\"typebot_data_stringy\"]}}", "commitMessage": "={{$('Switch').first().json.name}} ({{$json.github_status}})", "authentication": "oAuth2" }, "credentials": { "githubOAuth2Api": { "id": "5UZFyU8iEpfKOIbY", "name": "GitHub marskdev" } }, "typeVersion": 1 }, { "id": "4b8b16d4-5363-4f08-b8b5-deac7f4250f3", "name": "Edit existing file", "type": "n8n-nodes-base.github", "position": [ 1620, 1360 ], "webhookId": "286cabce-a3ec-4202-9d94-d005502d73cc", "parameters": { "owner": { "__rl": true, "mode": "name", "value": "={{ $('Switch').item.json.repo.owner }}" }, "filePath": "={{$('Switch').first().json.id}}.json", "resource": "file", "operation": "edit", "repository": { "__rl": true, "mode": "name", "value": "={{ $('Switch').item.json.repo.name }}" }, "fileContent": "={{$('isDiffOrNew').item.json[\"typebot_data_stringy\"]}}", "commitMessage": "={{$('Switch').first().json.name}} ({{$json.github_status}})", "authentication": "oAuth2" }, "credentials": { "githubOAuth2Api": { "id": "5UZFyU8iEpfKOIbY", "name": "GitHub marskdev" } }, "typeVersion": 1 }, { "id": "c2cb20ab-07e5-41a3-8f7d-ed6474977226", "name": "Return", "type": "n8n-nodes-base.set", "position": [ 1840, 1560 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "8d513345-6484-431f-afb7-7cf045c90f4f", "name": "Done", "type": "boolean", "value": true } ] } }, "typeVersion": 3.3 }, { "id": "7ce14355-b3b9-4cd0-a09e-6d91bfe6bfcc", "name": "Delete a file", "type": "n8n-nodes-base.github", "position": [ 1620, 1860 ], "webhookId": "592f888e-3e41-49ce-b88a-d73f8756eac8", "parameters": { "owner": { "__rl": true, "mode": "name", "value": "={{ $('Switch').item.json.repo.owner }}" }, "filePath": "={{$('Switch').first().json.name}}", "resource": "file", "operation": "delete", "repository": { "__rl": true, "mode": "name", "value": "={{ $('Switch').item.json.repo.name }}" }, "commitMessage": "={{$('Switch').first().json.name}} (deleted)", "authentication": "oAuth2" }, "credentials": { "githubOAuth2Api": { "id": "5UZFyU8iEpfKOIbY", "name": "GitHub marskdev" } }, "typeVersion": 1.1 }, { "id": "c2252937-414f-446c-a2b1-96eef623f57e", "name": "If", "type": "n8n-nodes-base.if", "position": [ 1400, 1780 ], "parameters": { "options": {}, "conditions": { "options": { "version": 2, "leftValue": "", "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "id": "bb927e0c-f27b-4dce-80df-8d7611467045", "operator": { "type": "boolean", "operation": "true", "singleValue": true }, "leftValue": "={{ $json.isDeleted }}", "rightValue": "" } ] } }, "typeVersion": 2.2 }, { "id": "10146994-a24f-4d9e-955d-f3e76f4abae0", "name": "isDeleted", "type": "n8n-nodes-base.code", "position": [ 1180, 1780 ], "parameters": { "jsCode": "const flow = $input.first().json.typebots;\n\nconst some = flow.some(x => x.id === $input.first().json.name.split(\".\")[0])\n\nreturn [{json: { isDeleted: !some }}];" }, "typeVersion": 2 }, { "id": "d692e133-5184-4753-bbab-751f9903b1cb", "name": "isDiffOrNew", "type": "n8n-nodes-base.code", "position": [ 960, 1360 ], "parameters": { "jsCode": "const orderJsonKeys = (jsonObj) => {\n const ordered = {};\n Object.keys(jsonObj).sort().forEach(key => {\n ordered[key] = jsonObj[key];\n });\n return ordered;\n}\n\n// Check if file returned with content\nif (Object.keys($input.all()[0].json).includes(\"content\")) {\n // Decode base64 content and parse JSON\n const origFlow = JSON.parse(Buffer.from($input.all()[0].json.content, 'base64').toString());\n const typebotFlow = $input.all()[1].json;\n \n // Order JSON objects\n const orderedOriginal = orderJsonKeys(origFlow);\n const orderedActual = orderJsonKeys(typebotFlow);\n\n // Determine difference\n if (JSON.stringify(orderedOriginal) === JSON.stringify(orderedActual)) {\n $input.all()[0].json.github_status = \"same\";\n } else {\n $input.all()[0].json.github_status = \"different\";\n $input.all()[0].json.typebot_data_stringy = JSON.stringify(orderedActual, null, 2);\n }\n $input.all()[0].json.content_decoded = orderedOriginal;\n// No file returned / new workflow\n} else if (Object.keys($input.all()[0].json).includes(\"data\")) {\n const origFlow = JSON.parse($input.all()[0].json.data);\n const typebotFlow = $input.all()[1].json;\n \n // Order JSON objects\n const orderedOriginal = orderJsonKeys(origFlow);\n const orderedActual = orderJsonKeys(typebotFlow);\n\n // Determine difference\n if (JSON.stringify(orderedOriginal) === JSON.stringify(orderedActual)) {\n $input.all()[0].json.github_status = \"same\";\n } else {\n $input.all()[0].json.github_status = \"different\";\n $input.all()[0].json.typebot_data_stringy = JSON.stringify(orderedActual, null, 2);\n }\n $input.all()[0].json.content_decoded = orderedOriginal;\n\n} else {\n // Order JSON object\n const typebotFlow = $input.all()[1].json;\n const orderedActual = orderJsonKeys(typebotFlow);\n \n // Proper formatting\n $input.all()[0].json.github_status = \"new\";\n $input.all()[0].json.typebot_data_stringy = JSON.stringify(orderedActual, null, 2);\n}\n\n// Return items\nreturn $input.all();" }, "typeVersion": 1 }, { "id": "bcafd96c-6fd4-44ce-b975-33c7cf2dff84", "name": "Check Status", "type": "n8n-nodes-base.switch", "position": [ 1180, 1360 ], "parameters": { "rules": { "values": [ { "outputKey": "new", "conditions": { "options": { "version": 2, "leftValue": "", "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "id": "aea200f9-9f83-4e4e-a965-65fddcbb6a5f", "operator": { "name": "filter.operator.equals", "type": "string", "operation": "equals" }, "leftValue": "={{$json.github_status}}", "rightValue": "new" } ] }, "renameOutput": true }, { "outputKey": "different", "conditions": { "options": { "version": 2, "leftValue": "", "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "id": "706ebf35-6f74-43b6-9f98-94cf14107947", "operator": { "name": "filter.operator.equals", "type": "string", "operation": "equals" }, "leftValue": "={{$json.github_status}}", "rightValue": "different" } ] }, "renameOutput": true }, { "outputKey": "same", "conditions": { "options": { "version": 2, "leftValue": "", "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "id": "30c8c5a8-269f-424a-93ed-d2cbe52acf7c", "operator": { "type": "string", "operation": "equals" }, "leftValue": "={{$json.github_status}}", "rightValue": "same" } ] }, "renameOutput": true } ] }, "options": {} }, "typeVersion": 3.2 }, { "id": "aaf2d938-ec55-4152-9e34-a2e2e6769760", "name": "File is different", "type": "n8n-nodes-base.noOp", "position": [ 1400, 1360 ], "parameters": {}, "typeVersion": 1 }, { "id": "f2759b0f-3ec3-434f-acfe-36c10ebb35bb", "name": "File is new", "type": "n8n-nodes-base.noOp", "position": [ 1400, 1160 ], "parameters": {}, "typeVersion": 1 }, { "id": "785fff83-40c4-4d38-9300-369e68779412", "name": "File is same", "type": "n8n-nodes-base.noOp", "position": [ 1400, 1560 ], "parameters": {}, "typeVersion": 1 }, { "id": "54804b0b-0001-4a41-afb5-12c0c6cf653c", "name": "Merge", "type": "n8n-nodes-base.merge", "position": [ 740, 1360 ], "parameters": {}, "typeVersion": 3.2 }, { "id": "b9cb042f-d767-4c2a-86f8-5d567d23c32a", "name": "Switch", "type": "n8n-nodes-base.switch", "position": [ 80, 1620 ], "parameters": { "rules": { "values": [ { "outputKey": "typebot", "conditions": { "options": { "version": 2, "leftValue": "", "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "id": "8f6b31b0-a75c-4299-a530-d15b3ff65c9a", "operator": { "type": "string", "operation": "equals" }, "leftValue": "={{ $json.origin }}", "rightValue": "typebot" } ] }, "renameOutput": true }, { "outputKey": "github", "conditions": { "options": { "version": 2, "leftValue": "", "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "id": "09e36861-1120-4343-8d38-4797e9d67eec", "operator": { "name": "filter.operator.equals", "type": "string", "operation": "equals" }, "leftValue": "={{ $json.origin }}", "rightValue": "github" } ] }, "renameOutput": true } ] }, "options": {} }, "typeVersion": 3.2 }, { "id": "eb4adeea-418b-4d2d-a8ce-36739c195d7e", "name": "Loop Over Items", "type": "n8n-nodes-base.splitInBatches", "position": [ 1460, 740 ], "parameters": { "options": { "reset": "={{ $node[\"Loop Over Items\"].context[\"done\"] }}" } }, "typeVersion": 3 }, { "id": "58fb33e4-520e-4a58-b3ea-acdb5ef02208", "name": "Execute Workflow", "type": "n8n-nodes-base.executeWorkflow", "position": [ 1680, 740 ], "parameters": { "mode": "each", "options": {}, "workflowId": { "__rl": true, "mode": "id", "value": "={{ $workflow.id }}" }, "workflowInputs": { "value": {}, "schema": [], "mappingMode": "defineBelow", "matchingColumns": [], "attemptToConvertTypes": false, "convertFieldsToString": true } }, "typeVersion": 1.2 } ], "pinData": {}, "connections": { "If": { "main": [ [ { "node": "Delete a file", "type": "main", "index": 0 } ], [ { "node": "Return", "type": "main", "index": 0 } ] ] }, "Merge": { "main": [ [ { "node": "isDiffOrNew", "type": "main", "index": 0 } ] ] }, "Switch": { "main": [ [ { "node": "Get Typebot", "type": "main", "index": 0 } ], [ { "node": "isDeleted", "type": "main", "index": 0 } ] ] }, "github": { "main": [ [ { "node": "Loop Over Items", "type": "main", "index": 0 } ] ] }, "Globals": { "main": [ [ { "node": "List Typebots", "type": "main", "index": 0 } ] ] }, "typebot": { "main": [ [ { "node": "Loop Over Items", "type": "main", "index": 0 } ] ] }, "Split Out": { "main": [ [ { "node": "typebot", "type": "main", "index": 0 } ] ] }, "isDeleted": { "main": [ [ { "node": "If", "type": "main", "index": 0 } ] ] }, "List files": { "main": [ [ { "node": "github", "type": "main", "index": 0 } ] ] }, "Edit Fields": { "main": [ [ { "node": "Merge", "type": "main", "index": 1 } ] ] }, "File is new": { "main": [ [ { "node": "Create new file", "type": "main", "index": 0 } ] ] }, "Get Typebot": { "main": [ [ { "node": "Get file data", "type": "main", "index": 0 }, { "node": "Edit Fields", "type": "main", "index": 0 } ] ] }, "isDiffOrNew": { "main": [ [ { "node": "Check Status", "type": "main", "index": 0 } ] ] }, "Check Status": { "main": [ [ { "node": "File is new", "type": "main", "index": 0 } ], [ { "node": "File is different", "type": "main", "index": 0 } ], [ { "node": "File is same", "type": "main", "index": 0 } ] ] }, "File is same": { "main": [ [ { "node": "Return", "type": "main", "index": 0 } ] ] }, "Delete a file": { "main": [ [ { "node": "Return", "type": "main", "index": 0 } ] ] }, "Get file data": { "main": [ [ { "node": "Merge", "type": "main", "index": 0 } ] ] }, "List Typebots": { "main": [ [ { "node": "List files", "type": "main", "index": 0 }, { "node": "Split Out", "type": "main", "index": 0 } ] ] }, "Create new file": { "main": [ [ { "node": "Return", "type": "main", "index": 0 } ] ] }, "Loop Over Items": { "main": [ [], [ { "node": "Execute Workflow", "type": "main", "index": 0 } ] ] }, "Execute Workflow": { "main": [ [ { "node": "Loop Over Items", "type": "main", "index": 0 } ] ] }, "Schedule Trigger": { "main": [ [ { "node": "Globals", "type": "main", "index": 0 } ] ] }, "File is different": { "main": [ [ { "node": "Edit existing file", "type": "main", "index": 0 } ] ] }, "Edit existing file": { "main": [ [ { "node": "Return", "type": "main", "index": 0 } ] ] }, "On clicking 'execute'": { "main": [ [ { "node": "Globals", "type": "main", "index": 0 } ] ] }, "Execute Workflow Trigger": { "main": [ [ { "node": "Switch", "type": "main", "index": 0 } ] ] } } }

				
					{
  "meta": {
    "instanceId": "00e9ec826c332aaa2865e65cdec318b633185c63a1cba1b3a2500858724cc85e",
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "e770fbf4-8c4f-4aaa-b722-3140ecec28f2",
      "name": "On clicking 'execute'",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        360,
        640
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "49b53bc4-6441-4577-a851-bb7f2c580a39",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -220,
        480
      ],
      "parameters": {
        "color": 4,
        "width": 371,
        "height": 601,
        "content": "## Typebot Backup to GitHub \nThis workflow will backup all instance typebots to GitHub and also deleted it if was deleted in your typebot workspace.\n\nThe files are saved `ID.json` for the filename.\n\n### Setup\nOpen `Globals` node and update the values below 👇\n\n- **repo.owner:** your Github username\n- **repo.name:** the name of your repository\n- **typebot.url:** default url or your self-hosted Typebot url\n- **typebot.workspace.id:** your Typebot workspace id\n\n\nIf your username was `john-doe` and your repository was called `n8n-backups`:\n\n- repo.owner - john-doe\n- repo.name - n8n-backups\n\nFor Typebot see its [documentation](https://docs.typebot.io/api-reference/how-to)\n\nThe workflow calls itself using a subworkflow, to help reduce memory usage."
      },
      "typeVersion": 1
    },
    {
      "id": "7dede05f-8c5a-426e-a822-d21b7e50d976",
      "name": "Execute Workflow Trigger",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "position": [
        -140,
        1620
      ],
      "parameters": {
        "inputSource": "passthrough"
      },
      "typeVersion": 1.1
    },
    {
      "id": "7469a576-e3ea-4e55-93f3-7f380f1a57e7",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        180,
        480
      ],
      "parameters": {
        "color": 7,
        "width": 1831,
        "height": 601,
        "content": "## Main workflow loop"
      },
      "typeVersion": 1
    },
    {
      "id": "acb81c9e-152a-4bf3-ab23-1eb66e8d5510",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -220,
        1100
      ],
      "parameters": {
        "color": 6,
        "width": 2231,
        "height": 941,
        "content": "## Subworkflow"
      },
      "typeVersion": 1
    },
    {
      "id": "6df6e830-5721-421f-9b46-f99f9164eb4d",
      "name": "List Typebots",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        800,
        740
      ],
      "parameters": {
        "url": "={{ $json.typebot.url }}/api/v1/typebots",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBearerAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "workspaceId",
              "value": "={{ $json.typebot.workspace.id }}"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "3d44e0b2-c404-424a-8eba-7ec111738939",
      "name": "typebot",
      "type": "n8n-nodes-base.set",
      "position": [
        1240,
        640
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "8fbbf5fa-0455-4066-80e0-1b2885343aea",
              "name": "typebot.url",
              "type": "string",
              "value": "={{ $('Globals').item.json.typebot.url }}"
            },
            {
              "id": "5e73d2e7-4b1a-4180-8af2-047e52eb8a0a",
              "name": "repo.owner",
              "type": "string",
              "value": "={{ $('Globals').item.json.repo.owner }}"
            },
            {
              "id": "22445c28-5431-45a5-86ca-0ab2ff26cff5",
              "name": "repo.name",
              "type": "string",
              "value": "={{ $('Globals').item.json.repo.name }}"
            },
            {
              "id": "232d9947-a43f-48a9-b385-da1aa8f5139e",
              "name": "origin",
              "type": "string",
              "value": "typebot"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "4be16d80-43fd-4cc1-b79c-11fec3c76829",
      "name": "Get Typebot",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        300,
        1360
      ],
      "parameters": {
        "url": "={{ $('Switch').item.json.typebot.url }}/api/v1/typebots/{{ $json.id }}",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBearerAuth"
      },
      "typeVersion": 4.2
    },
    {
      "id": "952f2ff9-0421-4239-947d-3d8f0b7925fd",
      "name": "Split Out",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        1020,
        640
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "typebots"
      },
      "typeVersion": 1
    },
    {
      "id": "ef97c1ec-d175-44b7-a462-2c8c2a8221ad",
      "name": "Edit Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        520,
        1460
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "={{ $json.typebot }}"
      },
      "typeVersion": 3.4
    },
    {
      "id": "ef0cd866-afcd-41b9-8fad-15d79a88041e",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        560,
        600
      ],
      "parameters": {
        "color": 4,
        "width": 150,
        "height": 80,
        "content": "## Edit this node 👇"
      },
      "typeVersion": 1
    },
    {
      "id": "e68821d5-11ea-4324-9957-303433a8aad7",
      "name": "Globals",
      "type": "n8n-nodes-base.set",
      "position": [
        580,
        740
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "45027581-a75b-4375-a0f1-ebfddb0531f7",
              "name": "typebot.url",
              "type": "string",
              "value": "https://typebot.io"
            },
            {
              "id": "5513c8d4-1aba-45f3-ab8c-498fa36f5f59",
              "name": "typebot.workspace.id",
              "type": "string",
              "value": "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
            },
            {
              "id": "6cf546c5-5737-4dbd-851b-17d68e0a3780",
              "name": "repo.owner",
              "type": "string",
              "value": "john-doe"
            },
            {
              "id": "452efa28-2dc6-4ea3-a7a2-c35d100d0382",
              "name": "repo.name",
              "type": "string",
              "value": "typebot-backup"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "3027c8bd-a477-4f47-a2a9-fd952d9f9698",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        360,
        840
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 7
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "caff32a5-6d82-43c9-998c-3258342d66b3",
      "name": "github",
      "type": "n8n-nodes-base.set",
      "position": [
        1240,
        840
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "5e73d2e7-4b1a-4180-8af2-047e52eb8a0a",
              "name": "repo.owner",
              "type": "string",
              "value": "={{ $('Globals').item.json.repo.owner }}"
            },
            {
              "id": "22445c28-5431-45a5-86ca-0ab2ff26cff5",
              "name": "repo.name",
              "type": "string",
              "value": "={{ $('Globals').item.json.repo.name }}"
            },
            {
              "id": "232d9947-a43f-48a9-b385-da1aa8f5139e",
              "name": "origin",
              "type": "string",
              "value": "github"
            },
            {
              "id": "456ec816-8c15-498b-bbc5-a96abce95d59",
              "name": "typebots",
              "type": "array",
              "value": "={{ $('List Typebots').item.json.typebots }}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "4333f695-81d9-4c87-8d68-9a6245dc12d5",
      "name": "List files",
      "type": "n8n-nodes-base.github",
      "position": [
        1020,
        840
      ],
      "webhookId": "244ea8da-851f-4afb-980c-5e5973b6a1af",
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Globals').item.json.repo.owner }}"
        },
        "resource": "file",
        "operation": "list",
        "repository": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Globals').item.json.repo.name }}"
        },
        "authentication": "oAuth2"
      },
      "credentials": {
        "githubOAuth2Api": {
          "id": "5UZFyU8iEpfKOIbY",
          "name": "GitHub marskdev"
        }
      },
      "executeOnce": true,
      "typeVersion": 1.1
    },
    {
      "id": "7eab3efa-c3e0-420a-9fb8-9cd9ff52f90e",
      "name": "Get file data",
      "type": "n8n-nodes-base.github",
      "position": [
        520,
        1260
      ],
      "webhookId": "5cf07ee9-70c6-48bf-b370-534315f2d48e",
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Switch').item.json.repo.owner }}"
        },
        "filePath": "={{ $('Switch').item.json.id }}.json",
        "resource": "file",
        "operation": "get",
        "repository": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Switch').item.json.repo.name }}"
        },
        "authentication": "oAuth2",
        "asBinaryProperty": false,
        "additionalParameters": {}
      },
      "credentials": {
        "githubOAuth2Api": {
          "id": "5UZFyU8iEpfKOIbY",
          "name": "GitHub marskdev"
        }
      },
      "typeVersion": 1,
      "continueOnFail": true,
      "alwaysOutputData": true
    },
    {
      "id": "5e01d7b1-c09d-494f-8df1-c241db278084",
      "name": "Create new file",
      "type": "n8n-nodes-base.github",
      "position": [
        1620,
        1160
      ],
      "webhookId": "93cca36a-a5f4-4919-b655-e0fa2cc2ca36",
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Switch').item.json.repo.owner }}"
        },
        "filePath": "={{$('Switch').first().json.id}}.json",
        "resource": "file",
        "repository": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Switch').item.json.repo.name }}"
        },
        "fileContent": "={{$('isDiffOrNew').item.json[\"typebot_data_stringy\"]}}",
        "commitMessage": "={{$('Switch').first().json.name}} ({{$json.github_status}})",
        "authentication": "oAuth2"
      },
      "credentials": {
        "githubOAuth2Api": {
          "id": "5UZFyU8iEpfKOIbY",
          "name": "GitHub marskdev"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "4b8b16d4-5363-4f08-b8b5-deac7f4250f3",
      "name": "Edit existing file",
      "type": "n8n-nodes-base.github",
      "position": [
        1620,
        1360
      ],
      "webhookId": "286cabce-a3ec-4202-9d94-d005502d73cc",
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Switch').item.json.repo.owner }}"
        },
        "filePath": "={{$('Switch').first().json.id}}.json",
        "resource": "file",
        "operation": "edit",
        "repository": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Switch').item.json.repo.name }}"
        },
        "fileContent": "={{$('isDiffOrNew').item.json[\"typebot_data_stringy\"]}}",
        "commitMessage": "={{$('Switch').first().json.name}} ({{$json.github_status}})",
        "authentication": "oAuth2"
      },
      "credentials": {
        "githubOAuth2Api": {
          "id": "5UZFyU8iEpfKOIbY",
          "name": "GitHub marskdev"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "c2cb20ab-07e5-41a3-8f7d-ed6474977226",
      "name": "Return",
      "type": "n8n-nodes-base.set",
      "position": [
        1840,
        1560
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "8d513345-6484-431f-afb7-7cf045c90f4f",
              "name": "Done",
              "type": "boolean",
              "value": true
            }
          ]
        }
      },
      "typeVersion": 3.3
    },
    {
      "id": "7ce14355-b3b9-4cd0-a09e-6d91bfe6bfcc",
      "name": "Delete a file",
      "type": "n8n-nodes-base.github",
      "position": [
        1620,
        1860
      ],
      "webhookId": "592f888e-3e41-49ce-b88a-d73f8756eac8",
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Switch').item.json.repo.owner }}"
        },
        "filePath": "={{$('Switch').first().json.name}}",
        "resource": "file",
        "operation": "delete",
        "repository": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Switch').item.json.repo.name }}"
        },
        "commitMessage": "={{$('Switch').first().json.name}} (deleted)",
        "authentication": "oAuth2"
      },
      "credentials": {
        "githubOAuth2Api": {
          "id": "5UZFyU8iEpfKOIbY",
          "name": "GitHub marskdev"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "c2252937-414f-446c-a2b1-96eef623f57e",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        1400,
        1780
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "bb927e0c-f27b-4dce-80df-8d7611467045",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.isDeleted }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "10146994-a24f-4d9e-955d-f3e76f4abae0",
      "name": "isDeleted",
      "type": "n8n-nodes-base.code",
      "position": [
        1180,
        1780
      ],
      "parameters": {
        "jsCode": "const flow = $input.first().json.typebots;\n\nconst some = flow.some(x => x.id === $input.first().json.name.split(\".\")[0])\n\nreturn [{json: { isDeleted: !some }}];"
      },
      "typeVersion": 2
    },
    {
      "id": "d692e133-5184-4753-bbab-751f9903b1cb",
      "name": "isDiffOrNew",
      "type": "n8n-nodes-base.code",
      "position": [
        960,
        1360
      ],
      "parameters": {
        "jsCode": "const orderJsonKeys = (jsonObj) => {\n  const ordered = {};\n  Object.keys(jsonObj).sort().forEach(key => {\n    ordered[key] = jsonObj[key];\n  });\n  return ordered;\n}\n\n// Check if file returned with content\nif (Object.keys($input.all()[0].json).includes(\"content\")) {\n  // Decode base64 content and parse JSON\n  const origFlow = JSON.parse(Buffer.from($input.all()[0].json.content, 'base64').toString());\n  const typebotFlow = $input.all()[1].json;\n  \n  // Order JSON objects\n  const orderedOriginal = orderJsonKeys(origFlow);\n  const orderedActual = orderJsonKeys(typebotFlow);\n\n  // Determine difference\n  if (JSON.stringify(orderedOriginal) === JSON.stringify(orderedActual)) {\n    $input.all()[0].json.github_status = \"same\";\n  } else {\n    $input.all()[0].json.github_status = \"different\";\n    $input.all()[0].json.typebot_data_stringy = JSON.stringify(orderedActual, null, 2);\n  }\n  $input.all()[0].json.content_decoded = orderedOriginal;\n// No file returned / new workflow\n} else if (Object.keys($input.all()[0].json).includes(\"data\")) {\n  const origFlow = JSON.parse($input.all()[0].json.data);\n  const typebotFlow = $input.all()[1].json;\n  \n  // Order JSON objects\n  const orderedOriginal = orderJsonKeys(origFlow);\n  const orderedActual = orderJsonKeys(typebotFlow);\n\n  // Determine difference\n  if (JSON.stringify(orderedOriginal) === JSON.stringify(orderedActual)) {\n    $input.all()[0].json.github_status = \"same\";\n  } else {\n    $input.all()[0].json.github_status = \"different\";\n    $input.all()[0].json.typebot_data_stringy = JSON.stringify(orderedActual, null, 2);\n  }\n  $input.all()[0].json.content_decoded = orderedOriginal;\n\n} else {\n  // Order JSON object\n  const typebotFlow = $input.all()[1].json;\n  const orderedActual = orderJsonKeys(typebotFlow);\n  \n  // Proper formatting\n  $input.all()[0].json.github_status = \"new\";\n  $input.all()[0].json.typebot_data_stringy = JSON.stringify(orderedActual, null, 2);\n}\n\n// Return items\nreturn $input.all();"
      },
      "typeVersion": 1
    },
    {
      "id": "bcafd96c-6fd4-44ce-b975-33c7cf2dff84",
      "name": "Check Status",
      "type": "n8n-nodes-base.switch",
      "position": [
        1180,
        1360
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "new",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "aea200f9-9f83-4e4e-a965-65fddcbb6a5f",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{$json.github_status}}",
                    "rightValue": "new"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "different",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "706ebf35-6f74-43b6-9f98-94cf14107947",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{$json.github_status}}",
                    "rightValue": "different"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "same",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "30c8c5a8-269f-424a-93ed-d2cbe52acf7c",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{$json.github_status}}",
                    "rightValue": "same"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "aaf2d938-ec55-4152-9e34-a2e2e6769760",
      "name": "File is different",
      "type": "n8n-nodes-base.noOp",
      "position": [
        1400,
        1360
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "f2759b0f-3ec3-434f-acfe-36c10ebb35bb",
      "name": "File is new",
      "type": "n8n-nodes-base.noOp",
      "position": [
        1400,
        1160
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "785fff83-40c4-4d38-9300-369e68779412",
      "name": "File is same",
      "type": "n8n-nodes-base.noOp",
      "position": [
        1400,
        1560
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "54804b0b-0001-4a41-afb5-12c0c6cf653c",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        740,
        1360
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "b9cb042f-d767-4c2a-86f8-5d567d23c32a",
      "name": "Switch",
      "type": "n8n-nodes-base.switch",
      "position": [
        80,
        1620
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "typebot",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "8f6b31b0-a75c-4299-a530-d15b3ff65c9a",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.origin }}",
                    "rightValue": "typebot"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "github",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "09e36861-1120-4343-8d38-4797e9d67eec",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.origin }}",
                    "rightValue": "github"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "eb4adeea-418b-4d2d-a8ce-36739c195d7e",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        1460,
        740
      ],
      "parameters": {
        "options": {
          "reset": "={{ $node[\"Loop Over Items\"].context[\"done\"] }}"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "58fb33e4-520e-4a58-b3ea-acdb5ef02208",
      "name": "Execute Workflow",
      "type": "n8n-nodes-base.executeWorkflow",
      "position": [
        1680,
        740
      ],
      "parameters": {
        "mode": "each",
        "options": {},
        "workflowId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $workflow.id }}"
        },
        "workflowInputs": {
          "value": {},
          "schema": [],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        }
      },
      "typeVersion": 1.2
    }
  ],
  "pinData": {},
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "Delete a file",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Return",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge": {
      "main": [
        [
          {
            "node": "isDiffOrNew",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch": {
      "main": [
        [
          {
            "node": "Get Typebot",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "isDeleted",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "github": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Globals": {
      "main": [
        [
          {
            "node": "List Typebots",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "typebot": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out": {
      "main": [
        [
          {
            "node": "typebot",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "isDeleted": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "List files": {
      "main": [
        [
          {
            "node": "github",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "File is new": {
      "main": [
        [
          {
            "node": "Create new file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Typebot": {
      "main": [
        [
          {
            "node": "Get file data",
            "type": "main",
            "index": 0
          },
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "isDiffOrNew": {
      "main": [
        [
          {
            "node": "Check Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Status": {
      "main": [
        [
          {
            "node": "File is new",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "File is different",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "File is same",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "File is same": {
      "main": [
        [
          {
            "node": "Return",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Delete a file": {
      "main": [
        [
          {
            "node": "Return",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get file data": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "List Typebots": {
      "main": [
        [
          {
            "node": "List files",
            "type": "main",
            "index": 0
          },
          {
            "node": "Split Out",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create new file": {
      "main": [
        [
          {
            "node": "Return",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "Execute Workflow",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Execute Workflow": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Globals",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "File is different": {
      "main": [
        [
          {
            "node": "Edit existing file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit existing file": {
      "main": [
        [
          {
            "node": "Return",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "On clicking 'execute'": {
      "main": [
        [
          {
            "node": "Globals",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Execute Workflow Trigger": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}