feat(10-03): wire main workflow to use container-actions sub-workflow
- Added 9 nodes for sub-workflow integration - Text path: Check Match Count -> Prepare Text Action Input -> Execute Container Action - Inline path: Get Container For Action -> Prepare Inline Action Input -> Execute Inline Action - Confirmed stop: Get Container For Stop -> Prepare Confirmed Stop Input -> Execute Confirmed Stop Action - Confirmation dialogs remain in main workflow (stop, batch stop) - Uses CONTAINER_ACTIONS_WORKFLOW_ID env var for sub-workflow reference
This commit is contained in:
+234
-3
@@ -5042,6 +5042,138 @@
|
||||
2880,
|
||||
1650
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "// Prepare input for container actions sub-workflow\nconst data = $input.item.json;\nconst containerId = data.matches[0].Id;\nconst containerName = data.matches[0].Name;\nconst action = data.action;\nconst chatId = data.chatId;\n\nreturn {\n json: {\n containerId: containerId,\n containerName: containerName,\n action: action,\n chatId: chatId,\n messageId: 0, // Text mode doesn't have a message to edit\n responseMode: 'text'\n }\n};"
|
||||
},
|
||||
"id": "code-prepare-text-action-rr53pd94",
|
||||
"name": "Prepare Text Action Input",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
1780,
|
||||
500
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"source": "database",
|
||||
"workflowId": "={{ $env.CONTAINER_ACTIONS_WORKFLOW_ID }}",
|
||||
"mode": "once",
|
||||
"options": {
|
||||
"waitForSubWorkflow": true
|
||||
}
|
||||
},
|
||||
"id": "exec-container-action-qokchnw8",
|
||||
"name": "Execute Container Action",
|
||||
"type": "n8n-nodes-base.executeWorkflow",
|
||||
"typeVersion": 1.2,
|
||||
"position": [
|
||||
2000,
|
||||
500
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "// Handle sub-workflow result for text command path\nconst result = $input.item.json;\nconst success = result.success;\nconst message = result.message;\nconst chatId = result.chatId;\n\nreturn {\n json: {\n success: success,\n chatId: chatId,\n text: message\n }\n};"
|
||||
},
|
||||
"id": "code-handle-text-result-c6ha90fh",
|
||||
"name": "Handle Text Action Result",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
2220,
|
||||
500
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "// Prepare input for container actions sub-workflow from inline keyboard\n// Container lookup already done by Get Container For Action\nconst containers = $input.all().map(item => item.json);\nconst prevData = $('Prepare Immediate Action').item.json;\nconst containerName = prevData.containerName.toLowerCase();\nconst action = prevData.action;\nconst chatId = prevData.chatId;\nconst messageId = prevData.messageId;\n\n// Function to normalize container names\nfunction normalizeName(name) {\n return name\n .replace(/^\\//, '')\n .replace(/^(linuxserver[-_]|binhex[-_])/i, '')\n .toLowerCase();\n}\n\n// Find the matching container\nconst container = containers.find(c => normalizeName(c.Names[0]) === containerName);\n\nif (!container) {\n return {\n json: {\n error: true,\n chatId,\n messageId,\n text: 'Container not found'\n }\n };\n}\n\nreturn {\n json: {\n containerId: container.Id,\n containerName: normalizeName(container.Names[0]),\n action: action,\n chatId: chatId,\n messageId: messageId,\n responseMode: 'inline'\n }\n};"
|
||||
},
|
||||
"id": "code-prepare-inline-action-tyjn5pb1",
|
||||
"name": "Prepare Inline Action Input",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
2220,
|
||||
1200
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"source": "database",
|
||||
"workflowId": "={{ $env.CONTAINER_ACTIONS_WORKFLOW_ID }}",
|
||||
"mode": "once",
|
||||
"options": {
|
||||
"waitForSubWorkflow": true
|
||||
}
|
||||
},
|
||||
"id": "exec-inline-action-8aoev7xt",
|
||||
"name": "Execute Inline Action",
|
||||
"type": "n8n-nodes-base.executeWorkflow",
|
||||
"typeVersion": 1.2,
|
||||
"position": [
|
||||
2440,
|
||||
1200
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "// Handle sub-workflow result for inline keyboard path\nconst result = $input.item.json;\nconst success = result.success;\nconst message = result.message;\nconst action = result.action;\nconst containerName = result.containerName;\nconst chatId = result.chatId;\nconst messageId = result.messageId;\n\n// Build keyboard based on result\nlet keyboard;\nif (success) {\n // Success: only back button\n keyboard = {\n inline_keyboard: [\n [{ text: '\\u25C0\\uFE0F Back to Containers', callback_data: 'list:0' }]\n ]\n };\n} else {\n // Error: retry and back buttons\n keyboard = {\n inline_keyboard: [\n [{ text: '\\u{1F504} Try Again', callback_data: 'action:' + action + ':' + containerName }],\n [{ text: '\\u25C0\\uFE0F Back to Containers', callback_data: 'list:0' }]\n ]\n };\n}\n\nreturn {\n json: {\n chatId,\n messageId,\n text: message,\n reply_markup: keyboard\n }\n};"
|
||||
},
|
||||
"id": "code-handle-inline-result-x19h97t3",
|
||||
"name": "Handle Inline Action Result",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
2660,
|
||||
1200
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "// Prepare input for container actions sub-workflow from confirmed stop\nconst containers = $input.all().map(item => item.json);\nconst prevData = $('Prepare Confirmed Stop').item.json;\nconst containerName = prevData.containerName.toLowerCase();\nconst chatId = prevData.chatId;\nconst messageId = prevData.messageId;\n\n// Function to normalize container names\nfunction normalizeName(name) {\n return name\n .replace(/^\\//, '')\n .replace(/^(linuxserver[-_]|binhex[-_])/i, '')\n .toLowerCase();\n}\n\n// Find the matching container\nconst container = containers.find(c => normalizeName(c.Names[0]) === containerName);\n\nif (!container) {\n return {\n json: {\n error: true,\n chatId,\n messageId,\n text: 'Container not found'\n }\n };\n}\n\nreturn {\n json: {\n containerId: container.Id,\n containerName: normalizeName(container.Names[0]),\n action: 'stop',\n chatId: chatId,\n messageId: messageId,\n responseMode: 'inline'\n }\n};"
|
||||
},
|
||||
"id": "code-prepare-confirmed-stop-vt9cw9tl",
|
||||
"name": "Prepare Confirmed Stop Input",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
2440,
|
||||
1650
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"source": "database",
|
||||
"workflowId": "={{ $env.CONTAINER_ACTIONS_WORKFLOW_ID }}",
|
||||
"mode": "once",
|
||||
"options": {
|
||||
"waitForSubWorkflow": true
|
||||
}
|
||||
},
|
||||
"id": "exec-confirmed-stop-sub-qmm011fk",
|
||||
"name": "Execute Confirmed Stop Action",
|
||||
"type": "n8n-nodes-base.executeWorkflow",
|
||||
"typeVersion": 1.2,
|
||||
"position": [
|
||||
2660,
|
||||
1650
|
||||
]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"jsCode": "// Handle sub-workflow result for confirmed stop path\nconst result = $input.item.json;\nconst success = result.success;\nconst message = result.message;\nconst containerName = result.containerName;\nconst chatId = result.chatId;\nconst messageId = result.messageId;\n\n// Build keyboard based on result\nlet keyboard;\nif (success) {\n // Success: only back button\n keyboard = {\n inline_keyboard: [\n [{ text: '\\u25C0\\uFE0F Back to Containers', callback_data: 'list:0' }]\n ]\n };\n} else {\n // Error: retry and back buttons\n const timestamp = Math.floor(Date.now() / 1000);\n keyboard = {\n inline_keyboard: [\n [{ text: '\\u{1F504} Try Again', callback_data: 'confirm:stop:' + containerName + ':' + timestamp }],\n [{ text: '\\u25C0\\uFE0F Back to Containers', callback_data: 'list:0' }]\n ]\n };\n}\n\nreturn {\n json: {\n chatId,\n messageId,\n text: message,\n reply_markup: keyboard\n }\n};"
|
||||
},
|
||||
"id": "code-handle-confirmed-stop-f2r86fwr",
|
||||
"name": "Handle Confirmed Stop Result",
|
||||
"type": "n8n-nodes-base.code",
|
||||
"typeVersion": 2,
|
||||
"position": [
|
||||
2880,
|
||||
1650
|
||||
]
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
@@ -5531,7 +5663,7 @@
|
||||
],
|
||||
[
|
||||
{
|
||||
"node": "Build Action Command",
|
||||
"node": "Prepare Text Action Input",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
@@ -6268,7 +6400,7 @@
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Build Immediate Action Command",
|
||||
"node": "Prepare Inline Action Input",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
@@ -6458,7 +6590,7 @@
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Build Confirmed Stop Command",
|
||||
"node": "Prepare Confirmed Stop Input",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
@@ -7197,6 +7329,105 @@
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Prepare Text Action Input": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Execute Container Action",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Execute Container Action": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Handle Text Action Result",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Handle Text Action Result": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Send Action Result",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Prepare Inline Action Input": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Execute Inline Action",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Execute Inline Action": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Handle Inline Action Result",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Handle Inline Action Result": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Send Immediate Result",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Prepare Confirmed Stop Input": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Execute Confirmed Stop Action",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Execute Confirmed Stop Action": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Handle Confirmed Stop Result",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Handle Confirmed Stop Result": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Send Confirmed Stop Result",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"pinData": {},
|
||||
|
||||
Reference in New Issue
Block a user