The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "40_435_WEEKLY_SUMMARY",
"nodes": [
{
"id": "435-schedule",
"name": "Every Monday 09:00",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
200,
400
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 9 * * 1"
}
]
}
}
},
{
"id": "435-fetch-pieces",
"name": "Fetch Content Pieces",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
440,
200
],
"parameters": {
"method": "GET",
"url": "https://directus.automation-plus-ki.de/items/330_knowledge_items",
"authentication": "none",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer ={{ $env.DIRECTUS_TOKEN }}"
}
]
},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "limit",
"value": "100"
},
{
"name": "sort",
"value": "-created_at"
}
]
},
"options": {
"timeout": 10000
}
},
"onError": "continueRegularOutput"
},
{
"id": "435-fetch-pipeline",
"name": "Fetch Pipeline Jobs",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
440,
360
],
"parameters": {
"method": "GET",
"url": "https://directus.automation-plus-ki.de/items/400_content_pipeline",
"authentication": "none",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer ={{ $env.DIRECTUS_TOKEN }}"
}
]
},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "limit",
"value": "100"
},
{
"name": "sort",
"value": "-created_at"
}
]
},
"options": {
"timeout": 10000
}
},
"onError": "continueRegularOutput"
},
{
"id": "435-fetch-executions",
"name": "Fetch n8n Executions",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
440,
520
],
"parameters": {
"method": "GET",
"url": "http://10.0.1.16:5678/api/v1/executions",
"authentication": "none",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "X-N8N-API-KEY",
"value": "={{ $env.N8N_API_KEY }}"
}
]
},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "limit",
"value": "100"
}
]
},
"options": {
"timeout": 10000
}
},
"onError": "continueRegularOutput"
},
{
"id": "435-fetch-opportunities",
"name": "Fetch Content Opportunities",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
440,
680
],
"parameters": {
"method": "GET",
"url": "https://directus.automation-plus-ki.de/items/320_content_opportunities",
"authentication": "none",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer ={{ $env.DIRECTUS_TOKEN }}"
}
]
},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "limit",
"value": "20"
},
{
"name": "sort",
"value": "-created_at"
}
]
},
"options": {
"timeout": 10000
}
},
"onError": "continueRegularOutput"
},
{
"id": "435-analyse",
"name": "Weekly Analysis",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
740,
440
],
"parameters": {
"jsCode": "// \u2500\u2500 Hilfsfunktionen \u2500\u2500\nconst now = Date.now();\nconst msPerDay = 86400000;\nconst isThisWeek = (dateStr) => {\n if (!dateStr) return false;\n return (now - new Date(dateStr).getTime()) < 7 * msPerDay;\n};\n\n// \u2500\u2500 Content Pieces \u2500\u2500\nlet pieces = [];\ntry { pieces = $('Fetch Content Pieces').first().json?.data ?? []; } catch(e) {}\nconst piecesThisWeek = pieces.filter(p => isThisWeek(p.created_at ?? p.CreatedAt));\nconst byStatus = {};\nfor (const p of piecesThisWeek) {\n const s = p.status ?? 'unknown';\n byStatus[s] = (byStatus[s] ?? 0) + 1;\n}\n\n// Top Pieces (published zuerst, dann approved, dann draft)\nconst statusOrder = { published: 0, approved: 1, review: 2, draft: 3, idea: 4 };\nconst topPieces = [...piecesThisWeek]\n .sort((a, b) => (statusOrder[a.status] ?? 9) - (statusOrder[b.status] ?? 9))\n .slice(0, 5);\n\n// \u2500\u2500 Pipeline Jobs \u2500\u2500\nlet pipelineJobs = [];\ntry { pipelineJobs = $('Fetch Pipeline Jobs').first().json?.data ?? []; } catch(e) {}\nconst jobsThisWeek = pipelineJobs.filter(j => isThisWeek(j.created_at ?? j.CreatedAt));\nconst jobsByStatus = {};\nconst jobsByStage = {};\nfor (const j of jobsThisWeek) {\n const s = j.status ?? 'unknown';\n const stage = j.stage ?? 'unknown';\n jobsByStatus[s] = (jobsByStatus[s] ?? 0) + 1;\n jobsByStage[stage] = (jobsByStage[stage] ?? 0) + 1;\n}\nconst jobsDone = jobsByStatus['completed'] ?? jobsByStatus['done'] ?? 0;\nconst jobsFailed = jobsByStatus['failed'] ?? jobsByStatus['error'] ?? 0;\nconst jobsTotal = jobsThisWeek.length;\nconst successRate = jobsTotal > 0 ? Math.round(jobsDone / jobsTotal * 100) : 0;\n\n// Bottleneck: Stage mit meisten Fehlern\nconst failedJobs = jobsThisWeek.filter(j => ['failed','error'].includes(j.status));\nconst failedByStage = {};\nfor (const j of failedJobs) {\n const stage = j.stage ?? 'unknown';\n failedByStage[stage] = (failedByStage[stage] ?? 0) + 1;\n}\nconst bottleneck = Object.entries(failedByStage).sort((a,b) => b[1]-a[1])[0];\n\n// \u2500\u2500 n8n Ausf\u00fchrungen \u2500\u2500\nlet executions = [];\ntry { executions = $('Fetch n8n Executions').first().json?.data ?? []; } catch(e) {}\nconst execThisWeek = executions.filter(e => isThisWeek(e.startedAt ?? e.created_at));\nconst execSuccess = execThisWeek.filter(e => e.status === 'success').length;\nconst execFailed = execThisWeek.filter(e => ['error','failed'].includes(e.status)).length;\nconst execRate = execThisWeek.length > 0 ? Math.round(execSuccess / execThisWeek.length * 100) : 0;\n\n// Top Workflows nach Ausf\u00fchrungen\nconst wfCount = {};\nfor (const e of execThisWeek) {\n const wfName = e.workflowData?.name ?? e.workflowId ?? 'unbekannt';\n wfCount[wfName] = (wfCount[wfName] ?? 0) + 1;\n}\nconst topWorkflows = Object.entries(wfCount).sort((a,b) => b[1]-a[1]).slice(0, 3);\n\n// \u2500\u2500 Content Opportunities \u2500\u2500\nlet opportunities = [];\ntry { opportunities = $('Fetch Content Opportunities').first().json?.data ?? []; } catch(e) {}\nconst newOpportunities = opportunities.filter(o => isThisWeek(o.created_at ?? o.CreatedAt));\nconst topOpportunities = newOpportunities.slice(0, 3);\n\n// \u2500\u2500 Gesamtbewertung \u2500\u2500\nconst contentScore = piecesThisWeek.length >= 5 ? '\ud83d\udfe2' : piecesThisWeek.length >= 2 ? '\ud83d\udfe1' : '\ud83d\udd34';\nconst pipelineScore = successRate >= 80 ? '\ud83d\udfe2' : successRate >= 50 ? '\ud83d\udfe1' : '\ud83d\udd34';\nconst n8nScore = execRate >= 90 ? '\ud83d\udfe2' : execRate >= 70 ? '\ud83d\udfe1' : '\ud83d\udd34';\n\n// \u2500\u2500 Report zusammenbauen \u2500\u2500\nconst kw = Math.ceil((new Date().getTime() - new Date(new Date().getFullYear(), 0, 1).getTime()) / (7 * msPerDay));\nconst dateStr = new Date().toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric', timeZone: 'Europe/Berlin' });\n\nlet report = `\ud83d\udcca *AIOS Weekly Summary \u2014 KW${kw}* (${dateStr})\\n`;\nreport += `\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\\n\\n`;\n\n// KPI-\u00dcberblick\nreport += `*KPIs auf einen Blick:*\\n`;\nreport += `${contentScore} Content: ${piecesThisWeek.length} neue Pieces\\n`;\nreport += `${pipelineScore} Pipeline: ${successRate}% Erfolgsrate (${jobsDone}/${jobsTotal} Jobs)\\n`;\nreport += `${n8nScore} n8n: ${execRate}% Erfolgsrate (${execSuccess}/${execThisWeek.length} Runs)\\n\\n`;\n\n// Content-Produktion\nreport += `*\ud83d\udcdd Content-Produktion:*\\n`;\nif (piecesThisWeek.length === 0) {\n report += `\u2022 Keine neuen Pieces diese Woche\\n`;\n} else {\n const statusLabels = { published: 'Published', approved: 'Approved', review: 'In Review', draft: 'Draft', idea: 'Idee' };\n for (const [s, count] of Object.entries(byStatus)) {\n report += `\u2022 ${statusLabels[s] ?? s}: ${count}\\n`;\n }\n}\nif (topPieces.length > 0) {\n report += `\\n*Top Pieces:*\\n`;\n for (const p of topPieces) {\n const icon = p.status === 'published' ? '\u2705' : p.status === 'approved' ? '\ud83d\udfe2' : '\ud83d\udcdd';\n const title = (p.title ?? p.topic ?? 'Unbekannt').substring(0, 50);\n report += `${icon} ${title}\\n`;\n }\n}\nreport += `\\n`;\n\n// Pipeline-Gesundheit\nreport += `*\u2699\ufe0f Pipeline-Gesundheit:*\\n`;\nif (jobsTotal === 0) {\n report += `\u2022 Keine Jobs diese Woche\\n`;\n} else {\n report += `\u2022 Gesamt: ${jobsTotal} | \u2705 ${jobsDone} | \u274c ${jobsFailed}\\n`;\n if (bottleneck) {\n report += `\u2022 \ud83d\udea8 Bottleneck: Stage \"${bottleneck[0]}\" (${bottleneck[1]} Fehler)\\n`;\n }\n}\nreport += `\\n`;\n\n// n8n-Statistik\nreport += `*\ud83d\udd04 n8n-Aktivit\u00e4t:*\\n`;\nreport += `\u2022 ${execThisWeek.length} Runs | \u2705 ${execSuccess} | \u274c ${execFailed}\\n`;\nif (topWorkflows.length > 0) {\n report += `\u2022 Aktivste Workflows:\\n`;\n for (const [name, count] of topWorkflows) {\n const shortName = name.substring(0, 35);\n report += ` - ${shortName}: ${count}x\\n`;\n }\n}\nreport += `\\n`;\n\n// Content-Chancen\nif (newOpportunities.length > 0) {\n report += `*\ud83d\udca1 Neue Content-Chancen (${newOpportunities.length}):*\\n`;\n for (const o of topOpportunities) {\n const topic = (o.topic ?? o.keyword ?? o.title ?? 'Unbekannt').substring(0, 45);\n report += `\u2022 ${topic}\\n`;\n }\n report += `\\n`;\n}\n\n// Empfehlung\nreport += `*\ud83d\udccc Fokus n\u00e4chste Woche:*\\n`;\nif (bottleneck) {\n report += `\u2022 Stage \"${bottleneck[0]}\" debuggen (${bottleneck[1]} Fehler)\\n`;\n}\nif (piecesThisWeek.length < 3) {\n report += `\u2022 Content-Produktion hochfahren (Ziel: 5+ Pieces/Woche)\\n`;\n}\nif (newOpportunities.length > 0) {\n const bestOpportunity = topOpportunities[0];\n const topic = (bestOpportunity?.topic ?? bestOpportunity?.keyword ?? 'Trend-Thema').substring(0, 40);\n report += `\u2022 Beste Chance: \"${topic}\" aufgreifen\\n`;\n}\nif (!bottleneck && piecesThisWeek.length >= 3 && newOpportunities.length === 0) {\n report += `\u2022 Alles im gr\u00fcnen Bereich \u2014 weiter so! \ud83d\ude80\\n`;\n}\n\nreturn [{ json: { report } }];"
}
},
{
"id": "435-send",
"name": "Send to Telegram",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1000,
440
],
"parameters": {
"method": "POST",
"url": "=https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN }}/sendMessage",
"authentication": "none",
"sendBody": true,
"specifyBody": "string",
"body": "={{ JSON.stringify({ chat_id: $env.TELEGRAM_ALLOWED_CHAT_ID, text: $json.report, parse_mode: 'Markdown' }) }}",
"options": {
"timeout": 10000
}
},
"onError": "continueRegularOutput"
}
],
"connections": {
"Every Monday 09:00": {
"main": [
[
{
"node": "Fetch Content Pieces",
"type": "main",
"index": 0
},
{
"node": "Fetch Pipeline Jobs",
"type": "main",
"index": 0
},
{
"node": "Fetch n8n Executions",
"type": "main",
"index": 0
},
{
"node": "Fetch Content Opportunities",
"type": "main",
"index": 0
}
]
]
},
"Fetch Content Pieces": {
"main": [
[
{
"node": "Weekly Analysis",
"type": "main",
"index": 0
}
]
]
},
"Fetch Pipeline Jobs": {
"main": [
[
{
"node": "Weekly Analysis",
"type": "main",
"index": 0
}
]
]
},
"Fetch n8n Executions": {
"main": [
[
{
"node": "Weekly Analysis",
"type": "main",
"index": 0
}
]
]
},
"Fetch Content Opportunities": {
"main": [
[
{
"node": "Weekly Analysis",
"type": "main",
"index": 0
}
]
]
},
"Weekly Analysis": {
"main": [
[
{
"node": "Send to Telegram",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1",
"saveDataErrorExecution": "all",
"saveDataSuccessExecution": "none"
},
"staticData": null,
"tags": [
"content",
"reporting"
],
"meta": {
"description": "435 \u2014 W\u00f6chentlicher Summary: Content-Produktion, Pipeline-Gesundheit, n8n-Stats, Content-Chancen \u2014 jeden Montag 09:00 via Telegram"
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
40_435_WEEKLY_SUMMARY. Uses httpRequest. Scheduled trigger; 7 nodes.
Source: https://github.com/timo-goetz-ai/apki-core-platform/blob/main/automations/n8n-workflows/content-pipeline/40_435_WEEKLY_SUMMARY.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Birthday Automation - Production (Fixed). Uses stopAndError, httpRequest, emailSend, bannerbear. Scheduled trigger; 86 nodes.
This template runs two scheduled workflows to govern Microsoft Entra ID (Azure AD) guest accounts by detecting stale users via Microsoft Graph, staging deletions in SharePoint with a 72-hour window, n
Jira-Allure-Auto-Qa. Uses httpRequest, jira. Scheduled trigger; 68 nodes.
Spotify-Sync-Surrealdb-V1. Uses httpRequest, n8n-nodes-surrealdb, spotify. Scheduled trigger; 62 nodes.
As n8n instances scale, teams often lose track of sub-workflows—who uses them, where they are referenced, and whether they can be safely updated. This leads to inefficiencies like unnecessary copies o