Sauvegarde des workflows sur GitHub
Ceci est unOtherworkflow d'automatisation du domainecontenant 23 nœuds.Utilise principalement des nœuds comme If, N8n, Set, Code, Merge. Sauvegarde des workflows dans GitHub
- •Personal Access Token GitHub
- •Peut nécessiter les informations d'identification d'authentification de l'API cible
Nœuds utilisés (23)
Catégorie
{
"meta": {
"instanceId": "d6b502dfa4d9dd072cdc5c2bb763558661053f651289291352a84403e01b3d1b",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "42cc4260-626e-4f83-b1c3-c78c99b78b38",
"name": "Au clic sur 'exécuter'",
"type": "n8n-nodes-base.manualTrigger",
"position": [
1780,
520
],
"parameters": {},
"typeVersion": 1
},
{
"id": "f21386ff-f8db-4f5d-a44c-15484d1e4ab7",
"name": "Note adhésive",
"type": "n8n-nodes-base.stickyNote",
"position": [
1340,
900
],
"parameters": {
"color": 6,
"width": 2086.845881354743,
"height": 750.8363163824032,
"content": "## Subworkflow"
},
"typeVersion": 1
},
{
"id": "82851e4a-33a1-461b-965f-f51efcb5af90",
"name": "n8n",
"type": "n8n-nodes-base.n8n",
"position": [
2040,
620
],
"parameters": {
"filters": {},
"requestOptions": {}
},
"credentials": {
"n8nApi": {
"id": "1SDBLwjifPzb02W8",
"name": "n8n account"
}
},
"typeVersion": 1
},
{
"id": "90cac8e2-9509-4d48-9038-bb653ffbdf9d",
"name": "Retour",
"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": "11046021-89ba-4e61-b03f-d606e7dd0a56",
"name": "Obtenir le fichier",
"type": "n8n-nodes-base.httpRequest",
"position": [
2320,
980
],
"parameters": {
"url": "={{ $json.download_url }}",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "08af670c-ac82-422f-9938-c649dfdfbcf6",
"name": "Si fichier trop volumineux",
"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": "795fd895-94b2-46f1-b559-748b0db01c49",
"name": "Fusionner les éléments",
"type": "n8n-nodes-base.merge",
"position": [
2120,
1260
],
"parameters": {},
"typeVersion": 2
},
{
"id": "3d3399f3-bbfb-48ab-8644-91b28e731026",
"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": "2f2f42d0-d27c-4856-a263-4d5e9eda2c4c",
"name": "Vérifier le statut",
"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": "5316029f-f32f-4a8d-95de-50ee57051a08",
"name": "Fichier identique - Ne rien faire",
"type": "n8n-nodes-base.noOp",
"position": [
2760,
1100
],
"parameters": {},
"typeVersion": 1
},
{
"id": "37c5983b-48fe-41d5-8e3a-eb56dec2140b",
"name": "Le fichier est différent",
"type": "n8n-nodes-base.noOp",
"position": [
2760,
1260
],
"parameters": {},
"typeVersion": 1
},
{
"id": "a4dcce9e-b0d0-4b9e-ab16-9142e641c73d",
"name": "Le fichier est nouveau",
"type": "n8n-nodes-base.noOp",
"position": [
2760,
1420
],
"parameters": {},
"typeVersion": 1
},
{
"id": "03fcfdc4-2e52-42f0-a129-3ebaf8dd8fc1",
"name": "Créer un nouveau fichier",
"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": "dd35cc39-4ab4-4d53-b439-b425a2177e8f",
"name": "Modifier le fichier existant",
"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": "d05e2a25-24be-43fb-baa4-9c3391840e70",
"name": "Boucler sur les éléments",
"type": "n8n-nodes-base.splitInBatches",
"position": [
2240,
620
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "2a139d59-1387-4899-88b3-21106cd01099",
"name": "Déclencheur planifié",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
1780,
720
],
"parameters": {
"rule": {
"interval": [
{
"field": "hours",
"hoursInterval": 2
}
]
}
},
"typeVersion": 1.2
},
{
"id": "04e6c245-3117-4ef8-a181-754e616e958b",
"name": "Note adhésive 1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1340,
273.8835396388249
],
"parameters": {
"color": 4,
"width": 371.1995072042308,
"height": 600.88409546716,
"content": "## Backup to GitHub \nThis workflow will backup all instance workflows 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 workflows to go into a `workflows` folder you would set:\n\n- repo.owner - john-doe\n- repo.name - n8n-backups\n- repo.path - workflows/\n\n\nThe workflow calls itself using a subworkflow, to help reduce memory usage."
},
"typeVersion": 1
},
{
"id": "3d996985-0064-4749-85a1-2191c73746c9",
"name": "Note adhésive 2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1740,
440
],
"parameters": {
"color": 7,
"width": 886.4410237965205,
"height": 434.88564057365943,
"content": "## Main workflow loop"
},
"typeVersion": 1
},
{
"id": "c9bfa393-e120-4bfe-b957-702756b91aaf",
"name": "Obtenir les données du fichier",
"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": "d42ddc37-3bd9-4f19-8831-695bec4d0137",
"name": "Globals",
"type": "n8n-nodes-base.set",
"position": [
1700,
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": "workflows/"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "e970c63c-2aa2-46f9-be04-f045b6a938de",
"name": "Note adhésive 3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1660,
1060
],
"parameters": {
"color": 4,
"width": 150,
"height": 80,
"content": "## Edit this node 👇"
},
"typeVersion": 1
},
{
"id": "5b1991f7-0351-44de-908d-9aa8b8262d60",
"name": "Déclencheur d'exécution de workflow",
"type": "n8n-nodes-base.executeWorkflowTrigger",
"position": [
1420,
1280
],
"parameters": {
"inputSource": "passthrough"
},
"typeVersion": 1.1
},
{
"id": "8e5b3f71-0c5e-4e78-a3f7-0b574c9ddf06",
"name": "Exécuter le workflow",
"type": "n8n-nodes-base.executeWorkflow",
"position": [
2460,
620
],
"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": {
"82851e4a-33a1-461b-965f-f51efcb5af90": {
"main": [
[
{
"node": "d05e2a25-24be-43fb-baa4-9c3391840e70",
"type": "main",
"index": 0
}
]
]
},
"d42ddc37-3bd9-4f19-8831-695bec4d0137": {
"main": [
[
{
"node": "c9bfa393-e120-4bfe-b957-702756b91aaf",
"type": "main",
"index": 0
}
]
]
},
"11046021-89ba-4e61-b03f-d606e7dd0a56": {
"main": [
[
{
"node": "795fd895-94b2-46f1-b559-748b0db01c49",
"type": "main",
"index": 0
}
]
]
},
"a4dcce9e-b0d0-4b9e-ab16-9142e641c73d": {
"main": [
[
{
"node": "03fcfdc4-2e52-42f0-a129-3ebaf8dd8fc1",
"type": "main",
"index": 0
}
]
]
},
"795fd895-94b2-46f1-b559-748b0db01c49": {
"main": [
[
{
"node": "3d3399f3-bbfb-48ab-8644-91b28e731026",
"type": "main",
"index": 0
}
]
]
},
"3d3399f3-bbfb-48ab-8644-91b28e731026": {
"main": [
[
{
"node": "2f2f42d0-d27c-4856-a263-4d5e9eda2c4c",
"type": "main",
"index": 0
}
]
]
},
"2f2f42d0-d27c-4856-a263-4d5e9eda2c4c": {
"main": [
[
{
"node": "5316029f-f32f-4a8d-95de-50ee57051a08",
"type": "main",
"index": 0
}
],
[
{
"node": "37c5983b-48fe-41d5-8e3a-eb56dec2140b",
"type": "main",
"index": 0
}
],
[
{
"node": "a4dcce9e-b0d0-4b9e-ab16-9142e641c73d",
"type": "main",
"index": 0
}
]
]
},
"c9bfa393-e120-4bfe-b957-702756b91aaf": {
"main": [
[
{
"node": "08af670c-ac82-422f-9938-c649dfdfbcf6",
"type": "main",
"index": 0
}
]
]
},
"03fcfdc4-2e52-42f0-a129-3ebaf8dd8fc1": {
"main": [
[
{
"node": "90cac8e2-9509-4d48-9038-bb653ffbdf9d",
"type": "main",
"index": 0
}
]
]
},
"d05e2a25-24be-43fb-baa4-9c3391840e70": {
"main": [
[],
[
{
"node": "8e5b3f71-0c5e-4e78-a3f7-0b574c9ddf06",
"type": "main",
"index": 0
}
]
]
},
"8e5b3f71-0c5e-4e78-a3f7-0b574c9ddf06": {
"main": [
[
{
"node": "d05e2a25-24be-43fb-baa4-9c3391840e70",
"type": "main",
"index": 0
}
]
]
},
"2a139d59-1387-4899-88b3-21106cd01099": {
"main": [
[
{
"node": "82851e4a-33a1-461b-965f-f51efcb5af90",
"type": "main",
"index": 0
}
]
]
},
"37c5983b-48fe-41d5-8e3a-eb56dec2140b": {
"main": [
[
{
"node": "dd35cc39-4ab4-4d53-b439-b425a2177e8f",
"type": "main",
"index": 0
}
]
]
},
"08af670c-ac82-422f-9938-c649dfdfbcf6": {
"main": [
[
{
"node": "11046021-89ba-4e61-b03f-d606e7dd0a56",
"type": "main",
"index": 0
}
],
[
{
"node": "795fd895-94b2-46f1-b559-748b0db01c49",
"type": "main",
"index": 0
}
]
]
},
"dd35cc39-4ab4-4d53-b439-b425a2177e8f": {
"main": [
[
{
"node": "90cac8e2-9509-4d48-9038-bb653ffbdf9d",
"type": "main",
"index": 0
}
]
]
},
"42cc4260-626e-4f83-b1c3-c78c99b78b38": {
"main": [
[
{
"node": "82851e4a-33a1-461b-965f-f51efcb5af90",
"type": "main",
"index": 0
}
]
]
},
"5316029f-f32f-4a8d-95de-50ee57051a08": {
"main": [
[
{
"node": "90cac8e2-9509-4d48-9038-bb653ffbdf9d",
"type": "main",
"index": 0
}
]
]
},
"5b1991f7-0351-44de-908d-9aa8b8262d60": {
"main": [
[
{
"node": "d42ddc37-3bd9-4f19-8831-695bec4d0137",
"type": "main",
"index": 0
},
{
"node": "795fd895-94b2-46f1-b559-748b0db01c49",
"type": "main",
"index": 1
}
]
]
}
}
}Comment utiliser ce workflow ?
Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.
Dans quelles scénarios ce workflow est-il adapté ?
Avancé - Autres
Est-ce payant ?
Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.
Workflows recommandés
Solomon
@solomonFreelance consultant from Brazil, specializing in automations and data analysis. I work with select clients, addressing their toughest projects. For business inquiries, email me at automations.solomon@gmail.com or message me on Telegram for a faster response.
Partager ce workflow