{ "name": "Email to AI Task (Vikunja)", "nodes": [ { "parameters": { "values": { "string": [ { "name": "prompt", "value": "=You are a task extraction assistant.\n\nReturn ONLY valid JSON with these fields:\n{\n \"title\": string,\n \"summary\": string,\n \"priority\": number (1-5),\n \"due_date\": string | null,\n \"labels\": string[]\n}\n\nEmail subject: {{$json.subject}}\nEmail body: {{$json.textPlain}}" } ] }, "options": { "dotNotation": false } }, "name": "Build AI Prompt", "type": "n8n-nodes-base.set", "typeVersion": 1, "position": [ 1456, 368 ], "id": "1d09bb19-658b-4310-b4ae-a4633b90aa16" }, { "parameters": { "method": "POST", "url": "http://api.chat.pathcore.org/api/generate", "sendBody": true, "contentType": "raw", "body": "={{ JSON.stringify({ model: \"mistral\", prompt: $json.prompt, stream: false }) }}\n", "options": {} }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.3, "position": [ 1664, 368 ], "id": "d067d32f-1d08-456a-a51a-c5bb2ab7e82d", "name": "HTTP Request" }, { "parameters": { "method": "PUT", "url": "https://tasks.pathcore.org/api/v1/projects/1/tasks", "authentication": "genericCredentialType", "genericAuthType": "httpHeaderAuth", "sendBody": true, "specifyBody": "json", "jsonBody": "={\n \"title\": \"{{ $json.title }}\",\n \"description\": \"{{ $json.description }}\",\n \"project_id\": 1,\n \"priority\": {{ $json.priority }},\n \"due_date\": \"{{ $json.due_date }}\"\n}\n", "options": {} }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.3, "position": [ 2064, 368 ], "id": "0d3330f1-f828-48ad-b5ba-18daabc80c4e", "name": "HTTP Request1", "credentials": { "httpHeaderAuth": { "id": "ao2U85ZTTchihcSC", "name": "Vikunja API" } } }, { "parameters": { "downloadAttachments": true, "options": { "forceReconnect": 1, "trackLastMessageId": true } }, "type": "n8n-nodes-base.emailReadImap", "typeVersion": 2.1, "position": [ 1248, 368 ], "id": "a0c694fa-9757-416b-967d-0bdf995241e7", "name": "Email Trigger (IMAP)", "credentials": { "imap": { "id": "uen9pTUrJDRJFvlu", "name": "IMAP account" } } }, { "parameters": { "jsCode": "let text = $json.response || \"\";\n\n// Extract JSON block from Ollama response\nlet match = text.match(/\\{[\\s\\S]*\\}/);\nif (!match) {\n return [{\n title: \"Manual review required\",\n description: text,\n priority: 3,\n due_date: null,\n labels: [\"ai-error\"]\n }];\n}\n\nlet data = JSON.parse(match[0]);\n\n// Convert due_date to ISO 8601 with time (YYYY-MM-DDTHH:mm:ssZ)\nlet formattedDate = null;\nif (data.due_date === null || data.due_date === undefined || data.due_date === \"\") {\n // If no due_date, set to tomorrow\n let tomorrow = new Date();\n tomorrow.setDate(tomorrow.getDate() + 1);\n formattedDate = tomorrow.toISOString();\n} else if (data.due_date) {\n let dateStr = data.due_date.toLowerCase().trim();\n \n if (dateStr.includes(\"end of month\") || dateStr.includes(\"end of the month\")) {\n let today = new Date();\n let lastDay = new Date(today.getFullYear(), today.getMonth() + 1, 0);\n formattedDate = lastDay.toISOString();\n } else if (dateStr.includes(\"end of week\")) {\n let today = new Date();\n let daysUntilFriday = (5 - today.getDay() + 7) % 7 || 7;\n let friday = new Date(today);\n friday.setDate(friday.getDate() + daysUntilFriday);\n formattedDate = friday.toISOString();\n } else if (dateStr.includes(\"today\")) {\n formattedDate = new Date().toISOString();\n } else if (dateStr.includes(\"tomorrow\")) {\n let tomorrow = new Date();\n tomorrow.setDate(tomorrow.getDate() + 1);\n formattedDate = tomorrow.toISOString();\n } else if (dateStr.includes(\"next week\")) {\n let nextWeek = new Date();\n nextWeek.setDate(nextWeek.getDate() + 7);\n formattedDate = nextWeek.toISOString();\n } else {\n // Try parsing as ISO date or other formats\n let parsed = new Date(data.due_date);\n if (!isNaN(parsed.getTime())) {\n formattedDate = parsed.toISOString();\n }\n }\n}\n\n// Ensure labels is always an array\nlet labels = data.labels || [];\nif (!Array.isArray(labels)) {\n labels = [labels];\n}\n\nreturn [{\n title: data.title || \"New Task\",\n description: data.summary || \"\",\n priority: data.priority || 3,\n due_date: formattedDate,\n labels: labels\n}];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 1856, 368 ], "id": "c85d2e04-8a51-4c49-a7e5-c8f7b36e366b", "name": "Code in JavaScript" }, { "parameters": { "authentication": "oAuth2", "select": "channel", "channelId": { "__rl": true, "value": "C0A7DBLUT5K", "mode": "list", "cachedResultName": "vijunka-tasks" }, "text": "=🆕 New Vikunja Task Created ID: {{ $json.id }} Identifier: {{ $json.identifier }} Project ID: {{ $json.project_id }} Bucket ID: {{ $json.bucket_id }} Description: {{ $json.description }} Priority: {{ $json.priority }} Percent Done: {{ $json.percent_done }}% Done: {{ $json.done }} Done At: {{ $json.done_at }} Start Date: {{ $json.start_date }} Due Date: {{ $json.due_date }} End Date: {{ $json.end_date }} Repeat Mode: {{ $json.repeat_mode }} Favorite: {{ $json.is_favorite }} Assignees: {{ ($json.assignees || []).map(a => a.username).join(\", \") }} Labels: {{ ($json.labels || []).map(l => l.name).join(\", \") }} Created By: {{ $json.created_by?.username }} Created: {{ $json.created }} Updated: {{ $json.updated }}", "otherOptions": { "includeLinkToWorkflow": false } }, "type": "n8n-nodes-base.slack", "typeVersion": 2.4, "position": [ 2272, 368 ], "id": "cb9715a4-40c4-4de3-8f7e-d46c602dd730", "name": "Send a message", "webhookId": "7f5f138d-a956-489a-812f-0a915925dfd1", "credentials": { "slackOAuth2Api": { "id": "zntCoaowWYuBIKAY", "name": "Slack account" } } } ], "pinData": {}, "connections": { "Build AI Prompt": { "main": [ [ { "node": "HTTP Request", "type": "main", "index": 0 } ] ] }, "HTTP Request": { "main": [ [ { "node": "Code in JavaScript", "type": "main", "index": 0 } ] ] }, "Email Trigger (IMAP)": { "main": [ [ { "node": "Build AI Prompt", "type": "main", "index": 0 } ] ] }, "Code in JavaScript": { "main": [ [ { "node": "HTTP Request1", "type": "main", "index": 0 } ] ] }, "HTTP Request1": { "main": [ [ { "node": "Send a message", "type": "main", "index": 0 } ] ] } }, "active": true, "settings": { "executionOrder": "v1" }, "versionId": "67aafb11-9cbf-486a-b779-6f4dcebe7269", "meta": { "templateCredsSetupCompleted": true, "instanceId": "3f831ca7bfd296051ccce9f0b1bd3c7aab7da4cca2818b7ffc69b89b3b2840d2" }, "id": "wm6gwcPOLRiBwpdZ", "tags": [] }