mirror of
https://github.com/khoaliber/n8nworkflows.xyz.git
synced 2026-04-19 17:14:37 +00:00
1 line
12 KiB
JSON
1 line
12 KiB
JSON
{"meta":{"instanceId":"d6b502dfa4d9dd072cdc5c2bb763558661053f651289291352a84403e01b3d1b","templateCredsSetupCompleted":true},"nodes":[{"id":"4377c764-07f3-4304-8105-d3f009925917","name":"On clicking 'execute'","type":"n8n-nodes-base.manualTrigger","position":[1780,520],"parameters":{},"typeVersion":1},{"id":"10f6ea70-c2cb-4463-972c-e2fdef3e837a","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[1339.5461279763795,900],"parameters":{"color":6,"width":2086.845881354743,"height":750.8363163824032,"content":"## Subworkflow"},"typeVersion":1},{"id":"d22236c2-578c-400b-b3e5-354498620c39","name":"Return","type":"n8n-nodes-base.set","position":[3220,1100],"parameters":{"options":{},"assignments":{"assignments":[{"id":"8d513345-6484-431f-afb7-7cf045c90f4f","name":"Done","type":"boolean","value":true}]}},"typeVersion":3.3},{"id":"943eed85-d4cd-4ec5-b278-d143b0f6bd15","name":"Get File","type":"n8n-nodes-base.httpRequest","position":[2320,980],"parameters":{"url":"={{ $json.download_url }}","options":{}},"typeVersion":4.2},{"id":"124ebdd7-c2c1-4fec-89d3-596f034e0fe7","name":"If file too large","type":"n8n-nodes-base.if","position":[2120,1000],"parameters":{"options":{},"conditions":{"options":{"version":1,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"45ce825e-9fa6-430c-8931-9aaf22c42585","operator":{"type":"string","operation":"empty","singleValue":true},"leftValue":"={{ $json.content }}","rightValue":""},{"id":"9619a55f-7fb1-4f24-b1a7-7aeb82365806","operator":{"type":"string","operation":"notExists","singleValue":true},"leftValue":"={{ $json.error }}","rightValue":""}]}},"typeVersion":2},{"id":"751621b4-4f99-4178-a691-40fc7488874b","name":"Merge Items","type":"n8n-nodes-base.merge","position":[2120,1260],"parameters":{},"typeVersion":2},{"id":"8892eb02-0e8e-4617-85e6-e6f188361f95","name":"isDiffOrNew","type":"n8n-nodes-base.code","position":[2320,1260],"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 origWorkflow = JSON.parse(Buffer.from($input.all()[0].json.content, 'base64').toString());\n const n8nWorkflow = $input.all()[1].json;\n \n // Order JSON objects\n const orderedOriginal = orderJsonKeys(origWorkflow);\n const orderedActual = orderJsonKeys(n8nWorkflow);\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.n8n_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 origWorkflow = JSON.parse($input.all()[0].json.data);\n const n8nWorkflow = $input.all()[1].json;\n \n // Order JSON objects\n const orderedOriginal = orderJsonKeys(origWorkflow);\n const orderedActual = orderJsonKeys(n8nWorkflow);\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.n8n_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 n8nWorkflow = $input.all()[1].json;\n const orderedActual = orderJsonKeys(n8nWorkflow);\n \n // Proper formatting\n $input.all()[0].json.github_status = \"new\";\n $input.all()[0].json.n8n_data_stringy = JSON.stringify(orderedActual, null, 2);\n}\n\n// Return items\nreturn $input.all();"},"typeVersion":1},{"id":"bfddb2a2-c149-4710-bd77-b368d641114d","name":"Check Status","type":"n8n-nodes-base.switch","position":[2540,1260],"parameters":{"rules":{"rules":[{"value2":"same"},{"output":1,"value2":"different"},{"output":2,"value2":"new"}]},"value1":"={{$json.github_status}}","dataType":"string"},"typeVersion":1},{"id":"681e54af-b916-416d-9801-ac38a5882bcf","name":"Same file - Do nothing","type":"n8n-nodes-base.noOp","position":[2760,1100],"parameters":{},"typeVersion":1},{"id":"38b2041d-1d56-436f-aa04-79d7241dcc74","name":"File is different","type":"n8n-nodes-base.noOp","position":[2760,1260],"parameters":{},"typeVersion":1},{"id":"ae33280d-10d5-4882-be9b-7972394357e1","name":"File is new","type":"n8n-nodes-base.noOp","position":[2760,1420],"parameters":{},"typeVersion":1},{"id":"bea3995f-9f34-4119-a6cf-20281e70d685","name":"Create new file","type":"n8n-nodes-base.github","position":[2980,1420],"parameters":{"owner":{"__rl":true,"mode":"name","value":"={{ $('Globals').item.json.repo.owner }}"},"filePath":"={{ $('Globals').item.json.repo.path }}{{$('Execute Workflow Trigger').first().json.id}}.json","resource":"file","repository":{"__rl":true,"mode":"name","value":"={{ $('Globals').item.json.repo.name }}"},"fileContent":"={{$('isDiffOrNew').item.json[\"n8n_data_stringy\"]}}","commitMessage":"={{$('Execute Workflow Trigger').first().json.name}} ({{$json.github_status}})"},"credentials":{"githubApi":{"id":"3mfzXcMjoqNHsujs","name":"GitHub account"}},"typeVersion":1},{"id":"d9172af3-55f8-4b99-b462-3e6e718b5a77","name":"Edit existing file","type":"n8n-nodes-base.github","position":[2980,1240],"parameters":{"owner":{"__rl":true,"mode":"name","value":"={{ $('Globals').item.json.repo.owner }}"},"filePath":"={{ $('Globals').item.json.repo.path }}{{$('Execute Workflow Trigger').first().json.id}}.json","resource":"file","operation":"edit","repository":{"__rl":true,"mode":"name","value":"={{ $('Globals').item.json.repo.name }}"},"fileContent":"={{$('isDiffOrNew').item.json[\"n8n_data_stringy\"]}}","commitMessage":"={{$('Execute Workflow Trigger').first().json.name}} ({{$json.github_status}})"},"credentials":{"githubApi":{"id":"3mfzXcMjoqNHsujs","name":"GitHub account"}},"typeVersion":1},{"id":"d9589e32-ed20-46e7-9427-1680c6222406","name":"Loop Over Items","type":"n8n-nodes-base.splitInBatches","position":[2380,620],"parameters":{"options":{}},"typeVersion":3},{"id":"e1530650-aa76-4ab3-b5bb-cd6b805ea656","name":"Schedule Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[1780,720],"parameters":{"rule":{"interval":[{"field":"hours","hoursInterval":2}]}},"typeVersion":1.2},{"id":"79910589-f40f-46fa-a704-eaa65157a17a","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[1340,278.28654385738866],"parameters":{"color":4,"width":365.19481715599653,"height":596.4810912485963,"content":"## Backup to GitHub \nThis workflow will backup all instance credentials to GitHub.\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- **repo.path:** the folder to use within the repository. If it doesn't exist it will be created.\n\n\nIf your username was `john-doe` and your repository was called `n8n-backups` and you wanted the credentials to go into a `credentials` folder you would set:\n\n- repo.owner - john-doe\n- repo.name - n8n-backups\n- repo.path - credentials/\n\n\nThe workflow calls itself using a subworkflow, to help reduce memory usage."},"typeVersion":1},{"id":"e16c9874-1a35-41c4-8410-0c42efe17770","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[1740,440],"parameters":{"color":7,"width":1028.7522287279464,"height":434.88564057365943,"content":"## Main workflow loop"},"typeVersion":1},{"id":"a1464b91-516a-4fd9-9235-20de50e74cb2","name":"Get file data","type":"n8n-nodes-base.github","position":[1920,1000],"parameters":{"owner":{"__rl":true,"mode":"name","value":"={{ $json.repo.owner }}"},"filePath":"={{ $json.repo.path }}{{ $('Execute Workflow Trigger').item.json.id }}.json","resource":"file","operation":"get","repository":{"__rl":true,"mode":"name","value":"={{ $json.repo.name }}"},"asBinaryProperty":false,"additionalParameters":{}},"credentials":{"githubApi":{"id":"3mfzXcMjoqNHsujs","name":"GitHub account"}},"typeVersion":1,"continueOnFail":true,"alwaysOutputData":true},{"id":"eb2fe87f-f3af-4215-ac1f-7c2b45e8aff6","name":"Globals","type":"n8n-nodes-base.set","position":[1720,1160],"parameters":{"options":{},"assignments":{"assignments":[{"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":"n8n-backup"},{"id":"81c4dc54-86bf-4432-a23f-22c7ea831e74","name":"repo.path","type":"string","value":"credentials/"}]}},"typeVersion":3.4},{"id":"f4498ab4-1760-4849-9fe1-ecfcd7baa9f3","name":"Execute Command","type":"n8n-nodes-base.executeCommand","position":[2000,620],"parameters":{"command":"npx n8n export:credentials --all --decrypted"},"typeVersion":1},{"id":"d453a000-40ef-43f5-b108-5eb30422d1a3","name":"JSON formatting","type":"n8n-nodes-base.code","position":[2180,620],"parameters":{"jsCode":"// Function to beautify JSON\nfunction beautifyJson(jsonString) {\n try {\n // Parse the JSON string\n const jsonObject = JSON.parse(jsonString);\n\n // Format the JSON with indentation\n return jsonObject; // Return the parsed object directly\n } catch (error) {\n // Return the error message if JSON is invalid\n return `Invalid JSON: ${error.message}`;\n }\n}\n\n// Retrieve the JSON object from the input data\nconst input = $input.all()[0].json;\n\n// Extract the JSON string from the stdout field\nconst jsonString = input.stdout.match(/\\[{.*}\\]/s);\n\n// Check if a valid JSON string is found\nif (!jsonString) {\n return {\n json: {\n error: \"No valid JSON string found in stdout.\"\n }\n };\n}\n\n// Beautify the JSON\nconst beautifiedJson = beautifyJson(jsonString[0]);\n\n// Output the beautified JSON, ensuring each entry is in an object with a 'json' key\nconst output = beautifiedJson.map(entry => ({ json: entry }));\n\n// Return the output\nreturn output;\n"},"typeVersion":2},{"id":"49dbf875-7345-4241-a7fc-f42e53aef64e","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1680,1060],"parameters":{"color":4,"width":150,"height":80,"content":"## Edit this node 👇"},"typeVersion":1},{"id":"98158f3e-7aca-456b-994c-4c795d31c18c","name":"Execute Workflow","type":"n8n-nodes-base.executeWorkflow","position":[2600,620],"parameters":{"mode":"each","options":{},"workflowId":"={{ $workflow.id }}"},"typeVersion":1},{"id":"d8c52eb7-bcb0-49e7-bb32-7499b1ca22cd","name":"Execute Workflow Trigger","type":"n8n-nodes-base.executeWorkflowTrigger","position":[1440,1280],"parameters":{"inputSource":"passthrough"},"typeVersion":1.1}],"pinData":{},"connections":{"Globals":{"main":[[{"node":"Get file data","type":"main","index":0}]]},"Get File":{"main":[[{"node":"Merge Items","type":"main","index":0}]]},"File is new":{"main":[[{"node":"Create new file","type":"main","index":0}]]},"Merge Items":{"main":[[{"node":"isDiffOrNew","type":"main","index":0}]]},"isDiffOrNew":{"main":[[{"node":"Check Status","type":"main","index":0}]]},"Check Status":{"main":[[{"node":"Same file - Do nothing","type":"main","index":0}],[{"node":"File is different","type":"main","index":0}],[{"node":"File is new","type":"main","index":0}]]},"Get file data":{"main":[[{"node":"If file too large","type":"main","index":0}]]},"Create new file":{"main":[[{"node":"Return","type":"main","index":0}]]},"Execute Command":{"main":[[{"node":"JSON formatting","type":"main","index":0}]]},"JSON formatting":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"Loop Over Items":{"main":[[],[{"node":"Execute Workflow","type":"main","index":0},{"node":"Execute Workflow","type":"main","index":0}]]},"Execute Workflow":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"Schedule Trigger":{"main":[[{"node":"Execute Command","type":"main","index":0}]]},"File is different":{"main":[[{"node":"Edit existing file","type":"main","index":0}]]},"If file too large":{"main":[[{"node":"Get File","type":"main","index":0}],[{"node":"Merge Items","type":"main","index":0}]]},"Edit existing file":{"main":[[{"node":"Return","type":"main","index":0}]]},"On clicking 'execute'":{"main":[[{"node":"Execute Command","type":"main","index":0}]]},"Same file - Do nothing":{"main":[[{"node":"Return","type":"main","index":0}]]},"Execute Workflow Trigger":{"main":[[{"node":"Globals","type":"main","index":0},{"node":"Merge Items","type":"main","index":1}]]}}} |