{ "name": "Docker Event", "nodes": [ { "parameters": { "httpMethod": "POST", "path": "docker-event", "responseMode": "responseNode", "options": {} }, "type": "n8n-nodes-base.webhook", "typeVersion": 2.1, "position": [ 0, -224 ], "id": "870fa550-42f6-4e19-a796-f1f044b0cdc8", "name": "Webhook", "webhookId": "e147d70b-79d8-44fd-bbe8-8274cf905b11" }, { "parameters": { "jsCode": "const data = $input.first().json;\n\nconst container = data.container ?? data.body?.container ?? '';\nconst image = data.image ?? data.body?.image ?? '';\nconst timestamp = data.timestamp ?? data.body?.timestamp ?? '';\n\nconst slug = container.toLowerCase().replace(/[^a-z0-9]+/g, '-');\n\nconst serviceName = container.replace(/[-_]/g, ' ');\n\nreturn [{\n json: {\n container,\n image,\n serviceName,\n timestamp,\n slug \n }\n}];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 224, -224 ], "id": "aaa6a678-1ad3-4f82-9b01-37e21b47b189", "name": "Kontext aufbereiten" }, { "parameters": { "conditions": { "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "loose", "version": 3 }, "conditions": [ { "id": "ebe26f0c-d5a7-45c9-9747-afc75b57a41c", "leftValue": "={{ $json.data }}", "rightValue": "[]", "operator": { "type": "string", "operation": "notEndsWith" } } ], "combinator": "and" }, "looseTypeValidation": true, "options": {} }, "type": "n8n-nodes-base.if", "typeVersion": 2.3, "position": [ 672, -224 ], "id": "62197a33-5169-48e1-9539-57c047efb108", "name": "If" }, { "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": [ 448, -224 ], "id": "db783886-06b5-4473-8907-dd6c655aa3dd", "name": "Search for Slug", "credentials": { "httpBearerAuth": { "id": "ZtI5e08iryR9m6FG", "name": "Directus" } } }, { "parameters": { "model": "openrouter/free", "options": {} }, "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter", "typeVersion": 1, "position": [ 976, 16 ], "id": "b9130ff4-359b-4736-9442-1b0ca7d31877", "name": "OpenRouter Chat Model", "credentials": { "openRouterApi": { "id": "8Kdy4RHHwMZ0Cn6x", "name": "OpenRouter" } } }, { "parameters": { "promptType": "define", "text": "= Du bist ein technischer Autor für das Self-Hosting Portfolio von Dennis auf dk0.dev.\n Ein neuer Service wurde auf dem Server deployed:\n\n Container:{{ $('Kontext aufbereiten').item.json.container }}\n Image: {{ $('Kontext aufbereiten').item.json.image }}\n Service: {{ $('Kontext aufbereiten').item.json.serviceName }}\n\n Aufgabe:\n 1. Erkenne ob es sich um ein EIGENES Projekt (z.B. Image enthält \"denshooter\", \"dk0\", \"portfolio\") oder eine SELF-HOSTED\n App (z.B. plausible, nextcloud, gitea, etc.) handelt.\n 2. Erstelle eine ausführliche Projektbeschreibung.\n\n Für EIGENE Projekte:\n - Beschreibe was die App macht, welche Probleme sie löst, welche Features sie hat\n - Erwähne den Tech-Stack und architektonische Entscheidungen\n - category: \"webdev\" oder \"automation\"\n\n Für SELF-HOSTED Apps:\n - Beschreibe was die App macht und warum Self-Hosting besser ist als die Cloud-Alternative\n - Erwähne Vorteile wie Datenschutz, Kontrolle, Kosten\n - Beschreibe kurz wie sie in die bestehende Infrastruktur integriert ist (Docker, Reverse Proxy, etc.)\n - category: \"selfhosted\"\n\n Antworte NUR als valides JSON, kein anderer Text:\n {\n \"type\": \"own\" oder \"selfhosted\",\n \"title_en\": \"Aussagekräftiger Titel auf Englisch\",\n \"title_de\": \"Aussagekräftiger Titel auf Deutsch\",\n \"description_en\": \"Ausführliche Beschreibung, 4-6 Sätze. Was macht es, warum ist es wichtig, was sind die Highlights.\",\n \"description_de\": \"Ausführliche Beschreibung, 4-6 Sätze. Was macht es, warum ist es wichtig, was sind die Highlights.\",\n \"content_en\": \"Noch detaillierterer Text, 2-3 Absätze in Markdown. Features, Setup, technische Details.\",\n \"content_de\": \"Noch detaillierterer Text, 2-3 Absätze in Markdown. Features, Setup, technische Details.\",\n \"category\": \"selfhosted\" oder \"webdev\" oder \"automation\",\n \"technologies\": [\"Docker\", \"und alle anderen relevanten Technologien\"]\n ", "batching": {} }, "type": "@n8n/n8n-nodes-langchain.chainLlm", "typeVersion": 1.9, "position": [ 896, -224 ], "id": "77d46075-3342-4e93-8806-07087a2389dc", "name": "Basic LLM Chain" }, { "parameters": { "jsCode": "const raw = $input.first().json.text ?? \"\";\n\nconst match = raw.match(/\\{[\\s\\S]*\\}/);\nif (!match) throw new Error(\"No JSON found\");\n\nconst ai = JSON.parse(match[0]);\n\nreturn [\n {\n json: ai,\n },\n];\n" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 1248, -224 ], "id": "de5ed311-0d46-4677-963c-711a6ad514e9", "name": "Parse JSON" }, { "parameters": { "jsCode": "const ai = $('Parse JSON').first().json;\n const ctx = $('Kontext aufbereiten').first().json;\n\n const 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\n const 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\n return [{ json: response }];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 1472, -224 ], "id": "c47b915d-e4d7-43e9-8ee3-b41389896fa7", "name": "Add to Directus" }, { "parameters": { "respondWith": "json", "responseBody": "{ \"success\": true }", "options": {} }, "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.5, "position": [ 1920, -224 ], "id": "6cf8f30d-1352-466f-9163-9b4f16b972e0", "name": "Respond to Webhook" }, { "parameters": { "chatId": "145931600", "text": "={{ \n'🆕 Neuer Service erkannt!\\n\\n' +\n'📦 ' + $('Kontext aufbereiten').first().json.container + '\\n' +\n'🐳 ' + $('Kontext aufbereiten').first().json.image + '\\n\\n' +\n'📝 ' + $('Parse JSON').first().json.title_de + '\\n' + \n$('Parse JSON').first().json.description_de + '\\n\\n' +\n'Status: Draft in Directus erstellt (ID: ' + $json.data.id + ')\\n\\n' +\n('/publishproject_' + $json.data.id).replace(/_/g, '\\\\_') + ' — Veröffentlichen\\n' + \n('/deleteproject_' + $json.data.id).replace(/_/g, '\\\\_') + ' — Löschen' \n}}", "additionalFields": {} }, "type": "n8n-nodes-base.telegram", "typeVersion": 1.2, "position": [ 1696, -224 ], "id": "b29de3ec-b1ca-40c3-8493-af44e5372fd2", "name": "Send a text message", "webhookId": "c02ccf69-16dc-436e-b1cc-f8fa9dd8d33f", "credentials": { "telegramApi": { "id": "ADurvy9EKUDzbDdq", "name": "DK0_Server" } } } ], "pinData": {}, "connections": { "Webhook": { "main": [ [ { "node": "Kontext aufbereiten", "type": "main", "index": 0 } ] ] }, "Kontext aufbereiten": { "main": [ [ { "node": "Search for Slug", "type": "main", "index": 0 } ] ] }, "If": { "main": [ [], [ { "node": "Basic LLM Chain", "type": "main", "index": 0 } ] ] }, "Search for Slug": { "main": [ [ { "node": "If", "type": "main", "index": 0 } ] ] }, "OpenRouter Chat Model": { "ai_languageModel": [ [ { "node": "Basic LLM Chain", "type": "ai_languageModel", "index": 0 } ] ] }, "Basic LLM Chain": { "main": [ [ { "node": "Parse JSON", "type": "main", "index": 0 } ] ] }, "Parse JSON": { "main": [ [ { "node": "Add to Directus", "type": "main", "index": 0 } ] ] }, "Add to Directus": { "main": [ [ { "node": "Send a text message", "type": "main", "index": 0 } ] ] }, "Send a text message": { "main": [ [ { "node": "Respond to Webhook", "type": "main", "index": 0 } ] ] } }, "active": true, "settings": { "executionOrder": "v1", "binaryMode": "separate", "availableInMCP": false }, "versionId": "91b63f71-f5b7-495f-95ba-cbf999bb9a19", "meta": { "templateCredsSetupCompleted": true, "instanceId": "cb28e4db755465d5826da179e87f69603d81f833414cc52c327be9183a217b8d" }, "id": "RARR6MAlJSHAmBp8", "tags": [] }