feat(03-03): build batch confirmation keyboard with inline buttons

- Replace placeholder 'Format Multiple Matches' with 'Build Batch Keyboard'
- Create inline_keyboard with 'Yes, <action> N containers' and 'Cancel' buttons
- Encode batch container IDs in callback_data (limit 4 for 64-byte constraint)
- Use HTTP Request for sendMessage (same pattern as suggestion flow)
- Format container list with bullet points in confirmation message
This commit is contained in:
Lucas Berger
2026-01-30 08:45:56 -05:00
parent c0451f8325
commit ab8d5282c0
+16 -17
View File
@@ -590,28 +590,27 @@
}, },
{ {
"parameters": { "parameters": {
"jsCode": "// Multiple containers matched - placeholder for confirmation flow (Plan 03-02)\nconst data = $input.item.json;\nconst names = data.matches.map(m => m.Name).join(', ');\nreturn {\n json: {\n chatId: data.chatId,\n text: `Found ${data.matchCount} containers matching '<b>${data.containerQuery}</b>': ${names}\\n\\nConfirmation required. (Coming in next update)`\n }\n};" "jsCode": "// Build batch confirmation keyboard for multiple matches\nconst matches = $json.matches;\nconst action = $json.action;\nconst chatId = $json.chatId;\nconst query = $json.containerQuery;\n\n// List matched container names\nconst names = matches.map(m => m.Name);\nconst shortIds = matches.map(m => m.Id.substring(0, 12));\n\n// Build callback_data - must be <=64 bytes\n// For batch: a=action code, c=array of short IDs, t=timestamp\nconst actionCode = action === 'start' ? 's' : action === 'stop' ? 't' : 'r';\nconst timestamp = Date.now();\n\n// Check size - if too many containers, callback_data might exceed 64 bytes\n// Each short ID is 12 chars, plus overhead. Max ~3-4 containers safely\nlet callbackData;\nlet limitedCount = shortIds.length;\nif (shortIds.length <= 4) {\n callbackData = JSON.stringify({ a: actionCode, c: shortIds, t: timestamp });\n} else {\n // Too many containers - limit to first 4\n callbackData = JSON.stringify({ a: actionCode, c: shortIds.slice(0, 4), t: timestamp });\n limitedCount = 4;\n}\n\n// Format container list\nconst listText = names.map(n => ` \\u2022 ${n}`).join('\\n');\n\n// Build action verb for button\nconst actionVerb = action.charAt(0).toUpperCase() + action.slice(1);\n\nreturn {\n json: {\n chat_id: chatId,\n text: `Found <b>${matches.length}</b> containers matching '<b>${query}</b>':\\n\\n${listText}\\n\\n${actionVerb} all?`,\n parse_mode: \"HTML\",\n reply_markup: {\n inline_keyboard: [\n [\n { text: `Yes, ${action} ${limitedCount} containers`, callback_data: callbackData },\n { text: \"Cancel\", callback_data: '{\"a\":\"x\"}' }\n ]\n ]\n },\n // Store metadata for summary\n _meta: {\n action,\n containers: matches,\n timestamp,\n limitedCount\n }\n }\n};"
}, },
"id": "code-multiple-matches", "id": "code-build-batch-keyboard",
"name": "Format Multiple Matches", "name": "Build Batch Keyboard",
"type": "n8n-nodes-base.code", "type": "n8n-nodes-base.code",
"typeVersion": 2, "typeVersion": 2,
"position": [1780, 500] "position": [1780, 500]
}, },
{ {
"parameters": { "parameters": {
"resource": "message", "method": "POST",
"operation": "sendMessage", "url": "=https://api.telegram.org/bot{{ $credentials.telegramApi.accessToken }}/sendMessage",
"chatId": "={{ $json.chatId }}", "sendBody": true,
"text": "={{ $json.text }}", "specifyBody": "json",
"additionalFields": { "jsonBody": "={{ JSON.stringify({ chat_id: $json.chat_id, text: $json.text, parse_mode: $json.parse_mode, reply_markup: $json.reply_markup }) }}",
"parse_mode": "HTML" "options": {}
}
}, },
"id": "telegram-send-multiple", "id": "http-send-batch-confirm",
"name": "Send Multiple Matches", "name": "Send Batch Confirmation",
"type": "n8n-nodes-base.telegram", "type": "n8n-nodes-base.httpRequest",
"typeVersion": 1.2, "typeVersion": 4.2,
"position": [2000, 500], "position": [2000, 500],
"credentials": { "credentials": {
"telegramApi": { "telegramApi": {
@@ -1234,7 +1233,7 @@
], ],
[ [
{ {
"node": "Format Multiple Matches", "node": "Build Batch Keyboard",
"type": "main", "type": "main",
"index": 0 "index": 0
} }
@@ -1315,11 +1314,11 @@
] ]
] ]
}, },
"Format Multiple Matches": { "Build Batch Keyboard": {
"main": [ "main": [
[ [
{ {
"node": "Send Multiple Matches", "node": "Send Batch Confirmation",
"type": "main", "type": "main",
"index": 0 "index": 0
} }