---
phase: 05-polish-deploy
plan: 01
type: execute
wave: 1
depends_on: []
files_modified: [n8n-workflow.json]
autonomous: true
must_haves:
truths:
- "User sees persistent menu buttons in Telegram"
- "Typing 'status' triggers container list (no Claude API call)"
- "Typing 'start plex' triggers start flow (no Claude API call)"
- "Unknown commands show menu instead of error"
artifacts:
- path: "n8n-workflow.json"
provides: "Keyword Router Switch node"
contains: "Keyword Router"
- path: "n8n-workflow.json"
provides: "Persistent menu reply markup"
contains: "is_persistent"
key_links:
- from: "Telegram Trigger"
to: "Keyword Router"
via: "Route Message path"
pattern: "Keyword Router"
- from: "Keyword Router"
to: "Docker List Containers"
via: "status output"
pattern: "status.*Docker List"
---
Replace Claude/NLU nodes with keyword-based routing and add persistent Telegram menu buttons.
Purpose: Remove external Claude API dependency, enable offline-first operation with simple keyword matching.
Output: Working keyword routing with persistent menu, no Claude API calls in workflow.
@/home/luc/.claude/get-shit-done/workflows/execute-plan.md
@/home/luc/.claude/get-shit-done/templates/summary.md
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/05-polish-deploy/05-CONTEXT.md
@.planning/phases/05-polish-deploy/05-RESEARCH.md
@n8n-workflow.json
Task 1: Remove NLU/Claude nodes and add Keyword Router
n8n-workflow.json
Remove these nodes from the workflow:
- Prepare Claude Request
- Claude Intent Parser (HTTP Request node calling api.anthropic.com)
- Parse Intent (Code node)
- Intent Router (old Switch node routing on parsed intent)
- Send Unknown Intent
- Send Intent Error
- Remove Anthropic API Key credential reference
Replace with a single Switch node called "Keyword Router" with these rules (case-insensitive matching on message.text):
- Contains "status" -> output "status" -> connect to Docker List Containers
- Contains "start" -> output "start" -> connect to Parse Action Command (with action set to start)
- Contains "stop" -> output "stop" -> connect to Parse Action Command (with action set to stop)
- Contains "restart" -> output "restart" -> connect to Parse Action Command (with action set to restart)
- Contains "update" -> output "update" -> connect to existing update flow entry point
- Contains "logs" -> output "logs" -> connect to existing logs flow entry point
- Fallback (extra) -> connect to new "Show Menu" node
Use the Switch node pattern from RESEARCH.md:
```json
{
"conditions": {
"options": { "caseSensitive": false },
"conditions": [{
"leftValue": "={{ $json.message.text }}",
"rightValue": "status",
"operator": { "type": "string", "operation": "contains" }
}]
}
}
```
Update "Route Message" node to connect directly to "Keyword Router" instead of the old Claude flow.
Open workflow in n8n UI. Send "status" - should trigger Docker List Containers path.
Check that no nodes reference api.anthropic.com or Anthropic API Key credential.
Keyword Router handles all 6 commands (status, start, stop, restart, update, logs) plus fallback.
No Claude/NLU nodes remain in workflow.
Task 2: Add persistent Telegram menu
n8n-workflow.json
Create a new "Show Menu" node (HTTP Request type, not native Telegram node - per project pattern for keyboards).
Configure HTTP Request:
- URL: `https://api.telegram.org/bot{{ $credentials.telegramApi.token }}/sendMessage`
- Method: POST
- Body (JSON):
```json
{
"chat_id": "={{ $json.message.chat.id }}",
"text": "Use buttons below or type commands:",
"parse_mode": "HTML",
"reply_markup": {
"keyboard": [
[{"text": "Status"}],
[{"text": "Start"}, {"text": "Stop"}],
[{"text": "Restart"}, {"text": "Update"}],
[{"text": "Logs"}]
],
"is_persistent": true,
"resize_keyboard": true,
"one_time_keyboard": false
}
}
```
Connect Keyword Router fallback output to Show Menu node.
NOTE: Research suggests emojis optional (Claude's discretion from CONTEXT.md). Start without emojis for cleaner keyword matching - button text "Status" matches "status" keyword.
Also wire /start command to Show Menu:
- In Keyword Router, add rule: Contains "/start" -> output "menu" -> connect to Show Menu
Send any unknown command (e.g., "hello") - should receive menu with persistent keyboard.
Send "/start" - should receive same menu.
Keyboard should persist after sending other messages.
Persistent menu visible in Telegram chat.
Menu buttons trigger corresponding actions when tapped.
/start and unknown commands show menu.
1. All Claude/NLU nodes removed (grep for "anthropic", "Claude", "Intent" in workflow JSON)
2. Keyword Router handles: status, start, stop, restart, update, logs, /start, fallback
3. Persistent menu shows 6 buttons in grouped layout
4. Button taps trigger corresponding keyword routes
5. No errors in n8n execution logs for any command
- Zero references to Anthropic API or Claude in workflow
- All 6 container commands work via typed keywords
- Persistent menu visible and functional
- Unknown input shows menu (not error)