360 lines
10 KiB
JSON
360 lines
10 KiB
JSON
{
|
|
"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', 'übermorgen', 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"
|
|
},
|
|
"openAiApi": {
|
|
"id": "GPzxHwwXxeZg07o5",
|
|
"name": "OpenAi account"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"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 ? `✅ Task added to Nextcloud Deck!\\n\\n📋 *${$input.item.json.title}*${$input.item.json.duedate ? '\\n📅 Due: ' + $input.item.json.duedate : ''}${cardUrl ? '\\n🔗 ' + cardUrl : ''}`\n : `❌ 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: \"❌ 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: \"📋 *Deck Commands*\\n\\n/deck add <task> - 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: \"📋 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": []
|
|
}
|