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": "24h AI Recovery",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "hours",
"hoursInterval": 23
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.3,
"position": [
-192,
0
],
"id": "867641de-109f-429b-be79-4ebe98e20c9a",
"name": "Schedule Trigger (24h)"
},
{
"parameters": {
"options": {}
},
"type": "n8n-nodes-base.splitInBatches",
"typeVersion": 3,
"position": [
688,
0
],
"id": "9351104d-62a2-44b6-b947-5e56142be633",
"name": "Loop Over Articles"
},
{
"parameters": {
"jsCode": "const item = $input.first();\nconst textForLLM = `${item.json.title}\\n\\n${item.json.content || item.json.content_clean || ''}`;\n\nconst systemPrompt = 'You are a news analyst. Analyze the article and determine:\\n1. Whether it relates to Arctic topics\\n2. If yes, to which category\\n3. Create a brief summary\\nRespond ONLY in JSON format without additional text.';\n\nconst userPrompt = [\n 'You are an AI assistant analyzing news articles for an Arctic news aggregation system.',\n '',\n 'TASK: Analyze the article and return a JSON object with exactly these three fields:',\n '{',\n ' \"is_arctic\": boolean,',\n ' \"arctic_topic\": string,',\n ' \"summary_ai\": string',\n '}',\n '',\n 'FIELD DEFINITIONS:',\n '',\n '1. is_arctic (boolean): true if Arctic-related, false otherwise.',\n ' Consider Arctic-related if it mentions: Arctic region/countries/territories,',\n ' Arctic shipping/Northern Sea Route, Arctic climate/environment/wildlife,',\n ' Arctic resources (oil/gas/minerals), Arctic indigenous peoples,',\n ' Arctic research/expeditions, Arctic geopolitics/military, Arctic infrastructure.',\n '',\n '2. arctic_topic (string):',\n ' - If is_arctic is false: \"\u041d\u0435 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u043a \u0410\u0440\u043a\u0442\u0438\u043a\u0435\"',\n ' - If is_arctic is true, pick ONE from:',\n ' \"\u0410\u0440\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0441\u0443\u0434\u043e\u0445\u043e\u0434\u0441\u0442\u0432\u043e\", \"\u041a\u043b\u0438\u043c\u0430\u0442 \u0438 \u044d\u043a\u043e\u043b\u043e\u0433\u0438\u044f\", \"\u042d\u043d\u0435\u0440\u0433\u0435\u0442\u0438\u043a\u0430 \u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u044b\",',\n ' \"\u0413\u0435\u043e\u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430 \u0438 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c\", \"\u041a\u043e\u0440\u0435\u043d\u043d\u044b\u0435 \u043d\u0430\u0440\u043e\u0434\u044b\", \"\u041d\u0430\u0443\u043a\u0430 \u0438 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f\",',\n ' \"\u0418\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0438 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u0435\"',\n '',\n '3. summary_ai (string): 2-3 sentence summary in Russian.',\n '',\n 'ARTICLE:',\n textForLLM,\n '',\n 'Return ONLY valid JSON, no additional text or markdown.'\n].join('\\n');\n\nconst requestBody = {\n model: 'nvidia/nemotron-3-super-120b-a12b:free',\n messages: [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: userPrompt }\n ],\n response_format: { type: 'json_object' },\n temperature: 0.3,\n max_tokens: 1500\n};\n\nitem.json.llm_request_body = JSON.stringify(requestBody);\nitem.json.article_id = item.json.id;\n\nreturn [item];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
928,
0
],
"id": "0762a98f-d709-4210-9ddd-031c11c4a613",
"name": "Build Request Body"
},
{
"parameters": {
"method": "POST",
"url": "https://openrouter.ai/api/v1/chat/completions",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "=Bearer \u0412\u0430\u0448_\u043a\u043b\u044e\u0447"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ $json.llm_request_body }}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
1168,
0
],
"id": "bce49a5f-335f-4cde-a3cd-31da6094f63b",
"name": "AnalysAI"
},
{
"parameters": {
"jsCode": "const response = $input.first().json;\nconst articleId = $('Build Request Body').first().json.article_id;\n\nconst contentRaw = response.choices?.[0]?.message?.content;\n\nif (!contentRaw) {\n throw new Error('\u041d\u0435\u0442 content \u0432 \u043e\u0442\u0432\u0435\u0442\u0435 LLM');\n}\n\nconst parsed = JSON.parse(contentRaw.trim());\n\nconst endTime = new Date();\n\nreturn [{\n json: {\n article_id: articleId,\n is_arctic: parsed.is_arctic,\n arctic_topic: parsed.arctic_topic,\n summary_ai: parsed.summary_ai,\n tokens_used: response.usage?.total_tokens,\n processed_at: endTime.toISOString()\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1408,
0
],
"id": "491197fd-877e-4baa-9963-43c7503943e3",
"name": "Parse LLM Response"
},
{
"parameters": {
"operation": "update",
"collection": "news",
"itemId": "={{ $json.article_id }}",
"collectionFields": {
"fields": {
"field": [
{
"name": "summary_ai",
"value": "={{ $json.summary_ai }}"
},
{
"name": "is_arctic",
"value": "={{ $json.is_arctic }}"
},
{
"name": "arctic_topic",
"value": "={{ $json.arctic_topic }}"
},
{
"name": "tokens_used",
"value": "={{ $json.tokens_used }}"
},
{
"name": "processed_at",
"value": "={{ $json.processed_at }}"
}
]
}
}
},
"type": "@directus/n8n-nodes-directus.directus",
"typeVersion": 1,
"position": [
1648,
0
],
"id": "a5b82235-cc01-497b-a388-f2d0bf09c4b4",
"name": "Update Article with AI Response",
"credentials": {
"directusApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const items = $input.all();\nconst unprocessed = [];\n\nfor (const item of items) {\n const ai = item.json.summary_ai;\n \n // \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c, \u0435\u0441\u043b\u0438 summary_ai \u043f\u0443\u0441\u0442\u043e\u0439, null \u0438\u043b\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0443\n if (!ai || ai.trim() === '' || ai === '\u0422\u0435\u0441\u0442 \u0431\u0435\u0437 AI') {\n unprocessed.push(item);\n }\n}\n\nconsole.log(`\u0412\u0441\u0435\u0433\u043e \u0441\u0442\u0430\u0442\u0435\u0439: ${items.length}, \u0431\u0435\u0437 AI: ${unprocessed.length}`);\nreturn unprocessed;"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
384,
0
],
"id": "0605b0c8-9072-4f3c-aa81-9f82603c6af2",
"name": "Code in JavaScript"
},
{
"parameters": {
"url": "http://localhost:8055/items/news",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "filter[summary_ai][_null]",
"value": "true"
},
{
"name": "limit",
"value": "50"
},
{
"name": "sort",
"value": "-id"
}
]
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer \u0412\u0430\u0448_\u043a\u043b\u044e\u0447"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
0,
0
],
"id": "e1f47a9d-d45f-46cf-ad8a-008f786bd95d",
"name": "HTTP Request"
},
{
"parameters": {
"jsCode": "// \u0411\u0435\u0440\u0435\u043c \u043e\u0442\u0432\u0435\u0442 \u043e\u0442 Directus API \u0438 \u0440\u0430\u0437\u0431\u0438\u0432\u0430\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432 data \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 items\nconst response = $input.first().json;\nconst articles = response.data || [];\n\nconsole.log(` \u041d\u0430\u0439\u0434\u0435\u043d\u043e \u043d\u0435\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0445 \u0441\u0442\u0430\u0442\u0435\u0439: ${articles.length}`);\n\nif (articles.length === 0) {\n console.log(' \u041d\u0435\u0442 \u0441\u0442\u0430\u0442\u0435\u0439 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u043c.');\n return [];\n}\n\nreturn articles.map(article => ({ json: article }));"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
208,
0
],
"id": "1b540e40-759a-4586-a693-324cbd61adba",
"name": "Code in JavaScript1"
}
],
"connections": {
"Schedule Trigger (24h)": {
"main": [
[
{
"node": "HTTP Request",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Articles": {
"main": [
[],
[
{
"node": "Build Request Body",
"type": "main",
"index": 0
}
]
]
},
"Build Request Body": {
"main": [
[
{
"node": "AnalysAI",
"type": "main",
"index": 0
}
]
]
},
"AnalysAI": {
"main": [
[
{
"node": "Parse LLM Response",
"type": "main",
"index": 0
}
]
]
},
"Parse LLM Response": {
"main": [
[
{
"node": "Update Article with AI Response",
"type": "main",
"index": 0
}
]
]
},
"Update Article with AI Response": {
"main": [
[
{
"node": "Loop Over Articles",
"type": "main",
"index": 0
}
]
]
},
"Code in JavaScript": {
"main": [
[
{
"node": "Loop Over Articles",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request": {
"main": [
[
{
"node": "Code in JavaScript1",
"type": "main",
"index": 0
}
]
]
},
"Code in JavaScript1": {
"main": [
[
{
"node": "Code in JavaScript",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1",
"binaryMode": "separate"
},
"versionId": "5168470f-3ce2-463e-be40-32adb306de88",
"meta": {
"templateCredsSetupCompleted": true
},
"nodeGroups": [],
"id": "8eU5RKvezYwMN9ov",
"tags": []
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
directusApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
24h AI Recovery. Uses httpRequest, @directus/n8n-nodes-directus. Scheduled trigger; 9 nodes.
Source: https://github.com/orehys/Pulse_artic/blob/cc4b1428490b6d28496af9c02c517a35e5f7af45/n8n/24h_AI_Recovery.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