{ "name": "Docker Event - Callback Handler", "nodes": [ { "parameters": { "updates": [ "callback_query" ], "additionalFields": {} }, "type": "n8n-nodes-base.telegramTrigger", "typeVersion": 1.2, "position": [ -880, 288 ], "id": "a56a5174-3ccf-492f-810b-117be933560c", "name": "Telegram Trigger", "webhookId": "6e70b9ab-b76b-48dc-8e4d-5fe1bf0d7e39", "credentials": { "telegramApi": { "id": "ADurvy9EKUDzbDdq", "name": "DK0_Server" } } }, { "parameters": { "jsCode": "const callback = $input.first().json;\nconst data = callback.callback_query?.data || '';\nconst chatId = callback.callback_query?.from?.id;\nconst messageId = callback.callback_query?.message?.message_id;\n\n// Parse: auto:slug, manual:slug, ignore:slug\nconst [action, slug] = data.split(':');\n\nreturn [{\n json: {\n action,\n slug,\n chatId,\n messageId,\n rawCallback: data\n }\n}];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ -656, 288 ], "id": "10e5a475-4194-4919-9186-1eb052fbd79b", "name": "Parse Callback" }, { "parameters": { "rules": { "values": [ { "conditions": { "options": { "caseSensitive": true, "leftValue": "" }, "conditions": [ { "leftValue": "={{ $json.action }}", "rightValue": "auto", "operator": { "type": "string", "operation": "equals" } } ], "combinator": "and" }, "renameOutput": true, "outputKey": "Auto" }, { "conditions": { "options": { "caseSensitive": true, "leftValue": "" }, "conditions": [ { "leftValue": "={{ $json.action }}", "rightValue": "manual", "operator": { "type": "string", "operation": "equals" } } ], "combinator": "and" }, "renameOutput": true, "outputKey": "Manual" }, { "conditions": { "options": { "caseSensitive": true, "leftValue": "" }, "conditions": [ { "leftValue": "={{ $json.action }}", "rightValue": "ignore", "operator": { "type": "string", "operation": "equals" } } ], "combinator": "and" }, "renameOutput": true, "outputKey": "Ignore" } ] }, "options": {} }, "type": "n8n-nodes-base.switch", "typeVersion": 3.2, "position": [ -448, 288 ], "id": "a533e527-b3c5-4946-9a26-6f499c7dd6c5", "name": "Switch Action" }, { "parameters": { "url": "=https://cms.dk0.dev/items/projects?filter[slug][_eq]={{ $json.slug }}&limit=1", "authentication": "predefinedCredentialType", "nodeCredentialType": "httpBearerAuth", "options": {} }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ -224, 80 ], "id": "9fc55503-e890-4074-9823-f07001b6948a", "name": "Get Project from CMS" }, { "parameters": { "url": "=https://git.dk0.dev/api/v1/repos/denshooter/{{ $json.slug }}/commits?limit=3", "authentication": "genericCredentialType", "genericAuthType": "httpHeaderAuth", "options": {} }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ 0, 0 ], "id": "a3fda0d9-0cc9-4744-be3e-9a95ef44dfb4", "name": "Get Commits" }, { "parameters": { "url": "=https://git.dk0.dev/api/v1/repos/denshooter/{{ $json.slug }}/contents/README.md", "authentication": "genericCredentialType", "genericAuthType": "httpHeaderAuth", "options": {} }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ 0, 128 ], "id": "7106b8c9-fb20-46d9-9e4e-06882115bf7a", "name": "Get README" }, { "parameters": { "model": "openrouter/free", "options": {} }, "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter", "typeVersion": 1, "position": [ 448, 192 ], "id": "9acce2c3-1a26-450f-a263-0dc3a1f1e3cf", "name": "OpenRouter Chat Model" }, { "parameters": { "promptType": "define", "text": "=Du bist ein technischer Autor für das Portfolio von Dennis (dk0.dev).\n\nNeues eigenes Projekt deployed:\nRepo: {{ $('Parse Callback').item.json.slug }}\n\nREADME:\n{{ $('Get README').first().json.content ? Buffer.from($('Get README').first().json.content, 'base64').toString('utf8').substring(0, 1000) : 'Kein README' }}\n\nLetzte Commits:\n{{ $('Get Commits').first().json.map(c => '- ' + c.commit.message).join('\\n') }}\n\nErstelle eine Portfolio-Beschreibung:\n- Was macht das Projekt (Features, Zweck)\n- Tech-Stack und Architektur\n- Highlights aus den Commits\n- Warum ist es cool/interessant\n\nKategorie: webdev (wenn Web-App), automation (wenn Tool/Script), oder selfhosted\n\nAntworte NUR als JSON:\n{\n \"title_en\": \"Aussagekräftiger Titel\",\n \"title_de\": \"Aussagekräftiger Titel\",\n \"description_en\": \"4-6 Sätze\",\n \"description_de\": \"4-6 Sätze\",\n \"content_en\": \"2-3 Absätze Markdown mit technischen Details\",\n \"content_de\": \"2-3 Absätze Markdown mit technischen Details\",\n \"category\": \"webdev|automation|selfhosted\",\n \"technologies\": [\"Next.js\", \"Docker\", \"...\"]\n}", "batching": {} }, "type": "@n8n/n8n-nodes-langchain.chainLlm", "typeVersion": 1.9, "position": [ 224, 80 ], "id": "2b011cf8-6ed3-4cb1-ab6f-7727912864fc", "name": "AI: Generate Description" }, { "parameters": { "jsCode": "const raw = $input.first().json.text ?? \"\";\nconst match = raw.match(/\\{[\\s\\S]*\\}/);\nif (!match) throw new Error(\"No JSON found\");\nconst ai = JSON.parse(match[0]);\nreturn [{ json: ai }];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 448, 80 ], "id": "0cbdcf6e-e5d4-460e-b345-b6d47deed051", "name": "Parse JSON" }, { "parameters": { "jsCode": "const ai = $input.first().json;\nconst ctx = $('Parse Callback').first().json;\n\nconst body = {\n slug: ctx.slug,\n status: \"draft\",\n featured: false,\n title: ai.title_en,\n category: ai.category,\n technologies: ai.technologies,\n tags: ai.technologies,\n date: new Date().toISOString().slice(0, 10),\n translations: {\n create: [\n {\n languages_code: \"en-US\",\n title: ai.title_en,\n description: ai.description_en,\n content: ai.content_en\n },\n {\n languages_code: \"de-DE\",\n title: ai.title_de,\n description: ai.description_de,\n content: ai.content_de\n }\n ]\n }\n};\n\nconst response = await this.helpers.httpRequest({\n method: \"POST\",\n url: \"https://cms.dk0.dev/items/projects\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Authorization\": \"Bearer RF2QytqhcLXuVy6FO3PzWlsoR-ysCTwB\"\n },\n body\n});\n\nreturn [{ json: response }];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 672, 80 ], "id": "70aecf97-6b70-4f03-99e3-9ee44fc0830b", "name": "Add to Directus" }, { "parameters": { "chatId": "={{ $('Parse Callback').item.json.chatId }}", "text": "={{ \n'✅ Projekt erstellt: ' + $json.data.title + '\\n\\n' +\n'📝 ' + $('Parse JSON').first().json.description_de.substring(0, 200) + '...\\n\\n' +\n'Status: Draft (ID: ' + $json.data.id + ')\\n\\n' +\n'/publishproject' + $json.data.id + ' — Veröffentlichen\\n' + \n'/deleteproject' + $json.data.id + ' — Löschen' \n}}", "additionalFields": {} }, "type": "n8n-nodes-base.telegram", "typeVersion": 1.2, "position": [ 880, 80 ], "id": "9a353247-7d25-4330-9cbf-580599428ae1", "name": "Notify Success", "webhookId": "b1d7284d-c2e5-4e87-b65d-272f1b9b8d6d" }, { "parameters": { "chatId": "={{ $json.chatId }}", "text": "✍️ OK, schreib mir jetzt was das Projekt macht (4-6 Sätze).\n\nIch formatiere das dann schön und erstelle einen Draft.", "additionalFields": {} }, "type": "n8n-nodes-base.telegram", "typeVersion": 1.2, "position": [ -224, 288 ], "id": "9160b847-5f07-4d64-9488-faeaeca926b9", "name": "Ask for Manual Input", "webhookId": "c4cb518d-a2e2-48af-b9b6-c3f645fd37db" }, { "parameters": { "chatId": "={{ $json.chatId }}", "text": "❌ OK, ignoriert.", "additionalFields": {} }, "type": "n8n-nodes-base.telegram", "typeVersion": 1.2, "position": [ -224, 480 ], "id": "1624b6f1-8202-4fd2-bd0a-52fa039ca696", "name": "Confirm Ignore", "webhookId": "4c5248f1-4420-403c-a506-2e1968c5579d", "credentials": { "telegramApi": { "id": "ADurvy9EKUDzbDdq", "name": "DK0_Server" } } } ], "pinData": {}, "connections": { "Telegram Trigger": { "main": [ [ { "node": "Parse Callback", "type": "main", "index": 0 } ] ] }, "Parse Callback": { "main": [ [ { "node": "Switch Action", "type": "main", "index": 0 } ] ] }, "Switch Action": { "main": [ [ { "node": "Get Project from CMS", "type": "main", "index": 0 } ], [ { "node": "Ask for Manual Input", "type": "main", "index": 0 } ], [ { "node": "Confirm Ignore", "type": "main", "index": 0 } ] ] }, "Get Project from CMS": { "main": [ [ { "node": "Get Commits", "type": "main", "index": 0 } ] ] }, "Get Commits": { "main": [ [ { "node": "Get README", "type": "main", "index": 0 } ] ] }, "Get README": { "main": [ [ { "node": "AI: Generate Description", "type": "main", "index": 0 } ] ] }, "OpenRouter Chat Model": { "ai_languageModel": [ [ { "node": "AI: Generate Description", "type": "ai_languageModel", "index": 0 } ] ] }, "AI: Generate Description": { "main": [ [ { "node": "Parse JSON", "type": "main", "index": 0 } ] ] }, "Parse JSON": { "main": [ [ { "node": "Add to Directus", "type": "main", "index": 0 } ] ] }, "Add to Directus": { "main": [ [ { "node": "Notify Success", "type": "main", "index": 0 } ] ] } }, "active": false, "settings": { "executionOrder": "v1", "binaryMode": "separate", "availableInMCP": false }, "versionId": "4636a407-7f8e-4833-9345-9d3296ec9b74", "meta": { "instanceId": "cb28e4db755465d5826da179e87f69603d81f833414cc52c327be9183a217b8d" }, "id": "abnrtUuJ7BAWv9Hm", "tags": [] }