diff --git a/n8n-workflow.json b/n8n-workflow.json
index c9c86f1..075085c 100644
--- a/n8n-workflow.json
+++ b/n8n-workflow.json
@@ -2272,354 +2272,6 @@
}
}
},
- {
- "parameters": {
- "jsCode": "// Build Stop Confirmation dialog with timestamp for 30-second timeout\nconst data = $('Parse Callback Data').item.json;\nconst containerName = data.containerName;\nconst chatId = data.chatId;\nconst messageId = data.messageId;\nconst timestamp = Math.floor(Date.now() / 1000); // Unix timestamp\n\nconst keyboard = {\n inline_keyboard: [\n [\n { text: '\\u2705 Yes, Stop', callback_data: `confirm:stop:${containerName}:${timestamp}` },\n { text: '\\u274C Cancel', callback_data: `cancel:${containerName}` }\n ]\n ]\n};\n\nconst text = `\\u26A0\\uFE0F Stop ${containerName}?\\n\\nThis will stop the container immediately.\\n\\nConfirmation expires in 30 seconds.`;\n\nreturn {\n json: {\n chatId,\n messageId,\n text,\n reply_markup: keyboard\n }\n};"
- },
- "id": "code-build-stop-confirmation",
- "name": "Build Stop Confirmation",
- "type": "n8n-nodes-base.code",
- "typeVersion": 2,
- "position": [
- 1780,
- 1400
- ]
- },
- {
- "parameters": {
- "method": "POST",
- "url": "=https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN }}/editMessageText",
- "sendBody": true,
- "specifyBody": "json",
- "jsonBody": "={{ JSON.stringify({ chat_id: $json.chatId, message_id: $json.messageId, text: $json.text, parse_mode: 'HTML', reply_markup: $json.reply_markup }) }}",
- "options": {}
- },
- "id": "http-send-stop-confirmation",
- "name": "Send Stop Confirmation",
- "type": "n8n-nodes-base.httpRequest",
- "typeVersion": 4.2,
- "position": [
- 2000,
- 1400
- ],
- "credentials": {
- "telegramApi": {
- "id": "I0xTTiASl7C1NZhJ",
- "name": "Telegram account"
- }
- }
- },
- {
- "parameters": {
- "jsCode": "// Build Update Confirmation dialog with timestamp for 30-second timeout\nconst data = $('Parse Callback Data').item.json;\nconst containerName = data.containerName;\nconst chatId = data.chatId;\nconst messageId = data.messageId;\nconst timestamp = Math.floor(Date.now() / 1000); // Unix timestamp\n\nconst keyboard = {\n inline_keyboard: [\n [\n { text: '\\u2705 Yes, Update', callback_data: `confirm:update:${containerName}:${timestamp}` },\n { text: '\\u274C Cancel', callback_data: `cancel:${containerName}` }\n ]\n ]\n};\n\nconst text = `\\u26A0\\uFE0F Update ${containerName}?\\n\\nThis will pull the latest image and recreate the container.\\n\\nConfirmation expires in 30 seconds.`;\n\nreturn {\n json: {\n chatId,\n messageId,\n text,\n reply_markup: keyboard\n }\n};"
- },
- "id": "code-build-update-confirmation",
- "name": "Build Update Confirmation",
- "type": "n8n-nodes-base.code",
- "typeVersion": 2,
- "position": [
- 1780,
- 1500
- ]
- },
- {
- "parameters": {
- "method": "POST",
- "url": "=https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN }}/editMessageText",
- "sendBody": true,
- "specifyBody": "json",
- "jsonBody": "={{ JSON.stringify({ chat_id: $json.chatId, message_id: $json.messageId, text: $json.text, parse_mode: 'HTML', reply_markup: $json.reply_markup }) }}",
- "options": {}
- },
- "id": "http-send-update-confirmation",
- "name": "Send Update Confirmation",
- "type": "n8n-nodes-base.httpRequest",
- "typeVersion": 4.2,
- "position": [
- 2000,
- 1500
- ],
- "credentials": {
- "telegramApi": {
- "id": "I0xTTiASl7C1NZhJ",
- "name": "Telegram account"
- }
- }
- },
- {
- "parameters": {
- "method": "POST",
- "url": "=https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN }}/answerCallbackQuery",
- "sendBody": true,
- "specifyBody": "json",
- "jsonBody": "={{ JSON.stringify({ callback_query_id: $json.queryId }) }}",
- "options": {}
- },
- "id": "http-answer-confirm-callback",
- "name": "Answer Confirm Callback",
- "type": "n8n-nodes-base.httpRequest",
- "typeVersion": 4.2,
- "position": [
- 1340,
- 1600
- ],
- "credentials": {
- "telegramApi": {
- "id": "I0xTTiASl7C1NZhJ",
- "name": "Telegram account"
- }
- }
- },
- {
- "parameters": {
- "conditions": {
- "options": {
- "caseSensitive": true,
- "leftValue": "",
- "typeValidation": "strict"
- },
- "conditions": [
- {
- "id": "check-expired",
- "leftValue": "={{ $('Parse Callback Data').item.json.expired }}",
- "rightValue": true,
- "operator": {
- "type": "boolean",
- "operation": "equals"
- }
- }
- ],
- "combinator": "and"
- },
- "options": {}
- },
- "id": "if-confirm-expired",
- "name": "Check Confirm Expired",
- "type": "n8n-nodes-base.if",
- "typeVersion": 2,
- "position": [
- 1560,
- 1600
- ]
- },
- {
- "parameters": {
- "jsCode": "// Confirmation expired - return to submenu\nconst data = $('Parse Callback Data').item.json;\nconst containerName = data.containerName;\nconst chatId = data.chatId;\nconst messageId = data.messageId;\n\n// Build keyboard for expired message\nconst keyboard = {\n inline_keyboard: [\n [\n { text: '\\u25C0\\uFE0F Back to List', callback_data: 'list:0' }\n ]\n ]\n};\n\nreturn {\n json: {\n chatId,\n messageId,\n text: `\\u23F0 Confirmation for ${containerName} has expired.\\n\\nPlease try again.`,\n reply_markup: keyboard\n }\n};"
- },
- "id": "code-handle-confirm-expired",
- "name": "Handle Confirm Expired",
- "type": "n8n-nodes-base.code",
- "typeVersion": 2,
- "position": [
- 1780,
- 1700
- ]
- },
- {
- "parameters": {
- "method": "POST",
- "url": "=https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN }}/editMessageText",
- "sendBody": true,
- "specifyBody": "json",
- "jsonBody": "={{ JSON.stringify({ chat_id: $json.chatId, message_id: $json.messageId, text: $json.text, parse_mode: 'HTML', reply_markup: $json.reply_markup }) }}",
- "options": {}
- },
- "id": "http-send-expired-confirm",
- "name": "Send Expired Confirm",
- "type": "n8n-nodes-base.httpRequest",
- "typeVersion": 4.2,
- "position": [
- 2000,
- 1700
- ],
- "credentials": {
- "telegramApi": {
- "id": "I0xTTiASl7C1NZhJ",
- "name": "Telegram account"
- }
- }
- },
- {
- "parameters": {
- "rules": {
- "values": [
- {
- "id": "confirm-stop",
- "conditions": {
- "options": {
- "caseSensitive": true,
- "typeValidation": "loose"
- },
- "conditions": [
- {
- "id": "is-stop-confirm",
- "leftValue": "={{ $('Parse Callback Data').item.json.confirmAction }}",
- "rightValue": "stop",
- "operator": {
- "type": "string",
- "operation": "equals"
- }
- }
- ],
- "combinator": "and"
- },
- "renameOutput": true,
- "outputKey": "stop"
- },
- {
- "id": "confirm-update",
- "conditions": {
- "options": {
- "caseSensitive": true,
- "typeValidation": "loose"
- },
- "conditions": [
- {
- "id": "is-update-confirm",
- "leftValue": "={{ $('Parse Callback Data').item.json.confirmAction }}",
- "rightValue": "update",
- "operator": {
- "type": "string",
- "operation": "equals"
- }
- }
- ],
- "combinator": "and"
- },
- "renameOutput": true,
- "outputKey": "update"
- }
- ]
- },
- "options": {
- "fallbackOutput": "none"
- }
- },
- "id": "switch-route-confirm-action",
- "name": "Route Confirm Action",
- "type": "n8n-nodes-base.switch",
- "typeVersion": 3.2,
- "position": [
- 1780,
- 1600
- ]
- },
- {
- "parameters": {
- "jsCode": "// Prepare stop action from confirmation\nconst data = $('Parse Callback Data').item.json;\nreturn {\n json: {\n containerName: data.containerName,\n chatId: data.chatId,\n messageId: data.messageId\n }\n};"
- },
- "id": "code-prepare-confirmed-stop",
- "name": "Prepare Confirmed Stop",
- "type": "n8n-nodes-base.code",
- "typeVersion": 2,
- "position": [
- 2000,
- 1550
- ]
- },
- {
- "parameters": {
- "method": "GET",
- "url": "=http://docker-socket-proxy:2375/containers/json?all=true",
- "options": {}
- },
- "id": "http-get-container-for-stop",
- "name": "Get Container For Stop",
- "type": "n8n-nodes-base.httpRequest",
- "typeVersion": 4.2,
- "position": [
- 2220,
- 1550
- ]
- },
- {
- "parameters": {
- "jsCode": "// Find container and build stop command\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 \"${containerName}\" not found`\n }\n };\n}\n\nconst containerId = container.Id;\n\nreturn {\n json: {\n cmd: `curl -s -o /dev/null -w \"%{http_code}\" --max-time 15 -X POST 'http://docker-socket-proxy:2375/v1.47/containers/${containerId}/stop?t=10'`,\n containerId,\n containerName: normalizeName(container.Names[0]),\n chatId,\n messageId\n }\n};"
- },
- "id": "code-build-confirmed-stop-cmd",
- "name": "Build Confirmed Stop Command",
- "type": "n8n-nodes-base.code",
- "typeVersion": 2,
- "position": [
- 2440,
- 1550
- ]
- },
- {
- "parameters": {
- "command": "={{ $json.cmd }}",
- "options": {}
- },
- "id": "exec-confirmed-stop",
- "name": "Execute Confirmed Stop",
- "type": "n8n-nodes-base.executeCommand",
- "typeVersion": 1,
- "position": [
- 2660,
- 1550
- ]
- },
- {
- "parameters": {
- "jsCode": "// Build stop completion message (success shows back only, error shows retry + back)\nconst stdout = $input.item.json.stdout;\nconst prevData = $('Build Confirmed Stop Command').item.json;\nconst containerName = prevData.containerName;\nconst chatId = prevData.chatId;\nconst messageId = prevData.messageId;\n\nconst statusCode = parseInt(stdout.trim());\n\n// 204: Success, 304: Already stopped\nconst success = statusCode === 204 || statusCode === 304;\n\nlet text;\nlet keyboard;\n\nif (success) {\n text = `\\u23F9\\uFE0F ${containerName} stopped`;\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 text = `\\u274C Failed to stop ${containerName}`;\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,\n reply_markup: keyboard\n }\n};"
- },
- "id": "code-format-confirmed-stop-result",
- "name": "Format Confirmed Stop Result",
- "type": "n8n-nodes-base.code",
- "typeVersion": 2,
- "position": [
- 2880,
- 1550
- ]
- },
- {
- "parameters": {
- "method": "POST",
- "url": "=https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN }}/editMessageText",
- "sendBody": true,
- "specifyBody": "json",
- "jsonBody": "={{ JSON.stringify({ chat_id: $json.chatId, message_id: $json.messageId, text: $json.text, parse_mode: 'HTML', reply_markup: $json.reply_markup }) }}",
- "options": {}
- },
- "id": "http-send-confirmed-stop-result",
- "name": "Send Confirmed Stop Result",
- "type": "n8n-nodes-base.httpRequest",
- "typeVersion": 4.2,
- "position": [
- 3100,
- 1550
- ],
- "credentials": {
- "telegramApi": {
- "id": "I0xTTiASl7C1NZhJ",
- "name": "Telegram account"
- }
- }
- },
- {
- "parameters": {
- "method": "POST",
- "url": "=https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN }}/answerCallbackQuery",
- "sendBody": true,
- "specifyBody": "json",
- "jsonBody": "={{ JSON.stringify({ callback_query_id: $json.queryId }) }}",
- "options": {}
- },
- "id": "http-answer-cancel-confirm-callback",
- "name": "Answer Cancel Confirm Callback",
- "type": "n8n-nodes-base.httpRequest",
- "typeVersion": 4.2,
- "position": [
- 1340,
- 1800
- ],
- "credentials": {
- "telegramApi": {
- "id": "I0xTTiASl7C1NZhJ",
- "name": "Telegram account"
- }
- }
- },
{
"parameters": {
"jsCode": "// Cancel confirmation - return to container submenu\nconst data = $(\"Parse Callback Data\").item.json;\nreturn {\n json: {\n containerName: data.containerName,\n chatId: data.chatId,\n messageId: data.messageId\n }\n};"
@@ -4076,54 +3728,6 @@
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": {
- "__rl": true,
- "mode": "list",
- "value": "fYSZS5PkH0VSEaT5"
- },
- "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
- ]
- },
{
"parameters": {
"jsCode": "// Prepare input for Container Update sub-workflow\nconst data = $('Build Progress Message').item.json;\nconst container = data.container;\n\n// Extract container info\nconst containerId = container.id || container.Id || '';\nconst containerName = container.name || container.Name || '';\n\nreturn {\n json: {\n containerId: containerId,\n containerName: containerName,\n chatId: data.chatId,\n messageId: data.progressMessageId || 0,\n responseMode: \"inline\"\n }\n};"
@@ -4806,6 +4410,295 @@
1780,
1100
]
+ },
+ {
+ "parameters": {
+ "jsCode": "// Prepare input for confirmation sub-workflow\nconst data = $('Parse Callback Data').item.json;\n\n// Determine action based on callback type\nlet action = 'confirm'; // Default\nif (data.isCancelConfirm) {\n action = 'cancel';\n} else if (data.isConfirm && data.expired) {\n action = 'expired';\n} else if (data.isConfirm) {\n action = 'confirm';\n}\n\nreturn {\n json: {\n chatId: data.chatId,\n messageId: data.messageId,\n action: action,\n containerId: data.containerId || '',\n containerName: data.containerName,\n confirmAction: data.confirmAction || '',\n confirmationToken: data.timestamp || '',\n expired: data.expired || false,\n responseMode: 'inline'\n }\n};"
+ },
+ "id": "code-prepare-confirm-input",
+ "name": "Prepare Confirm Input",
+ "type": "n8n-nodes-base.code",
+ "typeVersion": 2,
+ "position": [
+ 1340,
+ 1550
+ ]
+ },
+ {
+ "parameters": {
+ "jsCode": "// Prepare input for showing stop confirmation dialog\nconst data = $('Parse Callback Data').item.json;\n\nreturn {\n json: {\n chatId: data.chatId,\n messageId: data.messageId,\n action: 'show_stop',\n containerId: data.containerId || '',\n containerName: data.containerName,\n responseMode: 'inline'\n }\n};"
+ },
+ "id": "code-prepare-show-stop",
+ "name": "Prepare Show Stop Input",
+ "type": "n8n-nodes-base.code",
+ "typeVersion": 2,
+ "position": [
+ 1780,
+ 1350
+ ]
+ },
+ {
+ "parameters": {
+ "jsCode": "// Prepare input for showing update confirmation dialog\nconst data = $('Parse Callback Data').item.json;\n\nreturn {\n json: {\n chatId: data.chatId,\n messageId: data.messageId,\n action: 'show_update',\n containerId: data.containerId || '',\n containerName: data.containerName,\n responseMode: 'inline'\n }\n};"
+ },
+ "id": "code-prepare-show-update",
+ "name": "Prepare Show Update Input",
+ "type": "n8n-nodes-base.code",
+ "typeVersion": 2,
+ "position": [
+ 1780,
+ 1450
+ ]
+ },
+ {
+ "parameters": {
+ "source": "database",
+ "workflowId": {
+ "__rl": true,
+ "mode": "id",
+ "value": "TODO_DEPLOY_CONFIRMATION_WORKFLOW"
+ },
+ "mode": "once",
+ "options": {
+ "waitForSubWorkflow": true
+ }
+ },
+ "id": "exec-confirmation-workflow",
+ "name": "Execute Confirmation",
+ "type": "n8n-nodes-base.executeWorkflow",
+ "typeVersion": 1.2,
+ "position": [
+ 2000,
+ 1500
+ ]
+ },
+ {
+ "parameters": {
+ "rules": {
+ "values": [
+ {
+ "id": "show-dialog",
+ "conditions": {
+ "options": {
+ "caseSensitive": true,
+ "typeValidation": "loose"
+ },
+ "conditions": [
+ {
+ "id": "is-show",
+ "leftValue": "={{ $json.action }}",
+ "rightValue": "show_",
+ "operator": {
+ "type": "string",
+ "operation": "startsWith"
+ }
+ }
+ ],
+ "combinator": "and"
+ },
+ "renameOutput": true,
+ "outputKey": "show"
+ },
+ {
+ "id": "confirm-stop-result",
+ "conditions": {
+ "options": {
+ "caseSensitive": true,
+ "typeValidation": "loose"
+ },
+ "conditions": [
+ {
+ "id": "is-stop-result",
+ "leftValue": "={{ $json.action }}",
+ "rightValue": "confirm_stop_result",
+ "operator": {
+ "type": "string",
+ "operation": "equals"
+ }
+ }
+ ],
+ "combinator": "and"
+ },
+ "renameOutput": true,
+ "outputKey": "stop_result"
+ },
+ {
+ "id": "confirm-update",
+ "conditions": {
+ "options": {
+ "caseSensitive": true,
+ "typeValidation": "loose"
+ },
+ "conditions": [
+ {
+ "id": "is-confirm-update",
+ "leftValue": "={{ $json.action }}",
+ "rightValue": "confirm_update",
+ "operator": {
+ "type": "string",
+ "operation": "equals"
+ }
+ }
+ ],
+ "combinator": "and"
+ },
+ "renameOutput": true,
+ "outputKey": "confirm_update"
+ },
+ {
+ "id": "cancel",
+ "conditions": {
+ "options": {
+ "caseSensitive": true,
+ "typeValidation": "loose"
+ },
+ "conditions": [
+ {
+ "id": "is-cancel",
+ "leftValue": "={{ $json.action }}",
+ "rightValue": "cancel",
+ "operator": {
+ "type": "string",
+ "operation": "equals"
+ }
+ }
+ ],
+ "combinator": "and"
+ },
+ "renameOutput": true,
+ "outputKey": "cancel"
+ },
+ {
+ "id": "expired",
+ "conditions": {
+ "options": {
+ "caseSensitive": true,
+ "typeValidation": "loose"
+ },
+ "conditions": [
+ {
+ "id": "is-expired",
+ "leftValue": "={{ $json.action }}",
+ "rightValue": "expired",
+ "operator": {
+ "type": "string",
+ "operation": "equals"
+ }
+ }
+ ],
+ "combinator": "and"
+ },
+ "renameOutput": true,
+ "outputKey": "expired"
+ }
+ ]
+ },
+ "options": {
+ "fallbackOutput": "none"
+ }
+ },
+ "id": "switch-confirm-result",
+ "name": "Route Confirmation Result",
+ "type": "n8n-nodes-base.switch",
+ "typeVersion": 3.2,
+ "position": [
+ 2220,
+ 1500
+ ]
+ },
+ {
+ "parameters": {
+ "operation": "editMessageText",
+ "messageId": "={{ $json.messageId }}",
+ "chatId": "={{ $json.chatId }}",
+ "text": "={{ $json.text }}",
+ "replyMarkup": "inlineKeyboard",
+ "inlineKeyboard": "={{ JSON.stringify($json.reply_markup) }}",
+ "additionalFields": {
+ "parse_mode": "HTML"
+ }
+ },
+ "id": "http-send-confirm-dialog",
+ "name": "Send Confirmation Dialog",
+ "type": "n8n-nodes-base.telegram",
+ "typeVersion": 1.2,
+ "position": [
+ 2440,
+ 1400
+ ],
+ "credentials": {
+ "telegramApi": {
+ "id": "I0xTTiASl7C1NZhJ",
+ "name": "Telegram account"
+ }
+ }
+ },
+ {
+ "parameters": {
+ "operation": "editMessageText",
+ "messageId": "={{ $json.messageId }}",
+ "chatId": "={{ $json.chatId }}",
+ "text": "={{ $json.text }}",
+ "replyMarkup": "inlineKeyboard",
+ "inlineKeyboard": "={{ JSON.stringify($json.reply_markup) }}",
+ "additionalFields": {
+ "parse_mode": "HTML"
+ }
+ },
+ "id": "http-send-stop-result",
+ "name": "Send Stop Result",
+ "type": "n8n-nodes-base.telegram",
+ "typeVersion": 1.2,
+ "position": [
+ 2440,
+ 1500
+ ],
+ "credentials": {
+ "telegramApi": {
+ "id": "I0xTTiASl7C1NZhJ",
+ "name": "Telegram account"
+ }
+ }
+ },
+ {
+ "parameters": {
+ "operation": "editMessageText",
+ "messageId": "={{ $json.messageId }}",
+ "chatId": "={{ $json.chatId }}",
+ "text": "={{ $json.text }}",
+ "replyMarkup": "inlineKeyboard",
+ "inlineKeyboard": "={{ JSON.stringify($json.reply_markup) }}",
+ "additionalFields": {
+ "parse_mode": "HTML"
+ }
+ },
+ "id": "http-send-expired-msg",
+ "name": "Send Expired Message",
+ "type": "n8n-nodes-base.telegram",
+ "typeVersion": 1.2,
+ "position": [
+ 2440,
+ 1700
+ ],
+ "credentials": {
+ "telegramApi": {
+ "id": "I0xTTiASl7C1NZhJ",
+ "name": "Telegram account"
+ }
+ }
+ },
+ {
+ "parameters": {
+ "jsCode": "// Prepare cancel return data from confirmation result\nconst result = $input.item.json;\n\nreturn {\n json: {\n containerName: result.containerName,\n chatId: result.chatId,\n messageId: result.messageId\n }\n};"
+ },
+ "id": "code-prepare-cancel-from-confirm",
+ "name": "Prepare Cancel From Confirm",
+ "type": "n8n-nodes-base.code",
+ "typeVersion": 2,
+ "position": [
+ 2440,
+ 1600
+ ]
}
],
"connections": {
@@ -4929,23 +4822,17 @@
"index": 0
}
],
+ [],
[
{
- "node": "Answer Confirm Callback",
+ "node": "Prepare Confirm Input",
"type": "main",
"index": 0
}
],
[
{
- "node": "Answer Cancel Confirm Callback",
- "type": "main",
- "index": 0
- }
- ],
- [
- {
- "node": "Answer Batch Stop Confirm",
+ "node": "Prepare Confirm Input",
"type": "main",
"index": 0
}
@@ -5660,14 +5547,14 @@
],
[
{
- "node": "Build Stop Confirmation",
+ "node": "Prepare Show Stop Input",
"type": "main",
"index": 0
}
],
[
{
- "node": "Build Update Confirmation",
+ "node": "Prepare Show Update Input",
"type": "main",
"index": 0
}
@@ -5736,152 +5623,6 @@
]
]
},
- "Build Stop Confirmation": {
- "main": [
- [
- {
- "node": "Send Stop Confirmation",
- "type": "main",
- "index": 0
- }
- ]
- ]
- },
- "Build Update Confirmation": {
- "main": [
- [
- {
- "node": "Send Update Confirmation",
- "type": "main",
- "index": 0
- }
- ]
- ]
- },
- "Answer Confirm Callback": {
- "main": [
- [
- {
- "node": "Check Confirm Expired",
- "type": "main",
- "index": 0
- }
- ]
- ]
- },
- "Check Confirm Expired": {
- "main": [
- [
- {
- "node": "Handle Confirm Expired",
- "type": "main",
- "index": 0
- }
- ],
- [
- {
- "node": "Route Confirm Action",
- "type": "main",
- "index": 0
- }
- ]
- ]
- },
- "Handle Confirm Expired": {
- "main": [
- [
- {
- "node": "Send Expired Confirm",
- "type": "main",
- "index": 0
- }
- ]
- ]
- },
- "Route Confirm Action": {
- "main": [
- [
- {
- "node": "Prepare Confirmed Stop",
- "type": "main",
- "index": 0
- }
- ],
- [
- {
- "node": "Prepare Callback Update Input",
- "type": "main",
- "index": 0
- }
- ]
- ]
- },
- "Prepare Confirmed Stop": {
- "main": [
- [
- {
- "node": "Get Container For Stop",
- "type": "main",
- "index": 0
- }
- ]
- ]
- },
- "Get Container For Stop": {
- "main": [
- [
- {
- "node": "Prepare Confirmed Stop Input",
- "type": "main",
- "index": 0
- }
- ]
- ]
- },
- "Build Confirmed Stop Command": {
- "main": [
- [
- {
- "node": "Execute Confirmed Stop",
- "type": "main",
- "index": 0
- }
- ]
- ]
- },
- "Execute Confirmed Stop": {
- "main": [
- [
- {
- "node": "Format Confirmed Stop Result",
- "type": "main",
- "index": 0
- }
- ]
- ]
- },
- "Format Confirmed Stop Result": {
- "main": [
- [
- {
- "node": "Send Confirmed Stop Result",
- "type": "main",
- "index": 0
- }
- ]
- ]
- },
- "Answer Cancel Confirm Callback": {
- "main": [
- [
- {
- "node": "Prepare Cancel Return",
- "type": "main",
- "index": 0
- }
- ]
- ]
- },
"Prepare Cancel Return": {
"main": [
[
@@ -6331,39 +6072,6 @@
]
]
},
- "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
- }
- ]
- ]
- },
"Prepare Batch Update Input": {
"main": [
[
@@ -6602,33 +6310,7 @@
]
},
"Route Status Result": {
- "list": [
- [
- {
- "node": "Send Container List",
- "type": "main",
- "index": 0
- }
- ]
- ],
- "status_direct": [
- [
- {
- "node": "Send Container Submenu Direct",
- "type": "main",
- "index": 0
- }
- ]
- ],
- "error": [
- [
- {
- "node": "Send Container List",
- "type": "main",
- "index": 0
- }
- ]
- ]
+ "main": []
},
"Answer Select Callback": {
"main": [
@@ -6728,6 +6410,100 @@
}
]
]
+ },
+ "Prepare Confirm Input": {
+ "main": [
+ [
+ {
+ "node": "Execute Confirmation",
+ "type": "main",
+ "index": 0
+ }
+ ]
+ ]
+ },
+ "Prepare Show Stop Input": {
+ "main": [
+ [
+ {
+ "node": "Execute Confirmation",
+ "type": "main",
+ "index": 0
+ }
+ ]
+ ]
+ },
+ "Prepare Show Update Input": {
+ "main": [
+ [
+ {
+ "node": "Execute Confirmation",
+ "type": "main",
+ "index": 0
+ }
+ ]
+ ]
+ },
+ "Execute Confirmation": {
+ "main": [
+ [
+ {
+ "node": "Route Confirmation Result",
+ "type": "main",
+ "index": 0
+ }
+ ]
+ ]
+ },
+ "Route Confirmation Result": {
+ "main": [
+ [
+ {
+ "node": "Send Confirmation Dialog",
+ "type": "main",
+ "index": 0
+ }
+ ],
+ [
+ {
+ "node": "Send Stop Result",
+ "type": "main",
+ "index": 0
+ }
+ ],
+ [
+ {
+ "node": "Prepare Callback Update Input",
+ "type": "main",
+ "index": 0
+ }
+ ],
+ [
+ {
+ "node": "Prepare Cancel From Confirm",
+ "type": "main",
+ "index": 0
+ }
+ ],
+ [
+ {
+ "node": "Send Expired Message",
+ "type": "main",
+ "index": 0
+ }
+ ]
+ ]
+ },
+ "Prepare Cancel From Confirm": {
+ "main": [
+ [
+ {
+ "node": "Get Container For Cancel",
+ "type": "main",
+ "index": 0
+ }
+ ]
+ ]
}
},
"pinData": {},