diff --git a/n8n-container-actions.json b/n8n-container-actions.json
index b537e45..cb454b9 100644
--- a/n8n-container-actions.json
+++ b/n8n-container-actions.json
@@ -44,6 +44,65 @@
300
]
},
+ {
+ "parameters": {
+ "conditions": {
+ "options": {
+ "caseSensitive": true,
+ "typeValidation": "loose"
+ },
+ "conditions": [
+ {
+ "id": "has-container-id",
+ "leftValue": "={{ $json.containerId }}",
+ "rightValue": "",
+ "operator": {
+ "type": "string",
+ "operation": "notEquals"
+ }
+ }
+ ],
+ "combinator": "and"
+ }
+ },
+ "id": "if-has-id",
+ "name": "Has Container ID?",
+ "type": "n8n-nodes-base.if",
+ "typeVersion": 2.2,
+ "position": [
+ 420,
+ 300
+ ]
+ },
+ {
+ "parameters": {
+ "url": "http://docker-socket-proxy:2375/v1.47/containers/json?all=true",
+ "options": {
+ "timeout": 5000
+ }
+ },
+ "id": "http-get-containers",
+ "name": "Get All Containers",
+ "type": "n8n-nodes-base.httpRequest",
+ "typeVersion": 4.2,
+ "position": [
+ 600,
+ 400
+ ]
+ },
+ {
+ "parameters": {
+ "jsCode": "// Find container by name and resolve ID\nconst triggerData = $('When executed by another workflow').item.json;\nconst containerName = triggerData.containerName;\nconst containers = $input.all();\n\n// Normalize function to strip leading slash\nconst normalizeName = (name) => name.replace(/^\\//, '').toLowerCase();\nconst searchName = normalizeName(containerName);\n\n// Find matching container\nlet matched = null;\nfor (const item of containers) {\n const c = item.json;\n if (c.Names && c.Names.length > 0) {\n const cName = normalizeName(c.Names[0]);\n if (cName === searchName || cName.includes(searchName)) {\n matched = c;\n break;\n }\n }\n}\n\nif (!matched) {\n // Return error - container not found\n return {\n json: {\n ...triggerData,\n containerId: '',\n error: `Container '${containerName}' not found`\n }\n };\n}\n\nreturn {\n json: {\n ...triggerData,\n containerId: matched.Id\n }\n};"
+ },
+ "id": "code-resolve-id",
+ "name": "Resolve Container ID",
+ "type": "n8n-nodes-base.code",
+ "typeVersion": 2,
+ "position": [
+ 780,
+ 400
+ ]
+ },
{
"parameters": {
"rules": {
@@ -128,7 +187,7 @@
"type": "n8n-nodes-base.switch",
"typeVersion": 3.2,
"position": [
- 460,
+ 960,
300
]
},
@@ -145,7 +204,7 @@
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
- 680,
+ 1160,
200
],
"onError": "continueRegularOutput"
@@ -163,7 +222,7 @@
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
- 680,
+ 1160,
300
],
"onError": "continueRegularOutput"
@@ -181,53 +240,93 @@
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
- 680,
+ 1160,
400
],
"onError": "continueRegularOutput"
},
{
"parameters": {
- "jsCode": "// Format start action result\nconst triggerData = $('When executed by another workflow').item.json;\nconst containerId = triggerData.containerId;\nconst containerName = triggerData.containerName;\nconst action = triggerData.action;\nconst chatId = triggerData.chatId;\nconst messageId = triggerData.messageId;\nconst responseMode = triggerData.responseMode;\n\n// Docker API returns 204 No Content on success (empty response body)\n// Error responses contain 'message' field\nconst response = $input.item.json || {};\nconst hasError = response.message || response.error || false;\n\n// Success = no error message in response (empty {} means 204 success)\nconst success = !hasError;\n\nlet message;\nif (success) {\n message = `\\u25B6\\uFE0F ${containerName} started successfully`;\n} else {\n message = `\\u274C Failed to start ${containerName}`;\n}\n\nreturn {\n json: {\n success,\n message,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n};"
+ "jsCode": "// Format start action result\nconst triggerData = $('When executed by another workflow').item.json;\nconst containerId = $json.containerId || triggerData.containerId;\nconst containerName = triggerData.containerName;\nconst action = triggerData.action;\nconst chatId = triggerData.chatId;\nconst messageId = triggerData.messageId;\nconst responseMode = triggerData.responseMode;\n\n// Docker API returns 204 No Content on success (empty response body)\n// Error responses contain 'message' field\nconst response = $input.item.json || {};\nconst hasError = response.message || response.error || false;\n\n// Success = no error message in response (empty {} means 204 success)\nconst success = !hasError;\n\nlet message;\nif (success) {\n message = `\\u25B6\\uFE0F ${containerName} started successfully`;\n} else {\n message = `\\u274C Failed to start ${containerName}`;\n}\n\nreturn {\n json: {\n success,\n message,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n};"
},
"id": "code-format-start-result",
"name": "Format Start Result",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
- 900,
+ 1380,
200
]
},
{
"parameters": {
- "jsCode": "// Format stop action result\nconst triggerData = $('When executed by another workflow').item.json;\nconst containerId = triggerData.containerId;\nconst containerName = triggerData.containerName;\nconst action = triggerData.action;\nconst chatId = triggerData.chatId;\nconst messageId = triggerData.messageId;\nconst responseMode = triggerData.responseMode;\n\n// Docker API returns 204 No Content on success (empty response body)\n// Error responses contain 'message' field\nconst response = $input.item.json || {};\nconst hasError = response.message || response.error || false;\n\n// Success = no error message in response (empty {} means 204 success)\nconst success = !hasError;\n\nlet message;\nif (success) {\n message = `\\u23F9\\uFE0F ${containerName} stopped`;\n} else {\n message = `\\u274C Failed to stop ${containerName}`;\n}\n\nreturn {\n json: {\n success,\n message,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n};"
+ "jsCode": "// Format stop action result\nconst triggerData = $('When executed by another workflow').item.json;\nconst containerId = $json.containerId || triggerData.containerId;\nconst containerName = triggerData.containerName;\nconst action = triggerData.action;\nconst chatId = triggerData.chatId;\nconst messageId = triggerData.messageId;\nconst responseMode = triggerData.responseMode;\n\n// Docker API returns 204 No Content on success (empty response body)\n// Error responses contain 'message' field\nconst response = $input.item.json || {};\nconst hasError = response.message || response.error || false;\n\n// Success = no error message in response (empty {} means 204 success)\nconst success = !hasError;\n\nlet message;\nif (success) {\n message = `\\u23F9\\uFE0F ${containerName} stopped`;\n} else {\n message = `\\u274C Failed to stop ${containerName}`;\n}\n\nreturn {\n json: {\n success,\n message,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n};"
},
"id": "code-format-stop-result",
"name": "Format Stop Result",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
- 900,
+ 1380,
300
]
},
{
"parameters": {
- "jsCode": "// Format restart action result\nconst triggerData = $('When executed by another workflow').item.json;\nconst containerId = triggerData.containerId;\nconst containerName = triggerData.containerName;\nconst action = triggerData.action;\nconst chatId = triggerData.chatId;\nconst messageId = triggerData.messageId;\nconst responseMode = triggerData.responseMode;\n\n// Docker API returns 204 No Content on success (empty response body)\n// Error responses contain 'message' field\nconst response = $input.item.json || {};\nconst hasError = response.message || response.error || false;\n\n// Success = no error message in response (empty {} means 204 success)\nconst success = !hasError;\n\nlet message;\nif (success) {\n message = `\\u{1F504} ${containerName} restarted`;\n} else {\n message = `\\u274C Failed to restart ${containerName}`;\n}\n\nreturn {\n json: {\n success,\n message,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n};"
+ "jsCode": "// Format restart action result\nconst triggerData = $('When executed by another workflow').item.json;\nconst containerId = $json.containerId || triggerData.containerId;\nconst containerName = triggerData.containerName;\nconst action = triggerData.action;\nconst chatId = triggerData.chatId;\nconst messageId = triggerData.messageId;\nconst responseMode = triggerData.responseMode;\n\n// Docker API returns 204 No Content on success (empty response body)\n// Error responses contain 'message' field\nconst response = $input.item.json || {};\nconst hasError = response.message || response.error || false;\n\n// Success = no error message in response (empty {} means 204 success)\nconst success = !hasError;\n\nlet message;\nif (success) {\n message = `\\u{1F504} ${containerName} restarted`;\n} else {\n message = `\\u274C Failed to restart ${containerName}`;\n}\n\nreturn {\n json: {\n success,\n message,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n};"
},
"id": "code-format-restart-result",
"name": "Format Restart Result",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
- 900,
+ 1380,
400
]
}
],
"connections": {
"When executed by another workflow": {
+ "main": [
+ [
+ {
+ "node": "Has Container ID?",
+ "type": "main",
+ "index": 0
+ }
+ ]
+ ]
+ },
+ "Has Container ID?": {
+ "main": [
+ [
+ {
+ "node": "Route Action",
+ "type": "main",
+ "index": 0
+ }
+ ],
+ [
+ {
+ "node": "Get All Containers",
+ "type": "main",
+ "index": 0
+ }
+ ]
+ ]
+ },
+ "Get All Containers": {
+ "main": [
+ [
+ {
+ "node": "Resolve Container ID",
+ "type": "main",
+ "index": 0
+ }
+ ]
+ ]
+ },
+ "Resolve Container ID": {
"main": [
[
{
@@ -301,4 +400,4 @@
"executionOrder": "v1",
"callerPolicy": "any"
}
-}
\ No newline at end of file
+}
diff --git a/n8n-container-update.json b/n8n-container-update.json
index 1ff3d97..0e00ddf 100644
--- a/n8n-container-update.json
+++ b/n8n-container-update.json
@@ -39,6 +39,65 @@
300
]
},
+ {
+ "parameters": {
+ "conditions": {
+ "options": {
+ "caseSensitive": true,
+ "typeValidation": "loose"
+ },
+ "conditions": [
+ {
+ "id": "has-container-id",
+ "leftValue": "={{ $json.containerId }}",
+ "rightValue": "",
+ "operator": {
+ "type": "string",
+ "operation": "notEquals"
+ }
+ }
+ ],
+ "combinator": "and"
+ }
+ },
+ "id": "if-has-id",
+ "name": "Has Container ID?",
+ "type": "n8n-nodes-base.if",
+ "typeVersion": 2.2,
+ "position": [
+ 400,
+ 300
+ ]
+ },
+ {
+ "parameters": {
+ "url": "http://docker-socket-proxy:2375/v1.47/containers/json?all=true",
+ "options": {
+ "timeout": 5000
+ }
+ },
+ "id": "http-get-containers",
+ "name": "Get All Containers",
+ "type": "n8n-nodes-base.httpRequest",
+ "typeVersion": 4.2,
+ "position": [
+ 560,
+ 400
+ ]
+ },
+ {
+ "parameters": {
+ "jsCode": "// Find container by name and resolve ID\nconst triggerData = $('When executed by another workflow').item.json;\nconst containerName = triggerData.containerName;\nconst containers = $input.all();\n\n// Normalize function to strip leading slash\nconst normalizeName = (name) => name.replace(/^\\//, '').toLowerCase();\nconst searchName = normalizeName(containerName);\n\n// Find matching container\nlet matched = null;\nfor (const item of containers) {\n const c = item.json;\n if (c.Names && c.Names.length > 0) {\n const cName = normalizeName(c.Names[0]);\n if (cName === searchName || cName.includes(searchName)) {\n matched = c;\n break;\n }\n }\n}\n\nif (!matched) {\n throw new Error(`Container '${containerName}' not found`);\n}\n\nreturn {\n json: {\n ...triggerData,\n containerId: matched.Id\n }\n};"
+ },
+ "id": "code-resolve-id",
+ "name": "Resolve Container ID",
+ "type": "n8n-nodes-base.code",
+ "typeVersion": 2,
+ "position": [
+ 720,
+ 400
+ ]
+ },
{
"parameters": {
"method": "GET",
@@ -616,6 +675,46 @@
],
"connections": {
"When executed by another workflow": {
+ "main": [
+ [
+ {
+ "node": "Has Container ID?",
+ "type": "main",
+ "index": 0
+ }
+ ]
+ ]
+ },
+ "Has Container ID?": {
+ "main": [
+ [
+ {
+ "node": "Inspect Container",
+ "type": "main",
+ "index": 0
+ }
+ ],
+ [
+ {
+ "node": "Get All Containers",
+ "type": "main",
+ "index": 0
+ }
+ ]
+ ]
+ },
+ "Get All Containers": {
+ "main": [
+ [
+ {
+ "node": "Resolve Container ID",
+ "type": "main",
+ "index": 0
+ }
+ ]
+ ]
+ },
+ "Resolve Container ID": {
"main": [
[
{