{ "name": "Zulip Command Handler", "nodes": [ { "parameters": { "httpMethod": "POST", "path": "zulip-commands", "responseMode": "responseNode", "options": {} }, "id": "webhook-zulip", "name": "Zulip Webhook", "type": "n8n-nodes-base.webhook", "typeVersion": 2, "position": [240, 300] }, { "parameters": { "jsCode": "// Parse Zulip webhook payload const body = $input.first().json.body || $input.first().json; // Extract message content const message = body.message || {}; const content = message.content || body.data || \"\"; const senderEmail = message.sender_email || body.user_email || \"unknown\"; const stream = message.display_recipient || body.stream || \"general\"; const topic = message.subject || body.topic || \"general\"; // Parse command: /category action args const match = content.match(/^\/(\w+)(?:\s+(\w+))?(?:\s+(.+))?$/); if (\!match) { return [{ json: { isCommand: false, rawContent: content, sender: senderEmail, stream: stream, topic: topic, error: \"Not a valid command format. Use /category action [args]\" } }]; } return [{ json: { isCommand: true, category: match[1], action: match[2] || \"default\", args: match[3] || \"\", sender: senderEmail, stream: stream, topic: topic, rawContent: content } }];" }, "id": "parse-command", "name": "Parse Zulip Command", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [460, 300] }, { "parameters": { "conditions": { "boolean": [ { "value1": "={{ $json.isCommand }}", "value2": true } ] } }, "id": "is-command", "name": "Is Valid Command?", "type": "n8n-nodes-base.if", "typeVersion": 2, "position": [680, 300] }, { "parameters": { "rules": { "values": [ {"value": "project", "output": 0}, {"value": "code", "output": 1}, {"value": "deploy", "output": 2}, {"value": "sprint", "output": 3}, {"value": "dt", "output": 4}, {"value": "design", "output": 5} ] }, "fallbackOutput": 6, "options": {}, "dataPropertyName": "={{ $json.category }}" }, "id": "route-command", "name": "Route by Category", "type": "n8n-nodes-base.switch", "typeVersion": 3, "position": [900, 200] }, { "parameters": { "url": "https://gitea.mylder.io/admin/skills-library/raw/branch/main/skills/project/create.md", "options": {} }, "id": "load-project-skill", "name": "Load Project Skill", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4, "position": [1120, 0] }, { "parameters": { "url": "https://gitea.mylder.io/admin/skills-library/raw/branch/main/skills/code/review.md", "options": {} }, "id": "load-code-skill", "name": "Load Code Skill", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4, "position": [1120, 100] }, { "parameters": { "url": "https://gitea.mylder.io/admin/skills-library/raw/branch/main/skills/deploy/preview.md", "options": {} }, "id": "load-deploy-skill", "name": "Load Deploy Skill", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4, "position": [1120, 200] }, { "parameters": { "url": "https://gitea.mylder.io/admin/skills-library/raw/branch/main/skills/sprint/plan.md", "options": {} }, "id": "load-sprint-skill", "name": "Load Sprint Skill", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4, "position": [1120, 300] }, { "parameters": { "url": "https://gitea.mylder.io/admin/skills-library/raw/branch/main/skills/design-thinking/ideate.md", "options": {} }, "id": "load-dt-skill", "name": "Load Design Thinking Skill", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4, "position": [1120, 400] }, { "parameters": { "jsCode": "// Handle unknown command return [{ json: { response: \"Unknown command category. Available: /project, /code, /deploy, /sprint, /dt, /design\", isError: true } }];" }, "id": "unknown-command", "name": "Unknown Command", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [1120, 600] }, { "parameters": { "jsCode": "// Format response for Zulip const data = $input.first().json; let response = data.response || data.error || \"Command processed\"; // Zulip expects { content: \"message\" } format return [{ json: { content: response } }];" }, "id": "format-response", "name": "Format Zulip Response", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [1540, 300] }, { "parameters": { "respondWith": "json", "responseBody": "={{ $json }}", "options": {} }, "id": "respond-webhook", "name": "Respond to Zulip", "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1, "position": [1760, 300] }, { "parameters": { "jsCode": "// Error response for invalid command const data = $input.first().json; return [{ json: { content: data.error || \"Invalid command format. Use: /category action [args]\" } }];" }, "id": "error-response", "name": "Error Response", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [900, 460] } ], "connections": { "Zulip Webhook": { "main": [[{"node": "Parse Zulip Command", "type": "main", "index": 0}]] }, "Parse Zulip Command": { "main": [[{"node": "Is Valid Command?", "type": "main", "index": 0}]] }, "Is Valid Command?": { "main": [ [{"node": "Route by Category", "type": "main", "index": 0}], [{"node": "Error Response", "type": "main", "index": 0}] ] }, "Route by Category": { "main": [ [{"node": "Load Project Skill", "type": "main", "index": 0}], [{"node": "Load Code Skill", "type": "main", "index": 0}], [{"node": "Load Deploy Skill", "type": "main", "index": 0}], [{"node": "Load Sprint Skill", "type": "main", "index": 0}], [{"node": "Load Design Thinking Skill", "type": "main", "index": 0}], [{"node": "Load Design Thinking Skill", "type": "main", "index": 0}], [{"node": "Unknown Command", "type": "main", "index": 0}] ] }, "Load Project Skill": { "main": [[{"node": "Format Zulip Response", "type": "main", "index": 0}]] }, "Load Code Skill": { "main": [[{"node": "Format Zulip Response", "type": "main", "index": 0}]] }, "Load Deploy Skill": { "main": [[{"node": "Format Zulip Response", "type": "main", "index": 0}]] }, "Load Sprint Skill": { "main": [[{"node": "Format Zulip Response", "type": "main", "index": 0}]] }, "Load Design Thinking Skill": { "main": [[{"node": "Format Zulip Response", "type": "main", "index": 0}]] }, "Unknown Command": { "main": [[{"node": "Format Zulip Response", "type": "main", "index": 0}]] }, "Error Response": { "main": [[{"node": "Respond to Zulip", "type": "main", "index": 0}]] }, "Format Zulip Response": { "main": [[{"node": "Respond to Zulip", "type": "main", "index": 0}]] } }, "settings": { "executionOrder": "v1" }, "staticData": null, "tags": [], "triggerCount": 1, "updatedAt": "2025-12-11T20:30:00.000Z", "versionId": "1" }