{ "updatedAt": "2026-05-14T00:03:13.116Z", "createdAt": "2026-05-12T17:56:05.279Z", "id": "El1BHJZ56JlzhrRZ", "name": "Voice Memo Capture (Audio URL + Local Whisper)", "description": null, "active": true, "isArchived": false, "nodes": [ { "parameters": { "httpMethod": "POST", "path": "voice-memo", "responseMode": "responseNode", "options": {} }, "type": "n8n-nodes-base.webhook", "typeVersion": 2.1, "position": [ -980, 0 ], "id": "9f1da0a8-32db-4e67-a6e4-18cf8b4d42ee", "name": "Webhook - Voice Memo", "webhookId": "06796590-13b3-4347-9582-1ac92719c95d" }, { "parameters": { "jsCode": "const body = $json.body ?? $json;\n\nconst audio_url = String(body.audio_url || body.url || '').trim();\nconst telegram_file_id = String(body.telegram_file_id || body.file_id || '').trim();\nconst discord_audio_url = String(body.discord_audio_url || '').trim();\nconst audio_base64 = String(body.audio_base64 || '').trim();\nconst audio_format = String(body.audio_format || body.format || 'ogg').trim();\nconst language = String(body.language || 'en').trim();\nconst title = String(body.title || 'Voice Memo').trim();\nconst tags = Array.isArray(body.tags) ? body.tags : String(body.tags || 'voice,memo').split(',').map(s => s.trim()).filter(Boolean);\nconst include_tts = body.include_tts === true || body.tts_readback === true;\nconst voice = String(body.voice || body.tts_voice || 'af_heart').trim();\nif (!audio_url && !telegram_file_id && !discord_audio_url && !audio_base64) {\n throw new Error('POST JSON must include audio_url, telegram_file_id, discord_audio_url, or audio_base64');\n}\nreturn [{ json: { audio_url, telegram_file_id, discord_audio_url, audio_base64, audio_format, language, title, tags, include_tts, voice } }];" }, "id": "vm-normalize-v2", "name": "Normalize Input", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ -680, 0 ] }, { "parameters": { "method": "POST", "url": "http://172.19.0.1:18813/process", "sendBody": true, "specifyBody": "json", "jsonBody": "={{ JSON.stringify({ audio_url: $json.audio_url, telegram_file_id: $json.telegram_file_id, discord_audio_url: $json.discord_audio_url, title: $json.title, tags: $json.tags, include_tts: $json.include_tts, voice: $json.voice }) }}", "options": { "timeout": 180000, "fullResponse": false } }, "id": "vm-process-v2", "name": "Process Voice Memo", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ -460, 0 ] }, { "parameters": { "jsCode": "const input = $('Normalize Input').first().json;\nconst proc = $input.first().json;\n\nfunction slugify(s) { return String(s || 'voice-memo').toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 80) || 'voice-memo'; }\nfunction yaml(s) { return String(s ?? '').split('\\n').join(' ').replaceAll('\"', '\\\\\"'); }\n\nconst date = new Date(proc.created_at || Date.now());\nconst ymd = date.toISOString().slice(0,10);\nconst notePath = `Voice Memos/${ymd}-${slugify(proc.title || input.title)}.md`;\n\nconst title = proc.title || input.title || 'Voice Memo';\nconst tags = proc.tags || input.tags || ['voice', 'memo'];\nconst tagLines = tags.map(t => ` - ${yaml(t)}`).join('\\n');\nconst sourceType = proc.source_type || input.source || 'unknown';\nconst sourceUrl = input.source_url || '';\n\nlet audioNote = '';\nif (proc.tts_audio_url) {\n audioNote = `\\n## Audio Summary\\n\\n> Listen to the AI-generated summary: ${proc.tts_audio_url}\\n`;\n}\n\nconst markdown = `---\\ntitle: \"${yaml(title)}\"\\nsource: \"${yaml(sourceUrl)}\"\\nsource_type: \"${sourceType}\"\\ncreated: \"${date.toISOString()}\"\\ntags:\\n${tagLines}\\n---\\n\\n# ${title}\\n\\n## Summary\\n\\n${(proc.summary || '').trim()}\\n${audioNote}\\n## Transcript\\n\\n${proc.transcript || 'No transcript available.'}\\n`;\n\nreturn [{ json: { ...input, notePath, markdown, title, tts_audio_url: proc.tts_audio_url || null } }];\n" }, "id": "vm-build-obsidian-v2", "name": "Build Obsidian Note", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ -240, 0 ] }, { "parameters": { "method": "PUT", "url": "={{'http://172.19.0.1:27123/vault/' + encodeURIComponent($json.notePath).replace(/%2F/g, '/')}}", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "Content-Type", "value": "text/markdown" } ] }, "sendBody": true, "contentType": "raw", "rawContentType": "text/markdown", "body": "={{$json.markdown}}", "options": { "timeout": 30000 }, "authentication": "genericCredentialType", "genericAuthType": "httpHeaderAuth" }, "id": "vm-write-obsidian-v2", "name": "Write Note to Obsidian", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 0, 0 ], "credentials": { "httpHeaderAuth": { "id": "465Swz2b71O2KRAK", "name": "Obsidian Local REST API" } } }, { "parameters": { "chatId": "8367012007", "text": "={{ \"Voice memo captured (\" + $json.source_type + \"): \" + $json.title + \"\\nObsidian: \" + $json.notePath + ($json.tts_audio_url ? \"\\nAudio summary: \" + $json.tts_audio_url : \"\") }}", "additionalFields": {} }, "type": "n8n-nodes-base.telegram", "typeVersion": 1.2, "position": [ 1160, -80 ], "id": "41bf5a55-2047-400a-87c7-44744a0f2a42", "name": "Send Telegram Notification", "credentials": { "telegramApi": { "id": "aox4dyIWVSRdcH5z", "name": "Telegram Bot (OpenClaw)" } } }, { "parameters": { "respondWith": "json", "responseBody": "={{ JSON.stringify({ ok: true, notePath: $json.notePath, title: $json.title, source_type: $json.source_type, tts_audio_url: $json.tts_audio_url || null }) }}" }, "id": "vm-respond-v2", "name": "Respond", "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.1, "position": [ 460, 0 ] } ], "connections": { "Webhook - Voice Memo": { "main": [ [ { "node": "Normalize Input", "type": "main", "index": 0 } ] ] }, "Normalize Input": { "main": [ [ { "node": "Process Voice Memo", "type": "main", "index": 0 } ] ] }, "Process Voice Memo": { "main": [ [ { "node": "Build Obsidian Note", "type": "main", "index": 0 } ] ] }, "Build Obsidian Note": { "main": [ [ { "node": "Write Note to Obsidian", "type": "main", "index": 0 } ] ] }, "Write Note to Obsidian": { "main": [ [ { "node": "Send Telegram Notification", "type": "main", "index": 0 } ] ] }, "Send Telegram Notification": { "main": [ [ { "node": "Respond", "type": "main", "index": 0 } ] ] } }, "settings": { "executionOrder": "v1", "timezone": "America/Los_Angeles", "saveDataErrorExecution": "all", "saveDataSuccessExecution": "none", "callerPolicy": "workflowsFromSameOwner", "availableInMCP": false }, "staticData": null, "meta": null, "pinData": null, "versionId": "4511e901-afab-493e-9b17-99a9d9865147", "activeVersionId": "4511e901-afab-493e-9b17-99a9d9865147", "versionCounter": 38, "triggerCount": 1, "shared": [ { "updatedAt": "2026-05-12T17:56:05.281Z", "createdAt": "2026-05-12T17:56:05.281Z", "role": "workflow:owner", "workflowId": "El1BHJZ56JlzhrRZ", "projectId": "WGdp8QunI1tHpjXa", "project": { "updatedAt": "2026-03-11T21:08:10.005Z", "createdAt": "2026-03-11T21:05:11.541Z", "id": "WGdp8QunI1tHpjXa", "name": "will will ", "type": "personal", "icon": null, "description": null, "creatorId": "5ad50ead-6e6a-4d12-ab5b-e5db15835bb5" } } ], "tags": [], "activeVersion": { "updatedAt": "2026-05-14T00:03:13.117Z", "createdAt": "2026-05-14T00:03:13.117Z", "versionId": "4511e901-afab-493e-9b17-99a9d9865147", "workflowId": "El1BHJZ56JlzhrRZ", "nodes": [ { "parameters": { "httpMethod": "POST", "path": "voice-memo", "responseMode": "responseNode", "options": {} }, "type": "n8n-nodes-base.webhook", "typeVersion": 2.1, "position": [ -980, 0 ], "id": "9f1da0a8-32db-4e67-a6e4-18cf8b4d42ee", "name": "Webhook - Voice Memo", "webhookId": "06796590-13b3-4347-9582-1ac92719c95d" }, { "parameters": { "jsCode": "const body = $json.body ?? $json;\n\nconst audio_url = String(body.audio_url || body.url || '').trim();\nconst telegram_file_id = String(body.telegram_file_id || body.file_id || '').trim();\nconst discord_audio_url = String(body.discord_audio_url || '').trim();\nconst audio_base64 = String(body.audio_base64 || '').trim();\nconst audio_format = String(body.audio_format || body.format || 'ogg').trim();\nconst language = String(body.language || 'en').trim();\nconst title = String(body.title || 'Voice Memo').trim();\nconst tags = Array.isArray(body.tags) ? body.tags : String(body.tags || 'voice,memo').split(',').map(s => s.trim()).filter(Boolean);\nconst include_tts = body.include_tts === true || body.tts_readback === true;\nconst voice = String(body.voice || body.tts_voice || 'af_heart').trim();\nif (!audio_url && !telegram_file_id && !discord_audio_url && !audio_base64) {\n throw new Error('POST JSON must include audio_url, telegram_file_id, discord_audio_url, or audio_base64');\n}\nreturn [{ json: { audio_url, telegram_file_id, discord_audio_url, audio_base64, audio_format, language, title, tags, include_tts, voice } }];" }, "id": "vm-normalize-v2", "name": "Normalize Input", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ -680, 0 ] }, { "parameters": { "method": "POST", "url": "http://172.19.0.1:18813/process", "sendBody": true, "specifyBody": "json", "jsonBody": "={{ JSON.stringify({ audio_url: $json.audio_url, telegram_file_id: $json.telegram_file_id, discord_audio_url: $json.discord_audio_url, title: $json.title, tags: $json.tags, include_tts: $json.include_tts, voice: $json.voice }) }}", "options": { "timeout": 180000, "fullResponse": false } }, "id": "vm-process-v2", "name": "Process Voice Memo", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ -460, 0 ] }, { "parameters": { "jsCode": "const input = $('Normalize Input').first().json;\nconst proc = $input.first().json;\n\nfunction slugify(s) { return String(s || 'voice-memo').toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 80) || 'voice-memo'; }\nfunction yaml(s) { return String(s ?? '').split('\\n').join(' ').replaceAll('\"', '\\\\\"'); }\n\nconst date = new Date(proc.created_at || Date.now());\nconst ymd = date.toISOString().slice(0,10);\nconst notePath = `Voice Memos/${ymd}-${slugify(proc.title || input.title)}.md`;\n\nconst title = proc.title || input.title || 'Voice Memo';\nconst tags = proc.tags || input.tags || ['voice', 'memo'];\nconst tagLines = tags.map(t => ` - ${yaml(t)}`).join('\\n');\nconst sourceType = proc.source_type || input.source || 'unknown';\nconst sourceUrl = input.source_url || '';\n\nlet audioNote = '';\nif (proc.tts_audio_url) {\n audioNote = `\\n## Audio Summary\\n\\n> Listen to the AI-generated summary: ${proc.tts_audio_url}\\n`;\n}\n\nconst markdown = `---\\ntitle: \"${yaml(title)}\"\\nsource: \"${yaml(sourceUrl)}\"\\nsource_type: \"${sourceType}\"\\ncreated: \"${date.toISOString()}\"\\ntags:\\n${tagLines}\\n---\\n\\n# ${title}\\n\\n## Summary\\n\\n${(proc.summary || '').trim()}\\n${audioNote}\\n## Transcript\\n\\n${proc.transcript || 'No transcript available.'}\\n`;\n\nreturn [{ json: { ...input, notePath, markdown, title, tts_audio_url: proc.tts_audio_url || null } }];\n" }, "id": "vm-build-obsidian-v2", "name": "Build Obsidian Note", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ -240, 0 ] }, { "parameters": { "method": "PUT", "url": "={{'http://172.19.0.1:27123/vault/' + encodeURIComponent($json.notePath).replace(/%2F/g, '/')}}", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "Content-Type", "value": "text/markdown" } ] }, "sendBody": true, "contentType": "raw", "rawContentType": "text/markdown", "body": "={{$json.markdown}}", "options": { "timeout": 30000 }, "authentication": "genericCredentialType", "genericAuthType": "httpHeaderAuth" }, "id": "vm-write-obsidian-v2", "name": "Write Note to Obsidian", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 0, 0 ], "credentials": { "httpHeaderAuth": { "id": "465Swz2b71O2KRAK", "name": "Obsidian Local REST API" } } }, { "parameters": { "chatId": "8367012007", "text": "={{ \"Voice memo captured (\" + $json.source_type + \"): \" + $json.title + \"\\nObsidian: \" + $json.notePath + ($json.tts_audio_url ? \"\\nAudio summary: \" + $json.tts_audio_url : \"\") }}", "additionalFields": {} }, "type": "n8n-nodes-base.telegram", "typeVersion": 1.2, "position": [ 1160, -80 ], "id": "41bf5a55-2047-400a-87c7-44744a0f2a42", "name": "Send Telegram Notification", "credentials": { "telegramApi": { "id": "aox4dyIWVSRdcH5z", "name": "Telegram Bot (OpenClaw)" } } }, { "parameters": { "respondWith": "json", "responseBody": "={{ JSON.stringify({ ok: true, notePath: $json.notePath, title: $json.title, source_type: $json.source_type, tts_audio_url: $json.tts_audio_url || null }) }}" }, "id": "vm-respond-v2", "name": "Respond", "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.1, "position": [ 460, 0 ] } ], "connections": { "Webhook - Voice Memo": { "main": [ [ { "node": "Normalize Input", "type": "main", "index": 0 } ] ] }, "Normalize Input": { "main": [ [ { "node": "Process Voice Memo", "type": "main", "index": 0 } ] ] }, "Process Voice Memo": { "main": [ [ { "node": "Build Obsidian Note", "type": "main", "index": 0 } ] ] }, "Build Obsidian Note": { "main": [ [ { "node": "Write Note to Obsidian", "type": "main", "index": 0 } ] ] }, "Write Note to Obsidian": { "main": [ [ { "node": "Send Telegram Notification", "type": "main", "index": 0 } ] ] }, "Send Telegram Notification": { "main": [ [ { "node": "Respond", "type": "main", "index": 0 } ] ] } }, "authors": "will will", "name": null, "description": null, "autosaved": false, "workflowPublishHistory": [ { "createdAt": "2026-05-14T00:03:13.146Z", "id": 1475, "workflowId": "El1BHJZ56JlzhrRZ", "versionId": "4511e901-afab-493e-9b17-99a9d9865147", "event": "activated", "userId": "5ad50ead-6e6a-4d12-ab5b-e5db15835bb5" }, { "createdAt": "2026-05-14T00:03:13.139Z", "id": 1474, "workflowId": "El1BHJZ56JlzhrRZ", "versionId": "4511e901-afab-493e-9b17-99a9d9865147", "event": "deactivated", "userId": "5ad50ead-6e6a-4d12-ab5b-e5db15835bb5" } ] } }