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": "30_350_CONTENT_FORECAST",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 14,
"triggerAtMinute": 0
}
]
},
"cronExpression": "0 14 * * 5"
},
"id": "schedule-trigger",
"name": "Freitag 14:00",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
240,
300
]
},
{
"parameters": {},
"id": "manual-trigger",
"name": "Manuell starten",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
240,
480
]
},
{
"parameters": {
"method": "GET",
"url": "https://directus.automation-plus-ki.de/items/300_trends?limit=20&sort=-created_at",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer ={{ $env.DIRECTUS_TOKEN }}"
}
]
}
},
"id": "fetch-trends",
"name": "Trends der letzten 30 Tage",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
460,
260
]
},
{
"parameters": {
"method": "GET",
"url": "https://directus.automation-plus-ki.de/items/310_sentiment?limit=10&sort=-created_at",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer ={{ $env.DIRECTUS_TOKEN }}"
}
]
}
},
"id": "fetch-sentiment",
"name": "Sentiment-Daten laden",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
460,
440
]
},
{
"parameters": {
"method": "GET",
"url": "https://directus.automation-plus-ki.de/items/320_content_opportunities?limit=10&sort=-created_at",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer ={{ $env.DIRECTUS_TOKEN }}"
}
]
}
},
"id": "fetch-opportunities",
"name": "Top Opportunities laden",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
460,
620
]
},
{
"parameters": {
"mode": "combine",
"mergeByFields": {
"values": []
},
"options": {}
},
"id": "merge-all",
"name": "Daten zusammenf\u00fchren",
"type": "n8n-nodes-base.merge",
"typeVersion": 3,
"position": [
680,
440
]
},
{
"parameters": {
"jsCode": "// Alle drei Datens\u00e4tze zu einem Forecast-Prompt kombinieren\nconst items = $input.all();\n\nconst trends = items[0]?.json?.data ?? [];\nconst sentiments = items[1]?.json?.data ?? [];\nconst opportunities = items[2]?.json?.data ?? [];\n\nconst trendsText = trends.slice(0, 10).map((t, i) =>\n `${i+1}. ${t.topic ?? t.keyword ?? t.title ?? JSON.stringify(t).substring(0,80)}`\n).join('\\n');\n\nconst sentimentText = sentiments.slice(0, 5).map((s) =>\n `- ${s.topic ?? s.keyword ?? ''}: ${s.sentiment ?? s.score ?? s.label ?? 'neutral'}`\n).join('\\n');\n\nconst oppText = opportunities.slice(0, 8).map((o, i) =>\n `${i+1}. ${o.topic ?? o.title ?? ''} (Score: ${o.opportunity_score ?? 'n/a'})`\n).join('\\n');\n\nconst today = new Date();\nconst in14Days = new Date(today.getTime() + 14*24*60*60*1000);\nconst dateRange = `${today.toISOString().split('T')[0]} bis ${in14Days.toISOString().split('T')[0]}`;\n\nconst prompt = `Du bist ein Content-Stratege spezialisiert auf KI-Themen im deutschsprachigen Raum (DACH).\n\nAnalysiere folgende Daten und erstelle einen 2-Wochen Content-Forecast.\n\n## AKTUELLE TRENDS (letzte 30 Tage)\n${trendsText || 'Keine Trend-Daten verf\u00fcgbar'}\n\n## SENTIMENT-ANALYSE\n${sentimentText || 'Keine Sentiment-Daten verf\u00fcgbar'}\n\n## TOP CONTENT-CHANCEN\n${oppText || 'Keine Opportunity-Daten verf\u00fcgbar'}\n\n## DEIN AUFTRAG\nErstelle einen Content-Kalender f\u00fcr: ${dateRange}\n\nLiefere NUR valides JSON (kein Text drumherum):\n{\n \"forecast_period\": \"${dateRange}\",\n \"market_pulse\": \"2-3 S\u00e4tze zur aktuellen Stimmungslage\",\n \"hot_topics_now\": [\"Thema1\", \"Thema2\", \"Thema3\"],\n \"upcoming_topics\": [\"Thema1\", \"Thema2\"],\n \"topics_declining\": [\"Thema1\"],\n \"recommended_pieces\": [\n {\n \"topic\": \"Konkretes Thema\",\n \"category\": \"KI-Tools\",\n \"publish_date\": \"YYYY-MM-DD\",\n \"target_platforms\": \"blog,linkedin\",\n \"priority\": \"high\",\n \"reasoning\": \"Kurze Begr\u00fcndung\"\n }\n ]\n}\nErstelle genau 7 recommended_pieces. Variiere Kategorien, Plattformen und Daten \u00fcber 14 Tage.`;\n\nreturn [{ json: { prompt, date_range: dateRange } }];"
},
"id": "build-forecast-prompt",
"name": "Forecast-Prompt bauen",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
900,
440
]
},
{
"parameters": {
"method": "POST",
"url": "=https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key={{ $env.GEMINI_API_KEY }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "json",
"body": "={ \"contents\": [{ \"role\": \"user\", \"parts\": [{ \"text\": \"{{ $json.prompt }}\" }] }], \"generationConfig\": { \"temperature\": 0.6, \"maxOutputTokens\": 2048 } }"
},
"id": "gemini-forecast",
"name": "Gemini: Forecast generieren",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1120,
440
]
},
{
"parameters": {
"jsCode": "const res = $input.first().json;\nconst raw = res.candidates?.[0]?.content?.parts?.[0]?.text ?? '{}';\n\nlet forecast = {};\ntry {\n const match = raw.match(/\\{[\\s\\S]*\\}/);\n if (match) forecast = JSON.parse(match[0]);\n} catch(_) {\n forecast = { raw };\n}\n\nconst pieces = forecast.recommended_pieces ?? [];\nreturn pieces.map(p => ({ json: {\n ...p,\n market_pulse: forecast.market_pulse ?? '',\n forecast_period: forecast.forecast_period ?? '',\n hot_topics_now: JSON.stringify(forecast.hot_topics_now ?? []),\n upcoming_topics: JSON.stringify(forecast.upcoming_topics ?? [])\n} }));"
},
"id": "parse-forecast",
"name": "Forecast parsen",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1340,
440
]
},
{
"parameters": {
"method": "POST",
"url": "https://directus.automation-plus-ki.de/items/330_knowledge_items",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer ={{ $env.DIRECTUS_TOKEN }}"
}
]
},
"sendBody": true,
"contentType": "json",
"body": "={ \"piece_id\": \"forecast-{{ $now.format('YYYYMMDD') }}-{{ $itemIndex }}\", \"title\": \"{{ $json.topic }}\", \"topic\": \"{{ $json.topic }}\", \"category\": \"{{ $json.category }}\", \"status\": \"idea\", \"target_platforms\": \"{{ $json.target_platforms }}\", \"scheduled_at\": \"{{ $json.publish_date }}T09:00:00.000Z\", \"excerpt\": \"Forecast-Empfehlung: {{ $json.reasoning }}\" }"
},
"id": "create-idea-pieces",
"name": "Content-Pieces anlegen",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1560,
440
]
},
{
"parameters": {
"method": "POST",
"url": "https://directus.automation-plus-ki.de/items/audit_log",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer ={{ $env.DIRECTUS_TOKEN }}"
}
]
},
"sendBody": true,
"contentType": "json",
"body": "={ \"ts\": \"{{ new Date().toISOString() }}\", \"actor\": \"30_350_CONTENT_FORECAST\", \"action\": \"forecast.generated\", \"resource_type\": \"content_pieces\", \"result\": \"ok\" }"
},
"id": "audit-log",
"name": "Audit Log",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1780,
440
]
}
],
"connections": {
"Freitag 14:00": {
"main": [
[
{
"node": "Trends der letzten 30 Tage",
"type": "main",
"index": 0
},
{
"node": "Sentiment-Daten laden",
"type": "main",
"index": 0
},
{
"node": "Top Opportunities laden",
"type": "main",
"index": 0
}
]
]
},
"Manuell starten": {
"main": [
[
{
"node": "Trends der letzten 30 Tage",
"type": "main",
"index": 0
},
{
"node": "Sentiment-Daten laden",
"type": "main",
"index": 0
},
{
"node": "Top Opportunities laden",
"type": "main",
"index": 0
}
]
]
},
"Trends der letzten 30 Tage": {
"main": [
[
{
"node": "Daten zusammenf\u00fchren",
"type": "main",
"index": 0
}
]
]
},
"Sentiment-Daten laden": {
"main": [
[
{
"node": "Daten zusammenf\u00fchren",
"type": "main",
"index": 1
}
]
]
},
"Top Opportunities laden": {
"main": [
[
{
"node": "Daten zusammenf\u00fchren",
"type": "main",
"index": 2
}
]
]
},
"Daten zusammenf\u00fchren": {
"main": [
[
{
"node": "Forecast-Prompt bauen",
"type": "main",
"index": 0
}
]
]
},
"Forecast-Prompt bauen": {
"main": [
[
{
"node": "Gemini: Forecast generieren",
"type": "main",
"index": 0
}
]
]
},
"Gemini: Forecast generieren": {
"main": [
[
{
"node": "Forecast parsen",
"type": "main",
"index": 0
}
]
]
},
"Forecast parsen": {
"main": [
[
{
"node": "Content-Pieces anlegen",
"type": "main",
"index": 0
}
]
]
},
"Content-Pieces anlegen": {
"main": [
[
{
"node": "Audit Log",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"tags": [
"research",
"forecast",
"content-planning"
]
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
30_350_CONTENT_FORECAST. Uses httpRequest. Scheduled trigger; 11 nodes.
Source: https://github.com/timo-goetz-ai/apki-core-platform/blob/5cd9c9d9ed0ed464da995af94683e9301965a3bc/automations/n8n-workflows/research/30_350_CONTENT_FORECAST.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