{"name": "Telegram Assistant - Deck Integration", "active": false, "nodes": [{"parameters": {"httpMethod": "POST", "path": "telegram-deck", "responseMode": "responseNode", "options": {}}, "id": "webhook-deck-1", "name": "Webhook", "type": "n8n-nodes-base.webhook", "typeVersion": 1.1, "position": [240, 300], "webhookId": "telegram-deck"}, {"parameters": {"mode": "runOnceForEachItem", "jsCode": "// Parse deck command\nconst args = $input.item.json.args || '';\nconst chatId = $input.item.json.chatId;\n\n// Extract subcommand\nconst parts = args.trim().split(/\\s+/);\nconst subCommand = parts[0]?.toLowerCase() || 'help';\nconst taskText = parts.slice(1).join(' ');\n\nreturn {\n chatId: chatId,\n subCommand: subCommand,\n taskText: taskText,\n originalArgs: args\n};"}, "id": "parse-deck-command-1", "name": "Parse Deck Command", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [460, 300]}, {"parameters": {"dataType": "string", "value1": "={{ $json.subCommand }}", "rules": {"rules": [{"value2": "add", "output": 0}, {"value2": "list", "output": 1}]}, "fallbackOutput": 2}, "id": "switch-deck-action-1", "name": "Route Deck Action", "type": "n8n-nodes-base.switch", "typeVersion": 3, "position": [680, 300]}, {"parameters": {"conditions": {"string": [{"value1": "={{ $json.taskText }}", "operation": "isNotEmpty"}]}}, "id": "check-task-text-1", "name": "Check Task Text", "type": "n8n-nodes-base.if", "typeVersion": 1, "position": [900, 200]}, {"parameters": {"url": "https://api.openai.com/v1/chat/completions", "authentication": "predefinedCredentialType", "nodeCredentialType": "openAiApi", "sendHeaders": true, "headerParameters": {"parameters": [{"name": "Authorization", "value": "=Bearer {{ $credentials.openai_api_key }}"}]}, "sendBody": true, "specifyBody": "json", "jsonBody": "={\n \"model\": \"gpt-4o-mini\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"Extract task information from user input. Return JSON with: title (required, concise task name), description (optional, details), duedate (optional, YYYY-MM-DD format). For German dates like 'morgen', '\u00fcbermorgen', calculate from today ({{ $now.toFormat('yyyy-MM-dd') }}). Be concise.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"{{ $json.taskText }}\"\n }\n ],\n \"temperature\": 0.3,\n \"max_tokens\": 150\n}", "options": {}}, "id": "ai-extract-task-1", "name": "AI Extract Task Details", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.1, "position": [1120, 100], "credentials": {"httpHeaderAuth": {"id": "openai_api_key", "name": "OpenAI API Key"}}}, {"parameters": {"mode": "runOnceForEachItem", "jsCode": "// Parse AI response\nconst aiResponse = $input.item.json.choices[0].message.content;\nlet taskData;\n\ntry {\n // Try to parse as JSON\n taskData = JSON.parse(aiResponse);\n} catch (e) {\n // Fallback to original text\n taskData = {\n title: $input.item.json.taskText.substring(0, 100),\n description: $input.item.json.taskText,\n duedate: null\n };\n}\n\nreturn {\n chatId: $input.item.json.chatId,\n title: taskData.title || 'Untitled Task',\n description: taskData.description || '',\n duedate: taskData.duedate || null\n};"}, "id": "format-task-data-1", "name": "Format Task Data", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [1340, 100]}, {"parameters": {"command": "=/home/node/create_card_from_ai.sh \"{{ $json.title }}\" \"{{ $json.description }}\" \"{{ $json.duedate || '' }}\""}, "id": "create-deck-card-1", "name": "Create Deck Card", "type": "n8n-nodes-base.executeCommand", "typeVersion": 1, "position": [1560, 100]}, {"parameters": {"mode": "runOnceForEachItem", "jsCode": "// Check if card creation was successful\nconst output = $input.item.json.stdout || '';\nconst error = $input.item.json.stderr || '';\n\nlet success = false;\nlet cardUrl = '';\n\nif (output.includes('Card created') || !error) {\n success = true;\n // Extract card URL if present in output\n const urlMatch = output.match(/https?:\\/\\/[^\\s]+/);\n cardUrl = urlMatch ? urlMatch[0] : '';\n}\n\nconst responseText = success \n ? `\u2705 Task added to Nextcloud Deck!\\n\\n\ud83d\udccb *${$input.item.json.title}*${$input.item.json.duedate ? '\\n\ud83d\udcc5 Due: ' + $input.item.json.duedate : ''}${cardUrl ? '\\n\ud83d\udd17 ' + cardUrl : ''}`\n : `\u274c Failed to create task.\\n\\nError: ${error}`;\n\nreturn {\n chatId: $input.item.json.chatId,\n text: responseText,\n parseMode: 'Markdown'\n};"}, "id": "format-success-response-1", "name": "Format Success Response", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [1780, 100]}, {"parameters": {"respondWith": "json", "responseBody": "={{ JSON.stringify($json) }}", "options": {}}, "id": "respond-result-1", "name": "Respond Result", "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1, "position": [2000, 300]}, {"parameters": {"respondWith": "json", "responseBody": "={{ JSON.stringify({\n chatId: $json.chatId,\n text: \"\u274c Please specify a task to add.\\n\\nExample: /deck add Review Q4 reports by Friday\"\n}) }}", "options": {}}, "id": "respond-no-task-1", "name": "Respond No Task", "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1, "position": [1120, 300]}, {"parameters": {"respondWith": "json", "responseBody": "={{ JSON.stringify({\n chatId: $json.chatId,\n text: \"\ud83d\udccb *Deck Commands*\\n\\n/deck add - Add a task\\n/deck list - List tasks (coming soon)\\n\\nExample:\\n/deck add Review project proposal by tomorrow\"\n}) }}", "options": {}}, "id": "respond-deck-help-1", "name": "Respond Deck Help", "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1, "position": [900, 580]}, {"parameters": {"respondWith": "json", "responseBody": "={{ JSON.stringify({\n chatId: $json.chatId,\n text: \"\ud83d\udccb List functionality coming soon!\\n\\nFor now, check your Nextcloud Deck directly at:\\nhttps://nextcloud.egonetix.de/apps/deck\"\n}) }}", "options": {}}, "id": "respond-list-placeholder-1", "name": "Respond List (Coming Soon)", "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1, "position": [900, 400]}], "connections": {"Webhook": {"main": [[{"node": "Parse Deck Command", "type": "main", "index": 0}]]}, "Parse Deck Command": {"main": [[{"node": "Route Deck Action", "type": "main", "index": 0}]]}, "Route Deck Action": {"main": [[{"node": "Check Task Text", "type": "main", "index": 0}]]}, "Check Task Text": {"main": [[{"node": "AI Extract Task Details", "type": "main", "index": 0}], [{"node": "Respond No Task", "type": "main", "index": 0}]]}, "AI Extract Task Details": {"main": [[{"node": "Format Task Data", "type": "main", "index": 0}]]}, "Format Task Data": {"main": [[{"node": "Create Deck Card", "type": "main", "index": 0}]]}, "Create Deck Card": {"main": [[{"node": "Format Success Response", "type": "main", "index": 0}]]}, "Format Success Response": {"main": [[{"node": "Respond Result", "type": "main", "index": 0}]]}, "Respond No Task": {"main": [[{"node": "Respond Result", "type": "main", "index": 0}]]}, "Respond Deck Help": {"main": [[{"node": "Respond Result", "type": "main", "index": 0}]]}, "Respond List (Coming Soon)": {"main": [[{"node": "Respond Result", "type": "main", "index": 0}]]}}, "settings": {}, "staticData": null, "meta": null, "pinData": {}, "triggerCount": 0, "tags": []}