The n8n Telegram node's inlineKeyboard parameter doesn't work reliably
with editMessageText operation. Switched to HTTP Request node calling
Telegram API directly, which properly passes reply_markup.
Changed nodes:
- Send Confirmation Dialog
- Send Stop Result
- Send Expired Message
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The n8n Telegram node's inlineKeyboard parameter expects the keyboard
rows array directly, not the full {inline_keyboard: [...]} object.
Fixed nodes:
- Send Confirmation Dialog
- Send Stop Result
- Send Expired Message
Changed from: JSON.stringify($json.reply_markup)
Changed to: JSON.stringify($json.reply_markup.inline_keyboard)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The batch rule was added at index 4 but connections weren't updated,
causing all subsequent rules to route to wrong handlers:
- select → Answer List Callback (wrong)
- list → Answer Action Callback (wrong)
- action → Answer Noop Callback (wrong)
- noop → nothing (missing)
Fixed by correcting outputs 5-8 to connect to proper handlers.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Execute Workflow nodes need mode: "once" to properly pass input
data to sub-workflows. Added to:
- Execute Container Status
- Execute Select Status
- Execute Paginate Status
- Execute Batch Cancel Status
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Route Status Result had no outgoing connections after status
sub-workflow extraction. Added connections:
- list output → Send Container List
- status_direct output → Edit Container List
- error output → Send Docker Error
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replaced TODO placeholders with actual n8n workflow IDs:
- Batch UI: ZJhnGzJT26UUmW45
- Container Status: lqpg2CqesnKE2RJQ
- Confirmation Dialogs: fZ1hu8eiovkCk08G
- Updated instructions.md with new workflow IDs and renamed files
- All workflows deployed and activated in n8n
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Skip Delete Batch Select Message node for batch start
- Use editMessageText instead of sendMessage
- Batch start now smoothly transitions like batch stop
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changed batch start to editMessageText so the confirmation message
gets updated with progress/results instead of leaving it hanging
and sending a separate progress message.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Format Inline Logs Result now adds timestamp to message
- Shows 'Updated: HH:MM:SS' at bottom of logs display
- Ensures Telegram API always accepts refresh (content always different)
- Send Logs Response now uses Prepare Text Logs Input for chatId
- Container logs sub-workflow uses .includes() for fuzzy matching
- Multiple match handling added with helpful error message
- Remove parallel Send Text Update Started connection
- Text updates now only send result via sub-workflow
- Fixes duplicate message issue (Updating... + already up to date)
- Update Build Batch Keyboard to use bexec: format instead of legacy JSON
- Update Build Suggestion Keyboard to use action: format instead of legacy JSON
- Remove 7 nodes from old batch inline execution path:
- Build Batch Commands
- Prepare Batch Execution
- Execute Batch Action
- Parse Batch Result
- Format Batch Result
- Send Batch Result
- Answer Batch Query
Node count: 199 -> 192 (-7 nodes)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Deploy Container Logs sub-workflow to n8n (ID: oE7aO2GhbksXDEIw)
- Replace TODO_DEPLOY_LOGS_WORKFLOW with actual workflow ID
- Update n8n-container-logs.json with deployed ID
- Redeploy all workflows to n8n
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace PLACEHOLDER_LOGS_ID with TODO_DEPLOY_LOGS_WORKFLOW
- Applies to Execute Text Logs and Execute Inline Logs nodes
- Clear marker indicates n8n-container-logs.json deployment required
- User must replace TODO with actual workflow ID after n8n import
- Add Prepare Batch Update Input node to format sub-workflow input
- Add Execute Batch Update node calling Container Update sub-workflow
- Add Handle Batch Update Result node to process results
- Connect update path (output 0) in Route Batch Loop Action
- Node count: 209 -> 212 (+3)
This completes the batch update integration with the modular sub-workflow,
eliminating the need for duplicate update logic in the main workflow.
n8n typeVersion 1.2 requires workflowId as resource locator object:
{ "__rl": true, "mode": "list", "value": "<id>" }
not a plain string. This was causing "workflow not found" errors.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Recreated Container Actions sub-workflow via API to fix
"workflow not found" error. New ID: fYSZS5PkH0VSEaT5
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Removed 54 duplicate update nodes from text and callback paths
- Added Execute Sub-workflow nodes for both update entry points
- Text path: Check Update Match Count -> Prepare Text Update Input -> Execute Text Update
- Callback path: Route Confirm Action -> Prepare Callback Update Input -> Execute Callback Update
- Workflow reduced from 246 to 200 nodes (-19%)
- Line count reduced from ~8485 to 7209 (-15%)
DEBT-03 (duplicated update flow) resolved - update logic now in one place
Cleaned up orphan nodes before modularization:
- Removed "Answer Batch Exec" (httpRequest at [1340, 900])
- Removed "Batch Loop" (splitInBatches at [3100, -500])
Both nodes had no incoming connections and were vestigial
from earlier batch operation development that was replaced.
Node count: 248 -> 246
Deployed and verified working via n8n API.
- Added missing connection for "update" rule (index 6)
- This shifted "logs" to correct index 7
- Both text-based update and logs commands now work
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add :kb marker to inline keyboard stop confirmation callback
- Parse Callback Data detects :kb and sets fromKeyboard: true
- Prepare Batch Stop Exec passes fromKeyboard through to batch state
- Summary now correctly shows Back to List for keyboard flows only
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Track fromKeyboard in batch state (true for callbacks, false for text)
- Pass fromKeyboard through entire batch loop chain
- Build Batch Summary only includes Back to List when fromKeyboard=true
- Send Batch Summary uses conditional reply_markup from input
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Reference Prepare Immediate Batch Exec directly for chatId/messageId
instead of $json which is the Telegram response from previous node.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Prepare Batch Exec now references Prepare Immediate Batch Exec directly
instead of relying on $json which gets overwritten by Delete Batch
Select Message. Also handles both 'action' and 'batchAction' field names.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add batchPage to Handle Batch Clear output
- Update Rebuild Batch Select Keyboard to also check Handle Batch Clear
as data source
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changed Fetch Containers For Batch Mode and Fetch Containers For Toggle
Update to use all=true instead of all=false, so stopped containers
appear in the batch select list for batch start operations.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add batch:nav callback type for page navigation with selection
- Parse batch:nav in Parse Callback Data
- Add route for isBatchNav in Route Callback switch
- Add Prepare Batch Nav node to format data for rebuild
- Update Rebuild Batch Select Keyboard to use batch:nav for navigation
- Now Previous/Next buttons preserve selected containers
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Don't set isCancel:true for batch:cancel (was routing to wrong handler)
- Add page to batch:toggle callback format: batch:toggle:{page}:{selected}:{name}
- Parse page in Parse Callback Data for toggle callbacks
- Pass page through Handle Batch Toggle
- Add pagination to Rebuild Batch Select Keyboard (6 per page)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Parse Callback Data now handles batch:mode:{page} format
- Build Batch Select Keyboard uses 6 containers per page
- Added Previous/Next navigation buttons
- Shows "Showing X-Y of Z" count when paginated
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace Delete Batch Cancel Message with Prepare Batch Cancel Return code node
- Connect Prepare Batch Cancel Return to Get Containers For List
- Update Build Paginated List to accept data from multiple sources
- Cancel now shows the container list instead of deleting the menu
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Task 1: Update All Command
- Detects 'update all' or 'updateall' in Keyword Router
- Fetches all containers and filters to :latest tag containers
- Shows confirmation with count and list (up to 10 displayed)
- On confirm: passes to batch execution infrastructure
- Shows 'All containers are up to date!' if no :latest containers
- 30-second timeout on confirmation
Task 2: Inline Multi-Select
- Added batch:mode callback to enter selection mode
- batch:toggle:{csv}:{name} for toggling container selection
- batch:exec:{action}:{csv} for executing batch actions
- batch:clear and batch:cancel for selection management
- Checkmarks show selected containers in keyboard
- Action buttons appear when selection exists
- Callback size limit enforced (max ~8 containers)
- Stop action requires confirmation (per existing batch flow)
- Update/start/restart execute immediately
Integration:
- Both flows connect to existing batch execution from 09-02
- Reuses batch loop and progress display infrastructure
- Add Is Batch Complete IF node to check loop termination
- Add Build Batch Summary code node with failure-first format
- Add Send Batch Summary HTTP node with Back to List button
- Connect Is Batch Complete true output to summary flow
- Connect Is Batch Complete false output back to Batch Loop
- Summary shows failures with reasons prominently
- Warnings shown in detail (<=3) or summary (>3)
- Success count shown last
- Add Initialize Batch State code node to prepare batch data
- Add Send Batch Start Message to show initial progress
- Add Prepare Batch Loop to format containers for iteration
- Add Batch Loop (splitInBatches) for sequential processing
- Connect Route Batch Action outputs (update/start/restart) to batch flow
- Add "Match Batch Containers" code node with exact-match-first algorithm
- Add "Needs Disambiguation" IF node to route ambiguous matches
- Add "Build Disambiguation Message" code node with inline keyboard
- Add "Send Disambiguation" HTTP node to display options
- Add "Has Not Found" IF node to handle missing containers
- Add "Build Not Found Message" code node with partial match confirmation
- Add "Send Not Found Message" HTTP node
Matching algorithm:
1. Exact match first: 'plex' matches 'plex' even if 'jellyplex' exists
2. Single fuzzy match: treated as found
3. Multiple fuzzy matches: triggers disambiguation with keyboard options
4. No matches: reported as not found with option to proceed with found containers
- 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)