feat(09-01): add batch command detection and parsing
- Add "Detect Batch Command" code node to parse multi-container commands
- Add "Is Batch Command" IF node to route batch vs single container
- Add "Route Single Action" switch to route single commands to appropriate flow
- Add "Get Containers for Batch" node for Docker API container list
- Modify Keyword Router to route restart/start/stop/update through batch detection
- Single container commands route to existing Parse Action/Update Command flows
- Batch commands (2+ containers) route to new batch processing flow
Batch detection logic:
- Pattern: {action} {name1} {name2} ... where action is update/start/stop/restart
- Single container = not batch (existing flow)
- Two or more containers = batch (new flow)
This commit is contained in:
+175
-4
@@ -3800,6 +3800,130 @@
|
|||||||
"name": "Telegram account"
|
"name": "Telegram account"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"jsCode": "// Detect if this is a batch command (multiple container names)\n// Batch commands: {action} {name1} {name2} ... where action is update/start/stop/restart\nconst message = $json.message;\nconst text = message.text.toLowerCase().trim();\nconst chatId = message.chat.id;\nconst messageId = message.message_id;\n\n// Determine action type from the routed keyword\n// This node receives from Keyword Router which already matched the action\nlet action = null;\nlet containerPart = '';\n\nif (text.startsWith('restart ')) {\n action = 'restart';\n containerPart = text.substring(8).trim();\n} else if (text.includes('restart')) {\n action = 'restart';\n containerPart = text.replace('restart', '').trim();\n} else if (text.startsWith('start ')) {\n action = 'start';\n containerPart = text.substring(6).trim();\n} else if (text.includes('start')) {\n action = 'start';\n containerPart = text.replace('start', '').trim();\n} else if (text.startsWith('stop ')) {\n action = 'stop';\n containerPart = text.substring(5).trim();\n} else if (text.includes('stop')) {\n action = 'stop';\n containerPart = text.replace('stop', '').trim();\n} else if (text.startsWith('update ')) {\n action = 'update';\n containerPart = text.substring(7).trim();\n} else if (text.includes('update')) {\n action = 'update';\n containerPart = text.replace('update', '').trim();\n}\n\nif (!action || !containerPart) {\n // No valid action found, pass through as non-batch (will be handled by existing flow)\n return {\n json: {\n isBatch: false,\n action: action,\n containerNames: [],\n originalMessage: text,\n chatId: chatId,\n messageId: messageId,\n message: message\n }\n };\n}\n\n// Split container names by whitespace\nconst containerNames = containerPart.split(/\\s+/).filter(name => name.length > 0);\n\n// Batch = 2 or more containers\nconst isBatch = containerNames.length >= 2;\n\nreturn {\n json: {\n isBatch: isBatch,\n action: action,\n containerNames: containerNames,\n originalMessage: text,\n chatId: chatId,\n messageId: messageId,\n message: message\n }\n};"
|
||||||
|
},
|
||||||
|
"id": "code-detect-batch",
|
||||||
|
"name": "Detect Batch Command",
|
||||||
|
"type": "n8n-nodes-base.code",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
900,
|
||||||
|
-200
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"conditions": {
|
||||||
|
"options": {
|
||||||
|
"caseSensitive": true,
|
||||||
|
"leftValue": "",
|
||||||
|
"typeValidation": "strict"
|
||||||
|
},
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"id": "is-batch-check",
|
||||||
|
"leftValue": "={{ $json.isBatch }}",
|
||||||
|
"rightValue": true,
|
||||||
|
"operator": {
|
||||||
|
"type": "boolean",
|
||||||
|
"operation": "equals"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"combinator": "and"
|
||||||
|
},
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"id": "if-is-batch",
|
||||||
|
"name": "Is Batch Command",
|
||||||
|
"type": "n8n-nodes-base.if",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
1120,
|
||||||
|
-200
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"rules": {
|
||||||
|
"values": [
|
||||||
|
{
|
||||||
|
"id": "action-start-stop-restart",
|
||||||
|
"conditions": {
|
||||||
|
"options": {
|
||||||
|
"caseSensitive": true,
|
||||||
|
"typeValidation": "loose"
|
||||||
|
},
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"id": "is-action-type",
|
||||||
|
"leftValue": "={{ $json.action }}",
|
||||||
|
"rightValue": "update",
|
||||||
|
"operator": {
|
||||||
|
"type": "string",
|
||||||
|
"operation": "notEquals"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"combinator": "and"
|
||||||
|
},
|
||||||
|
"renameOutput": true,
|
||||||
|
"outputKey": "action"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "action-update",
|
||||||
|
"conditions": {
|
||||||
|
"options": {
|
||||||
|
"caseSensitive": true,
|
||||||
|
"typeValidation": "loose"
|
||||||
|
},
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"id": "is-update-type",
|
||||||
|
"leftValue": "={{ $json.action }}",
|
||||||
|
"rightValue": "update",
|
||||||
|
"operator": {
|
||||||
|
"type": "string",
|
||||||
|
"operation": "equals"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"combinator": "and"
|
||||||
|
},
|
||||||
|
"renameOutput": true,
|
||||||
|
"outputKey": "update"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"fallbackOutput": "none"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": "switch-route-single-action",
|
||||||
|
"name": "Route Single Action",
|
||||||
|
"type": "n8n-nodes-base.switch",
|
||||||
|
"typeVersion": 3.2,
|
||||||
|
"position": [
|
||||||
|
1340,
|
||||||
|
-100
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"command": "curl -s --max-time 5 'http://docker-socket-proxy:2375/v1.47/containers/json?all=true'",
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"id": "exec-docker-list-batch",
|
||||||
|
"name": "Get Containers for Batch",
|
||||||
|
"type": "n8n-nodes-base.executeCommand",
|
||||||
|
"typeVersion": 1,
|
||||||
|
"position": [
|
||||||
|
1340,
|
||||||
|
-300
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"connections": {
|
"connections": {
|
||||||
@@ -4921,28 +5045,28 @@
|
|||||||
],
|
],
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"node": "Parse Action Command",
|
"node": "Detect Batch Command",
|
||||||
"type": "main",
|
"type": "main",
|
||||||
"index": 0
|
"index": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"node": "Parse Action Command",
|
"node": "Detect Batch Command",
|
||||||
"type": "main",
|
"type": "main",
|
||||||
"index": 0
|
"index": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"node": "Parse Action Command",
|
"node": "Detect Batch Command",
|
||||||
"type": "main",
|
"type": "main",
|
||||||
"index": 0
|
"index": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"node": "Parse Update Command",
|
"node": "Detect Batch Command",
|
||||||
"type": "main",
|
"type": "main",
|
||||||
"index": 0
|
"index": 0
|
||||||
}
|
}
|
||||||
@@ -4963,6 +5087,53 @@
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"Detect Batch Command": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Is Batch Command",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Is Batch Command": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Get Containers for Batch",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Route Single Action",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Route Single Action": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Parse Action Command",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Parse Update Command",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
"Parse Action Command": {
|
"Parse Action Command": {
|
||||||
"main": [
|
"main": [
|
||||||
[
|
[
|
||||||
|
|||||||
Reference in New Issue
Block a user