Files
swarm-master/swarm-common/n8n-workflows/PlZywwqL8MRNEAN6.json
T
William Valentin ac3590df47 fix(n8n): harden evening digest workflow
Allow optional n8n execution, Obsidian note listing, and Obsidian save steps to continue on failure so the digest can still send when one local source is unavailable.
2026-06-05 13:06:52 -07:00

881 lines
30 KiB
JSON

{
"updatedAt": "2026-06-05T19:59:54.879Z",
"createdAt": "2026-05-13T21:40:33.847Z",
"id": "PlZywwqL8MRNEAN6",
"name": "Evening Digest",
"description": null,
"active": true,
"isArchived": false,
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 21 * * *"
}
]
}
},
"id": "a1b2c3d4-0001-4000-8000-000000000001",
"name": "Daily 9PM Schedule",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
0,
0
],
"onError": "continueRegularOutput"
},
{
"parameters": {
"method": "GET",
"url": "http://127.0.0.1:5678/api/v1/executions?status=success&limit=100",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
}
},
"id": "a1b2c3d4-0001-4000-8000-000000000002",
"name": "n8n Success Executions",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
240,
-200
],
"onError": "continueRegularOutput",
"credentials": {
"httpHeaderAuth": {
"id": "UPAHgUJVRqZQceL4",
"name": "n8n Public API (Failure Digest)"
}
},
"continueOnFail": true,
"alwaysOutputData": true
},
{
"parameters": {
"method": "GET",
"url": "http://127.0.0.1:5678/api/v1/executions?status=error&limit=50",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
}
},
"id": "a1b2c3d4-0001-4000-8000-000000000003",
"name": "n8n Failed Executions",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
240,
0
],
"onError": "continueRegularOutput",
"credentials": {
"httpHeaderAuth": {
"id": "UPAHgUJVRqZQceL4",
"name": "n8n Public API (Failure Digest)"
}
},
"continueOnFail": true,
"alwaysOutputData": true
},
{
"parameters": {
"method": "GET",
"url": "http://172.19.0.1:18809/health",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
}
},
"id": "a1b2c3d4-0001-4000-8000-000000000004",
"name": "Swarm Health",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
240,
200
],
"onError": "continueRegularOutput"
},
{
"parameters": {
"method": "GET",
"url": "http://172.19.0.1:27123/vault/Notes/",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
}
},
"id": "a1b2c3d4-0001-4000-8000-000000000005",
"name": "New Obsidian Notes",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
240,
400
],
"onError": "continueRegularOutput",
"credentials": {
"httpHeaderAuth": {
"id": "465Swz2b71O2KRAK",
"name": "Obsidian Local REST API"
}
},
"continueOnFail": true,
"alwaysOutputData": true
},
{
"parameters": {
"mode": "runOnceForAllItems",
"jsCode": "// Aggregate all collection results into a structured summary\nconst data = {};\n\n// Process successful executions\ntry {\n const successItems = $input.first()?.json?.data || [];\n const successByWorkflow = {};\n let totalSuccess = 0;\n for (const item of successItems) {\n const wfName = item.workflowData?.name || item.workflowId || 'Unknown';\n successByWorkflow[wfName] = (successByWorkflow[wfName] || 0) + 1;\n totalSuccess++;\n }\n data.successExecutions = { total: totalSuccess, byWorkflow: successByWorkflow };\n} catch(e) {\n data.successExecutions = { total: 0, byWorkflow: {}, error: e.message };\n}\n\n// Process failed executions\ntry {\n // Failed executions come from a separate input\n const failNode = $node['n8n Failed Executions']?.json;\n const failItems = failNode?.data || [];\n const failures = [];\n let totalFail = 0;\n for (const item of failItems) {\n const wfName = item.workflowData?.name || item.workflowId || 'Unknown';\n failures.push({\n workflow: wfName,\n id: item.id,\n stoppedAt: item.stoppedAt\n });\n totalFail++;\n }\n data.failedExecutions = { total: totalFail, failures: failures };\n} catch(e) {\n data.failedExecutions = { total: 0, failures: [], error: e.message };\n}\n\n// Swarm health\ntry {\n data.swarmHealth = $node['Swarm Health']?.json || { status: 'unavailable' };\n} catch(e) {\n data.swarmHealth = { status: 'error', error: e.message };\n}\n\n// New Obsidian notes\ntry {\n const obsResult = $node['New Obsidian Notes']?.json;\n const allFiles = obsResult?.files || [];\n // Filter for today's date in filename\n const today = new Intl.DateTimeFormat('en-CA', {\n timeZone: 'America/Los_Angeles',\n year: 'numeric', month: '2-digit', day: '2-digit'\n }).format(new Date()).replaceAll('/', '-');\n const todayFiles = allFiles.filter(f => {\n const name = typeof f === 'string' ? f : (f.name || f.path || '');\n return name.includes(today);\n });\n data.newNotes = todayFiles.map(f => typeof f === 'string' ? f : (f.name || f.path || JSON.stringify(f)));\n} catch(e) {\n data.newNotes = [];\n data.notesError = e.message;\n}\n\ndata.date = new Intl.DateTimeFormat('en-CA', {\n timeZone: 'America/Los_Angeles',\n year: 'numeric', month: '2-digit', day: '2-digit'\n}).format(new Date()).replaceAll('/', '-');\n\ndata.summary = JSON.stringify(data, null, 2);\n\nreturn [{ json: data }];"
},
"id": "a1b2c3d4-0001-4000-8000-000000000006",
"name": "Aggregate Data",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
500,
100
],
"onError": "continueRegularOutput"
},
{
"parameters": {
"method": "POST",
"url": "http://172.19.0.1:18806/v1/chat/completions",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ model: 'gemma-4-26B-A4B-it-UD-IQ2_M.gguf', temperature: 0.3, max_tokens: 800, messages: [{ role: 'system', content: 'You are an evening digest assistant. Given data about today\\'s automation runs, failures, new notes, and infrastructure health, produce a concise evening digest under 400 words. Use emojis for section headers. Format for Telegram/Markdown. Sections: 🔧 Executions Summary, ⚠️ Failures, 📝 New Notes, 🏥 Infrastructure Health, 📋 Action Items. Be factual and concise.' }, { role: 'user', content: 'Here is today\\'s data:\\n' + $json.summary }] }) }}",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
}
},
"id": "a1b2c3d4-0001-4000-8000-000000000007",
"name": "LLM Synthesis",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
740,
100
],
"onError": "continueRegularOutput"
},
{
"parameters": {
"mode": "runOnceForAllItems",
"jsCode": "// Extract LLM response text and prepare messages for Telegram/Discord/Obsidian\nlet text = '';\ntry {\n const llmResponse = $input.first()?.json;\n text = llmResponse?.choices?.[0]?.message?.content || '';\n // Strip code fences if present\n text = text.replace(/^```(?:markdown)?\\s*/i, '').replace(/```\\s*$/i, '').trim();\n} catch(e) {\n text = 'Evening digest generation encountered an error.';\n}\n\nif (!text) {\n text = '🌙 Evening Digest\\n\\nNo data collected today. All collection nodes may have failed.';\n}\n\n// Escape special chars for Telegram MarkdownV1\nlet telegramText = text;\n// Replace problematic markdown chars for Telegram\ntelegramText = telegramText.replace(/([_*\\[\\]()~`>#+\\-=|{}.!])/g, (m) => {\n // Keep basic markdown formatting\n if (['*', '_', '`'].includes(m)) return m;\n return '\\\\' + m;\n});\n\nconst today = new Intl.DateTimeFormat('en-CA', {\n timeZone: 'America/Los_Angeles',\n year: 'numeric', month: '2-digit', day: '2-digit'\n}).format(new Date()).replaceAll('/', '-');\n\nreturn [{\n json: {\n text: telegramText,\n discordText: text.substring(0, 2000),\n obsidianContent: `---\\ntitle: Evening Digest\\narea: infrastructure\\ntags: [infrastructure, digest, automation, daily, evening]\\ncreated: ${today}\\nupdated: ${today}\\nstatus: active\\n---\\n\\n# Evening Digest - ${today}\\n\\n${text}\\n`,\n notePath: `Notes/${today} Evening Digest.md`,\n date: today\n }\n}];"
},
"id": "a1b2c3d4-0001-4000-8000-000000000008",
"name": "Prepare Messages",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
980,
100
],
"onError": "continueRegularOutput"
},
{
"parameters": {
"chatId": "8367012007",
"text": "={{ $json.text }}",
"additionalFields": {
"parse_mode": "Markdown"
}
},
"id": "a1b2c3d4-0001-4000-8000-000000000009",
"name": "Send Telegram",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1,
"position": [
1220,
-100
],
"credentials": {
"telegramApi": {
"id": "aox4dyIWVSRdcH5z",
"name": "Telegram Bot (OpenClaw)"
}
}
},
{
"parameters": {
"method": "POST",
"url": "https://discord.com/api/v10/channels/1494453542243532932/messages",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ content: $json.discordText }) }}",
"options": {
"response": {
"response": {
"responseFormat": "text"
}
}
}
},
"id": "a1b2c3d4-0001-4000-8000-000000000010",
"name": "Send Discord",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1220,
100
],
"credentials": {
"httpHeaderAuth": {
"id": "UgPqYcoCNNIgr55m",
"name": "Discord Bot Auth"
}
}
},
{
"parameters": {
"method": "PUT",
"url": "={{ 'http://172.19.0.1:27123/vault/' + encodeURIComponent($json.notePath).replace(/%2F/g, '/') }}",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendBody": true,
"specifyBody": "raw",
"rawContentType": "text/markdown",
"body": "={{ $json.obsidianContent }}",
"options": {}
},
"id": "a1b2c3d4-0001-4000-8000-000000000011",
"name": "Save to Obsidian",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1220,
300
],
"credentials": {
"httpHeaderAuth": {
"id": "465Swz2b71O2KRAK",
"name": "Obsidian Local REST API"
}
},
"continueOnFail": true,
"alwaysOutputData": true
}
],
"connections": {
"Daily 9PM Schedule": {
"main": [
[
{
"node": "n8n Success Executions",
"type": "main",
"index": 0
},
{
"node": "n8n Failed Executions",
"type": "main",
"index": 0
},
{
"node": "Swarm Health",
"type": "main",
"index": 0
},
{
"node": "New Obsidian Notes",
"type": "main",
"index": 0
}
]
]
},
"n8n Success Executions": {
"main": [
[
{
"node": "Aggregate Data",
"type": "main",
"index": 0
}
]
]
},
"n8n Failed Executions": {
"main": [
[
{
"node": "Aggregate Data",
"type": "main",
"index": 0
}
]
]
},
"Swarm Health": {
"main": [
[
{
"node": "Aggregate Data",
"type": "main",
"index": 0
}
]
]
},
"New Obsidian Notes": {
"main": [
[
{
"node": "Aggregate Data",
"type": "main",
"index": 0
}
]
]
},
"Aggregate Data": {
"main": [
[
{
"node": "LLM Synthesis",
"type": "main",
"index": 0
}
]
]
},
"LLM Synthesis": {
"main": [
[
{
"node": "Prepare Messages",
"type": "main",
"index": 0
}
]
]
},
"Prepare Messages": {
"main": [
[
{
"node": "Send Telegram",
"type": "main",
"index": 0
},
{
"node": "Send Discord",
"type": "main",
"index": 0
},
{
"node": "Save to Obsidian",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1",
"callerPolicy": "workflowsFromSameOwner",
"availableInMCP": false,
"timezone": "America/Los_Angeles"
},
"staticData": {
"node:Daily 9PM Schedule": {
"recurrenceRules": []
}
},
"meta": null,
"pinData": null,
"versionId": "afb71f4d-6ac3-434d-b659-de003d47c339",
"activeVersionId": "afb71f4d-6ac3-434d-b659-de003d47c339",
"versionCounter": 11,
"triggerCount": 1,
"shared": [
{
"updatedAt": "2026-05-13T21:40:33.849Z",
"createdAt": "2026-05-13T21:40:33.849Z",
"role": "workflow:owner",
"workflowId": "PlZywwqL8MRNEAN6",
"projectId": "WGdp8QunI1tHpjXa",
"project": {
"updatedAt": "2026-03-11T21:08:10.005Z",
"createdAt": "2026-03-11T21:05:11.541Z",
"id": "WGdp8QunI1tHpjXa",
"name": "will will <will@wills-portal.com>",
"type": "personal",
"icon": null,
"description": null,
"creatorId": "5ad50ead-6e6a-4d12-ab5b-e5db15835bb5"
}
}
],
"tags": [],
"activeVersion": {
"updatedAt": "2026-05-13T21:40:33.854Z",
"createdAt": "2026-05-13T21:40:33.854Z",
"versionId": "afb71f4d-6ac3-434d-b659-de003d47c339",
"workflowId": "PlZywwqL8MRNEAN6",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 21 * * *"
}
]
}
},
"id": "a1b2c3d4-0001-4000-8000-000000000001",
"name": "Daily 9PM Schedule",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
0,
0
],
"onError": "continueRegularOutput"
},
{
"parameters": {
"method": "GET",
"url": "http://127.0.0.1:5678/api/v1/executions?status=success&limit=100",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
}
},
"id": "a1b2c3d4-0001-4000-8000-000000000002",
"name": "n8n Success Executions",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
240,
-200
],
"onError": "continueRegularOutput",
"credentials": {
"httpHeaderAuth": {
"id": "UPAHgUJVRqZQceL4",
"name": "n8n Public API (Failure Digest)"
}
}
},
{
"parameters": {
"method": "GET",
"url": "http://127.0.0.1:5678/api/v1/executions?status=error&limit=50",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
}
},
"id": "a1b2c3d4-0001-4000-8000-000000000003",
"name": "n8n Failed Executions",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
240,
0
],
"onError": "continueRegularOutput",
"credentials": {
"httpHeaderAuth": {
"id": "UPAHgUJVRqZQceL4",
"name": "n8n Public API (Failure Digest)"
}
}
},
{
"parameters": {
"method": "GET",
"url": "http://172.19.0.1:18809/health",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
}
},
"id": "a1b2c3d4-0001-4000-8000-000000000004",
"name": "Swarm Health",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
240,
200
],
"onError": "continueRegularOutput"
},
{
"parameters": {
"method": "GET",
"url": "http://172.19.0.1:27123/vault/Notes/",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
}
},
"id": "a1b2c3d4-0001-4000-8000-000000000005",
"name": "New Obsidian Notes",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
240,
400
],
"onError": "continueRegularOutput",
"credentials": {
"httpHeaderAuth": {
"id": "465Swz2b71O2KRAK",
"name": "Obsidian Local REST API"
}
}
},
{
"parameters": {
"mode": "runOnceForAllItems",
"jsCode": "// Aggregate all collection results into a structured summary\nconst data = {};\n\n// Process successful executions\ntry {\n const successItems = $input.first()?.json?.data || [];\n const successByWorkflow = {};\n let totalSuccess = 0;\n for (const item of successItems) {\n const wfName = item.workflowData?.name || item.workflowId || 'Unknown';\n successByWorkflow[wfName] = (successByWorkflow[wfName] || 0) + 1;\n totalSuccess++;\n }\n data.successExecutions = { total: totalSuccess, byWorkflow: successByWorkflow };\n} catch(e) {\n data.successExecutions = { total: 0, byWorkflow: {}, error: e.message };\n}\n\n// Process failed executions\ntry {\n // Failed executions come from a separate input\n const failNode = $node['n8n Failed Executions']?.json;\n const failItems = failNode?.data || [];\n const failures = [];\n let totalFail = 0;\n for (const item of failItems) {\n const wfName = item.workflowData?.name || item.workflowId || 'Unknown';\n failures.push({\n workflow: wfName,\n id: item.id,\n stoppedAt: item.stoppedAt\n });\n totalFail++;\n }\n data.failedExecutions = { total: totalFail, failures: failures };\n} catch(e) {\n data.failedExecutions = { total: 0, failures: [], error: e.message };\n}\n\n// Swarm health\ntry {\n data.swarmHealth = $node['Swarm Health']?.json || { status: 'unavailable' };\n} catch(e) {\n data.swarmHealth = { status: 'error', error: e.message };\n}\n\n// New Obsidian notes\ntry {\n const obsResult = $node['New Obsidian Notes']?.json;\n const allFiles = obsResult?.files || [];\n // Filter for today's date in filename\n const today = new Intl.DateTimeFormat('en-CA', {\n timeZone: 'America/Los_Angeles',\n year: 'numeric', month: '2-digit', day: '2-digit'\n }).format(new Date()).replaceAll('/', '-');\n const todayFiles = allFiles.filter(f => {\n const name = typeof f === 'string' ? f : (f.name || f.path || '');\n return name.includes(today);\n });\n data.newNotes = todayFiles.map(f => typeof f === 'string' ? f : (f.name || f.path || JSON.stringify(f)));\n} catch(e) {\n data.newNotes = [];\n data.notesError = e.message;\n}\n\ndata.date = new Intl.DateTimeFormat('en-CA', {\n timeZone: 'America/Los_Angeles',\n year: 'numeric', month: '2-digit', day: '2-digit'\n}).format(new Date()).replaceAll('/', '-');\n\ndata.summary = JSON.stringify(data, null, 2);\n\nreturn [{ json: data }];"
},
"id": "a1b2c3d4-0001-4000-8000-000000000006",
"name": "Aggregate Data",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
500,
100
],
"onError": "continueRegularOutput"
},
{
"parameters": {
"method": "POST",
"url": "http://172.19.0.1:18806/v1/chat/completions",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ model: 'gemma-4-26B-A4B-it-UD-IQ2_M.gguf', temperature: 0.3, max_tokens: 800, messages: [{ role: 'system', content: 'You are an evening digest assistant. Given data about today\\'s automation runs, failures, new notes, and infrastructure health, produce a concise evening digest under 400 words. Use emojis for section headers. Format for Telegram/Markdown. Sections: 🔧 Executions Summary, ⚠️ Failures, 📝 New Notes, 🏥 Infrastructure Health, 📋 Action Items. Be factual and concise.' }, { role: 'user', content: 'Here is today\\'s data:\\n' + $json.summary }] }) }}",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
}
},
"id": "a1b2c3d4-0001-4000-8000-000000000007",
"name": "LLM Synthesis",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
740,
100
],
"onError": "continueRegularOutput"
},
{
"parameters": {
"mode": "runOnceForAllItems",
"jsCode": "// Extract LLM response text and prepare messages for Telegram/Discord/Obsidian\nlet text = '';\ntry {\n const llmResponse = $input.first()?.json;\n text = llmResponse?.choices?.[0]?.message?.content || '';\n // Strip code fences if present\n text = text.replace(/^```(?:markdown)?\\s*/i, '').replace(/```\\s*$/i, '').trim();\n} catch(e) {\n text = 'Evening digest generation encountered an error.';\n}\n\nif (!text) {\n text = '🌙 Evening Digest\\n\\nNo data collected today. All collection nodes may have failed.';\n}\n\n// Escape special chars for Telegram MarkdownV1\nlet telegramText = text;\n// Replace problematic markdown chars for Telegram\ntelegramText = telegramText.replace(/([_*\\[\\]()~`>#+\\-=|{}.!])/g, (m) => {\n // Keep basic markdown formatting\n if (['*', '_', '`'].includes(m)) return m;\n return '\\\\' + m;\n});\n\nconst today = new Intl.DateTimeFormat('en-CA', {\n timeZone: 'America/Los_Angeles',\n year: 'numeric', month: '2-digit', day: '2-digit'\n}).format(new Date()).replaceAll('/', '-');\n\nreturn [{\n json: {\n text: telegramText,\n discordText: text.substring(0, 2000),\n obsidianContent: `---\\ntitle: Evening Digest\\narea: infrastructure\\ntags: [infrastructure, digest, automation, daily, evening]\\ncreated: ${today}\\nupdated: ${today}\\nstatus: active\\n---\\n\\n# Evening Digest - ${today}\\n\\n${text}\\n`,\n notePath: `Notes/${today} Evening Digest.md`,\n date: today\n }\n}];"
},
"id": "a1b2c3d4-0001-4000-8000-000000000008",
"name": "Prepare Messages",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
980,
100
],
"onError": "continueRegularOutput"
},
{
"parameters": {
"chatId": "8367012007",
"text": "={{ $json.text }}",
"additionalFields": {
"parse_mode": "Markdown"
}
},
"id": "a1b2c3d4-0001-4000-8000-000000000009",
"name": "Send Telegram",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1,
"position": [
1220,
-100
],
"credentials": {
"telegramApi": {
"id": "aox4dyIWVSRdcH5z",
"name": "Telegram Bot (OpenClaw)"
}
}
},
{
"parameters": {
"method": "POST",
"url": "https://discord.com/api/v10/channels/1494453542243532932/messages",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ content: $json.discordText }) }}",
"options": {
"response": {
"response": {
"responseFormat": "text"
}
}
}
},
"id": "a1b2c3d4-0001-4000-8000-000000000010",
"name": "Send Discord",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1220,
100
],
"credentials": {
"httpHeaderAuth": {
"id": "UgPqYcoCNNIgr55m",
"name": "Discord Bot Auth"
}
}
},
{
"parameters": {
"method": "PUT",
"url": "={{ 'http://172.19.0.1:27123/vault/' + encodeURIComponent($json.notePath).replace(/%2F/g, '/') }}",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendBody": true,
"specifyBody": "raw",
"rawContentType": "text/markdown",
"body": "={{ $json.obsidianContent }}",
"options": {}
},
"id": "a1b2c3d4-0001-4000-8000-000000000011",
"name": "Save to Obsidian",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1220,
300
],
"credentials": {
"httpHeaderAuth": {
"id": "465Swz2b71O2KRAK",
"name": "Obsidian Local REST API"
}
}
}
],
"connections": {
"Daily 9PM Schedule": {
"main": [
[
{
"node": "n8n Success Executions",
"type": "main",
"index": 0
},
{
"node": "n8n Failed Executions",
"type": "main",
"index": 0
},
{
"node": "Swarm Health",
"type": "main",
"index": 0
},
{
"node": "New Obsidian Notes",
"type": "main",
"index": 0
}
]
]
},
"n8n Success Executions": {
"main": [
[
{
"node": "Aggregate Data",
"type": "main",
"index": 0
}
]
]
},
"n8n Failed Executions": {
"main": [
[
{
"node": "Aggregate Data",
"type": "main",
"index": 0
}
]
]
},
"Swarm Health": {
"main": [
[
{
"node": "Aggregate Data",
"type": "main",
"index": 0
}
]
]
},
"New Obsidian Notes": {
"main": [
[
{
"node": "Aggregate Data",
"type": "main",
"index": 0
}
]
]
},
"Aggregate Data": {
"main": [
[
{
"node": "LLM Synthesis",
"type": "main",
"index": 0
}
]
]
},
"LLM Synthesis": {
"main": [
[
{
"node": "Prepare Messages",
"type": "main",
"index": 0
}
]
]
},
"Prepare Messages": {
"main": [
[
{
"node": "Send Telegram",
"type": "main",
"index": 0
},
{
"node": "Send Discord",
"type": "main",
"index": 0
},
{
"node": "Save to Obsidian",
"type": "main",
"index": 0
}
]
]
}
},
"authors": "will will",
"name": null,
"description": null,
"autosaved": false,
"workflowPublishHistory": [
{
"createdAt": "2026-05-13T21:40:40.515Z",
"id": 1432,
"workflowId": "PlZywwqL8MRNEAN6",
"versionId": "afb71f4d-6ac3-434d-b659-de003d47c339",
"event": "activated",
"userId": "5ad50ead-6e6a-4d12-ab5b-e5db15835bb5"
},
{
"createdAt": "2026-05-14T00:04:59.370Z",
"id": 1483,
"workflowId": "PlZywwqL8MRNEAN6",
"versionId": "afb71f4d-6ac3-434d-b659-de003d47c339",
"event": "activated",
"userId": "5ad50ead-6e6a-4d12-ab5b-e5db15835bb5"
},
{
"createdAt": "2026-05-14T00:04:59.415Z",
"id": 1485,
"workflowId": "PlZywwqL8MRNEAN6",
"versionId": "afb71f4d-6ac3-434d-b659-de003d47c339",
"event": "activated",
"userId": "5ad50ead-6e6a-4d12-ab5b-e5db15835bb5"
},
{
"createdAt": "2026-05-14T00:04:59.362Z",
"id": 1482,
"workflowId": "PlZywwqL8MRNEAN6",
"versionId": "afb71f4d-6ac3-434d-b659-de003d47c339",
"event": "deactivated",
"userId": "5ad50ead-6e6a-4d12-ab5b-e5db15835bb5"
},
{
"createdAt": "2026-05-14T00:04:59.388Z",
"id": 1484,
"workflowId": "PlZywwqL8MRNEAN6",
"versionId": "afb71f4d-6ac3-434d-b659-de003d47c339",
"event": "deactivated",
"userId": "5ad50ead-6e6a-4d12-ab5b-e5db15835bb5"
}
]
}
}