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": "AI Pulse \u2014 Scoring (Pass 1)",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "hours",
"hoursInterval": 4
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.3,
"position": [
0,
0
],
"id": "121cd46b-5e19-4844-94f7-68a6edfd214c",
"name": "Schedule Trigger"
},
{
"parameters": {
"language": "pythonNative",
"pythonCode": "import sqlite3\n\ndb_path = \"/data/ai-pulse/ai-pulse.db\"\nconn = sqlite3.connect(db_path)\nconn.row_factory = sqlite3.Row\ncursor = conn.cursor()\n\ncursor.execute(\"\"\"\n SELECT id, title, url, source_name, source_type, raw_content\n FROM articles\n WHERE relevance_score = 0\n ORDER BY ingested_at DESC\n LIMIT 200\n\"\"\")\nrows = cursor.fetchall()\nconn.close()\n\nreturn [{\"json\": dict(row)} for row in rows]"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
224,
96
],
"id": "44ed2bff-e695-45f9-a4d3-3780f38e1216",
"name": "Fetch Unscored Articles"
},
{
"parameters": {
"options": {}
},
"type": "n8n-nodes-base.splitInBatches",
"typeVersion": 3,
"position": [
448,
96
],
"id": "5704552c-3d07-4152-b5ed-cdd1395cd6fe",
"name": "Loop Articles"
},
{
"parameters": {
"language": "pythonNative",
"pythonCode": "import json as json_lib\n\nitems = _items\nresult = []\n\nfor item in items:\n data = item['json'] if 'json' in item else item\n \n title = str(data.get('title', 'Untitled'))[:300]\n source_name = str(data.get('source_name', 'Unknown'))\n raw = str(data.get('raw_content', ''))[:3000]\n \n prompt = (\n \"You are an AI relevance scorer for a Software Engineer interested in:\\n\"\n \"1. AI-powered dev tools (Copilot, Cursor, Gemini CLI, Claude Code, Windsurf, etc.)\\n\"\n \"2. AI agents & automation (MCP, tool use, agentic workflows, autonomous coding agents)\\n\"\n \"3. New model releases & benchmarks (GPT, Claude, Gemini, open-source LLMs)\\n\"\n \"4. SDLC excellence with AI (testing, CI/CD, code review, QA automation, deployment)\\n\"\n \"5. Context engineering & prompt engineering (system prompts, RAG, context windows, prompt patterns)\\n\"\n \"6. AI-assisted automation (workflow automation, n8n, scripting, infrastructure as code)\\n\\n\"\n \"Scoring guidelines:\\n\"\n \"- 80-100: Directly actionable for a hands-on engineer \u2014 new tools, releases, techniques they can use today\\n\"\n \"- 60-79: Relevant industry development \u2014 worth knowing but not immediately actionable\\n\"\n \"- 40-59: Tangentially related \u2014 general AI news with some engineering relevance\\n\"\n \"- 0-39: Not relevant \u2014 business/policy news, hype, speculation, or unrelated topics\\n\\n\"\n f\"Given this article:\\nTitle: {title}\\nSource: {source_name}\\n\"\n f\"Content: {raw}\\n\\n\"\n \"Return ONLY valid JSON, no other text:\\n\"\n \"{\\\"relevance_score\\\": <0-100>, \\\"category\\\": \\\"<dev-tools|agents-automation|model-releases|sdlc-ai|context-engineering|general>\\\", \\\"reasoning\\\": \\\"<one sentence>\\\"}\"\n )\n\n body = json_lib.dumps({\n \"model\": \"mistral\",\n \"prompt\": prompt,\n \"stream\": False,\n \"keep_alive\": \"10m\"\n })\n\n result.append({\"json\": {\n \"id\": data.get('id', 0),\n \"title\": title,\n \"source_name\": source_name,\n \"request_body\": body\n }})\n\nreturn result"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
672,
32
],
"id": "ea0ff242-499a-4c79-8260-2142aa982c20",
"name": "Prepare Prompt"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "5340ab1b-e7c8-4436-8c05-63283057a95a",
"name": "article_id",
"value": "={{ $('Prepare Prompt').item.json.id }}",
"type": "string"
}
]
},
"includeOtherFields": true,
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1120,
32
],
"id": "7d93aed2-8b38-4bdc-93a8-1b5f0b5e5c3b",
"name": "Add Article ID"
},
{
"parameters": {
"method": "POST",
"url": "http://host.docker.internal:11434/api/generate",
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={{ $json.request_body }}",
"options": {
"timeout": 120000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
896,
32
],
"id": "b412e266-fd42-45c8-88fb-f04a24e5729e",
"name": "Ollama Score Article",
"onError": "continueRegularOutput"
},
{
"parameters": {
"language": "pythonNative",
"pythonCode": "import sqlite3\nimport json as json_lib\n\ndb_path = \"/data/ai-pulse/ai-pulse.db\"\n\nitems = _items\narticle_id = 0\nrelevance_score = 0\ncategory = \"general\"\nreasoning = \"\"\nstatus = \"failed\"\n\nfor item in items:\n data = item['json'] if 'json' in item else item\n article_id = int(data.get('article_id', 0))\n response_text = str(data.get('response', ''))\n\n try:\n clean = response_text.strip()\n start = clean.find('{')\n end = clean.rfind('}') + 1\n if start >= 0 and end > start:\n parsed = json_lib.loads(clean[start:end])\n relevance_score = int(parsed.get('relevance_score', 0))\n category = str(parsed.get('category', 'general'))\n reasoning = str(parsed.get('reasoning', ''))\n status = \"success\"\n except:\n relevance_score = 1\n category = \"general\"\n status = \"parse_error\"\n\n if article_id > 0:\n conn = sqlite3.connect(db_path)\n cursor = conn.cursor()\n cursor.execute(\"\"\"\n UPDATE articles SET relevance_score = ?, category = ?\n WHERE id = ?\n \"\"\", (relevance_score, category, article_id))\n conn.commit()\n conn.close()\n\nreturn [{\"json\": {\"article_id\": article_id, \"score\": relevance_score, \"category\": category, \"reasoning\": reasoning, \"status\": status}}]"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1344,
96
],
"id": "6861ffc6-471e-4d22-becc-5fc3f0ad3029",
"name": "Update Article Score",
"onError": "continueRegularOutput"
},
{
"parameters": {},
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
0,
192
],
"id": "eafd3614-4919-4cc8-8e41-7b4af3573dc9",
"name": "When clicking \u2018Execute workflow\u2019"
}
],
"connections": {
"Schedule Trigger": {
"main": [
[
{
"node": "Fetch Unscored Articles",
"type": "main",
"index": 0
}
]
]
},
"Fetch Unscored Articles": {
"main": [
[
{
"node": "Loop Articles",
"type": "main",
"index": 0
}
]
]
},
"Loop Articles": {
"main": [
[],
[
{
"node": "Prepare Prompt",
"type": "main",
"index": 0
}
]
]
},
"Prepare Prompt": {
"main": [
[
{
"node": "Ollama Score Article",
"type": "main",
"index": 0
}
]
]
},
"Add Article ID": {
"main": [
[
{
"node": "Update Article Score",
"type": "main",
"index": 0
}
]
]
},
"Ollama Score Article": {
"main": [
[
{
"node": "Add Article ID",
"type": "main",
"index": 0
}
]
]
},
"Update Article Score": {
"main": [
[
{
"node": "Loop Articles",
"type": "main",
"index": 0
}
]
]
},
"When clicking \u2018Execute workflow\u2019": {
"main": [
[
{
"node": "Fetch Unscored Articles",
"type": "main",
"index": 0
}
]
]
}
},
"active": true,
"settings": {
"executionOrder": "v1",
"binaryMode": "separate",
"availableInMCP": false
},
"versionId": "b43914e0-7e47-415c-b428-24463b7f581f",
"id": "AF67hJBmcplOWDzq",
"tags": []
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
AI Pulse — Scoring (Pass 1). Uses httpRequest. Scheduled trigger; 8 nodes.
Source: https://github.com/sh3lan93/ai-pulse/blob/b616cb8446522055bc8679b9f6c03b08b07c1441/n8n-workflows/02-pass1-scoring.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.
WF-Main - XHS 主控制器. Uses scheduleTrigger, httpRequest, executeWorkflow, noOp. Scheduled trigger; 21 nodes.
Dm-Profile-Visitors. Uses httpRequest, googleSheets. Scheduled trigger; 21 nodes.
RSS to Multi-Channel Social (X / LinkedIn / Discord). Uses stickyNote, scheduleTrigger, httpRequest. Scheduled trigger; 19 nodes.
YouTube Channel to Notion. Uses stickyNote, scheduleTrigger, httpRequest, noOp. Scheduled trigger; 18 nodes.
Automate Droplet Snapshots On Digitalocean. Uses httpRequest, stickyNote. Scheduled trigger; 17 nodes.