This workflow follows the Chainllm → Execute Workflow Trigger recipe pattern — see all workflows that pair these two integrations.
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 →
{
"updatedAt": "2025-12-24T09:35:09.881Z",
"createdAt": "2025-12-23T09:30:29.836Z",
"id": "DX0m48INGS7vEwbu",
"name": "Multi_Capture",
"description": null,
"active": false,
"isArchived": false,
"nodes": [
{
"parameters": {
"inputSource": "passthrough"
},
"type": "n8n-nodes-base.executeWorkflowTrigger",
"typeVersion": 1.1,
"position": [
-1600,
944
],
"id": "trigger-multi-extract",
"name": "ExecuteWorkflowTrigger"
},
{
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// Prepare for multi-capture\nconst ctx = $json.ctx;\n\nreturn {\n ctx: ctx,\n inference_start: Date.now()\n }"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-1376,
848
],
"id": "prepare-extraction",
"name": "PrepareCapture"
},
{
"parameters": {
"method": "DELETE",
"url": "=https://discord.com/api/v10/channels/{{ $json.ctx.event.channel_id }}/messages/{{ $json.ctx.event.message_id }}/reactions/\ud83d\udd35/@me",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "discordBotApi",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
-1376,
1040
],
"id": "remove-blue-reaction",
"name": "Remove\ud83d\udd35Reaction",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 1000,
"credentials": {
"discordBotApi": {
"name": "<your credential>"
}
},
"onError": "continueRegularOutput"
},
{
"parameters": {
"promptType": "define",
"text": "=You are an extraction agent for a life-tracking system. Analyze the message and extract all relevant items.\n\n## Message to Analyze\n\n\"{{ $json.ctx.event.clean_text }}\"\n\n## Extraction Types\n\n### Activity (what the user is doing NOW)\nExtract if the message describes a CURRENT or RECENT action by the user.\n- **Categories:** work, leisure, study, health, sleep, relationships, admin\n- **Indicators:** \"I am\", \"I'm\", \"-ing verbs\", \"just did\", present/recent past tense\n\n### Note (observation, insight, or fact worth remembering)\nExtract if the message contains knowledge, observations, or reflections.\n- **Categories:** reflection (about self), fact (about world/others)\n- **Indicators:** observations about things/people, realizations, ideas, decisions\n\n### Todo (actionable task to complete)\nExtract if the message contains a clear task to do later.\n- **Priority:** high, medium, low\n- **Indicators:** \"need to\", \"should\", \"have to\", \"TODO\", future tasks\n\n## Key Rules\n\n1. A message can have 0, 1, 2, or 3 extractions\n2. Set confidence 0.0-1.0 based on how clearly the message indicates each type\n3. Only include extractions with confidence >= 0.5\n4. Prefer fewer high-confidence extractions over many low-confidence ones\n5. Activity describes what I'M doing; Note describes observations about anything else\n\n## Output Format\n\nOutput ONLY valid JSON, no explanation:\n\n{\"activity\": {\"category\": \"work\", \"description\": \"debugging auth\", \"confidence\": 0.92}, \"note\": {\"category\": \"reflection\", \"text\": \"noticed pattern in logs\", \"confidence\": 0.78}, \"todo\": null}",
"needsFallback": true,
"batching": {}
},
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"typeVersion": 1.7,
"position": [
-1152,
848
],
"id": "multi-extractor",
"name": "MultiCapturer"
},
{
"parameters": {
"model": "xiaomi/mimo-v2-flash:free",
"options": {
"timeout": 15000
}
},
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"typeVersion": 1,
"position": [
-1152,
1072
],
"id": "mimo-v2-flash",
"name": "MimoV2Flash",
"credentials": {
"openRouterApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"model": "nvidia/nemotron-nano-9b-v2:free",
"options": {
"timeout": 15000
}
},
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"typeVersion": 1,
"position": [
-1024,
1072
],
"id": "nemotron-nano-9b",
"name": "NemotronNano9b",
"credentials": {
"openRouterApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// Parse LLM response, filter by confidence, build trace query\nconst EMOJI = { activity: '\ud83d\udd18', note: '\ud83d\udcdd', todo: '\u2705' };\nconst CONFIDENCE_THRESHOLD = 0.5;\n\nconst llmText = $json.text?.trim() || '';\nconst prepareItem = $('PrepareCapture').first().json;\nconst ctx = prepareItem.ctx;\nconst durationMs = Date.now() - prepareItem.inference_start;\n\n// Full rendered prompt (template + input)\nconst fullPrompt = `You are an extraction agent for a life-tracking system. Analyze the message and extract all relevant items.\n\n## Message to Analyze\n\n\"${ctx.event.clean_text}\"\n\n## Extraction Types\n\n### Activity (what the user is doing NOW)\nExtract if the message describes a CURRENT or RECENT action by the user.\n- **Categories:** work, leisure, study, health, sleep, relationships, admin\n- **Indicators:** \"I am\", \"I'm\", \"-ing verbs\", \"just did\", present/recent past tense\n\n### Note (observation, insight, or fact worth remembering)\nExtract if the message contains knowledge, observations, or reflections.\n- **Categories:** reflection (about self), fact (about world/others)\n- **Indicators:** observations about things/people, realizations, ideas, decisions\n\n### Todo (actionable task to complete)\nExtract if the message contains a clear task to do later.\n- **Priority:** high, medium, low\n- **Indicators:** \"need to\", \"should\", \"have to\", \"TODO\", future tasks\n\n## Key Rules\n\n1. A message can have 0, 1, 2, or 3 extractions\n2. Set confidence 0.0-1.0 based on how clearly the message indicates each type\n3. Only include extractions with confidence >= 0.5\n4. Prefer fewer high-confidence extractions over many low-confidence ones\n5. Activity describes what I'M doing; Note describes observations about anything else\n\n## Output Format\n\nOutput ONLY valid JSON, no explanation:\n\n{\"activity\": {\"category\": \"work\", \"description\": \"debugging auth\", \"confidence\": 0.92}, \"note\": {\"category\": \"reflection\", \"text\": \"noticed pattern in logs\", \"confidence\": 0.78}, \"todo\": null}`;\n\n// Format trace_chain for PostgreSQL\nconst traceChain = ctx.event.trace_chain || [];\nconst traceChainPg = '{' + traceChain.join(',') + '}';\n\n// Parse JSON from LLM output\nlet parsed = { activity: null, note: null, todo: null };\nlet parseError = null;\n\ntry {\n let jsonStr = llmText;\n const codeBlock = llmText.match(/```(?:json)?\\s*([\\s\\S]*?)```/);\n if (codeBlock) jsonStr = codeBlock[1].trim();\n const objMatch = jsonStr.match(/\\{[\\s\\S]*\\}/);\n if (objMatch) jsonStr = objMatch[0];\n parsed = JSON.parse(jsonStr);\n} catch (e) {\n parseError = e.message;\n}\n\n// Build captures array\nconst captures = [];\nconst emojis = [];\n\nif (parsed.activity?.confidence >= CONFIDENCE_THRESHOLD) {\n captures.push({\n type: 'activity',\n emoji: EMOJI.activity,\n data: {\n timestamp: new Date().toISOString(),\n category: parsed.activity.category || 'work',\n description: parsed.activity.description || ctx.event.clean_text,\n message_url: ctx.event.message_url,\n confidence: parsed.activity.confidence\n }\n });\n emojis.push(EMOJI.activity);\n}\n\nif (parsed.note?.confidence >= CONFIDENCE_THRESHOLD) {\n captures.push({\n type: 'note',\n emoji: EMOJI.note,\n data: {\n timestamp: new Date().toISOString(),\n category: parsed.note.category || 'reflection',\n text: parsed.note.text || ctx.event.clean_text,\n message_url: ctx.event.message_url,\n confidence: parsed.note.confidence\n }\n });\n emojis.push(EMOJI.note);\n}\n\nif (parsed.todo?.confidence >= CONFIDENCE_THRESHOLD) {\n captures.push({\n type: 'todo',\n emoji: EMOJI.todo,\n data: {\n timestamp: new Date().toISOString(),\n priority: parsed.todo.priority || 'medium',\n text: parsed.todo.text || ctx.event.clean_text,\n message_url: ctx.event.message_url,\n confidence: parsed.todo.confidence\n }\n });\n emojis.push(EMOJI.todo);\n}\n\n// Fallback: if nothing captured, create low-confidence note\nif (captures.length === 0) {\n captures.push({\n type: 'note',\n emoji: EMOJI.note,\n data: {\n timestamp: new Date().toISOString(),\n category: 'reflection',\n text: ctx.event.clean_text,\n message_url: ctx.event.message_url,\n confidence: 0.3\n }\n });\n emojis.push(EMOJI.note);\n}\n\n// Pre-stringify the result for postgres jsonb\nconst resultJson = JSON.stringify(captures.map(c => ({ type: c.type, confidence: c.data.confidence })));\n\n// Return with ctx.db_queries for Execute_Queries\nreturn [{\n json: {\n ctx: {\n ...ctx,\n db_queries: [{\n key: 'trace',\n sql: `INSERT INTO traces (event_id, step_name, data, trace_chain)\nVALUES (\n $1::uuid,\n 'multi_capture',\n jsonb_build_object(\n 'prompt', $2,\n 'input', jsonb_build_object('text', $3),\n 'completion', $4,\n 'result', $5::jsonb,\n 'model', 'xiaomi/mimo-v2-flash:free',\n 'duration_ms', $6::integer,\n 'capture_count', $7::integer\n ),\n $8::uuid[]\n)\nRETURNING id, trace_chain || id AS updated_trace_chain;`,\n params: [\n ctx.event.event_id,\n fullPrompt,\n ctx.event.clean_text,\n llmText,\n resultJson,\n durationMs,\n captures.length,\n traceChainPg\n ]\n }]\n },\n captures,\n emojis,\n total_captures: captures.length,\n raw_response: llmText,\n parse_error: parseError,\n duration_ms: durationMs\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-800,
848
],
"id": "parse-and-split",
"name": "ParseResponse"
},
{
"parameters": {
"workflowId": {
"__rl": true,
"value": "CgUAxK0i4YhrZ2Wp",
"mode": "list",
"cachedResultName": "Execute_Queries",
"cachedResultUrl": "/workflow/CgUAxK0i4YhrZ2Wp"
},
"workflowInputs": {
"mappingMode": "defineBelow",
"value": {
"ctx": "={{ $json.ctx }}"
}
},
"options": {
"waitForSubWorkflow": true
}
},
"type": "n8n-nodes-base.executeWorkflow",
"typeVersion": 1.3,
"position": [
-576,
848
],
"id": "store-llm-trace",
"name": "StoreLlmTrace"
},
{
"parameters": {
"jsCode": "// Split captures into individual items for projection storage\n// Input: Store LLM Trace result (ctx with db.trace)\n// Output: One item per capture, each with trace_id attached\n\nconst ctx = $json.ctx;\nconst parseResult = $('ParseResponse').first().json;\n\nconst llmTraceId = ctx.db?.trace?.row?.id;\nconst updatedTraceChain = ctx.db?.trace?.row?.updated_trace_chain || [];\nconst updatedTraceChainPg = '{' + updatedTraceChain.join(',') + '}';\n\n// Split captures array into individual items, each with its own db_queries\nreturn parseResult.captures.map(capture => ({\n json: {\n ctx: {\n ...ctx,\n db_queries: [{\n key: 'projection',\n sql: `INSERT INTO projections (trace_id, event_id, trace_chain, projection_type, data, status, timezone)\nVALUES (\n $1::uuid,\n $2::uuid,\n $3::uuid[],\n $4,\n $5::jsonb,\n 'auto_confirmed',\n $6\n)\nRETURNING *;`,\n params: [\n llmTraceId,\n ctx.event.event_id,\n updatedTraceChainPg,\n capture.type,\n JSON.stringify(capture.data),\n ctx.event.timezone\n ]\n }]\n },\n capture\n }\n}));"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-352,
848
],
"id": "prepare-projections",
"name": "SplitCaptures"
},
{
"parameters": {
"workflowId": {
"__rl": true,
"value": "CgUAxK0i4YhrZ2Wp",
"mode": "list",
"cachedResultName": "Execute_Queries",
"cachedResultUrl": "/workflow/CgUAxK0i4YhrZ2Wp"
},
"workflowInputs": {
"mappingMode": "defineBelow",
"value": {
"ctx": "={{ $json.ctx }}"
}
},
"options": {
"waitForSubWorkflow": true
}
},
"type": "n8n-nodes-base.executeWorkflow",
"typeVersion": 1.3,
"position": [
128,
848
],
"id": "store-projection",
"name": "StoreProjection"
},
{
"parameters": {
"jsCode": "// Collect results for logging with standard emojis\nconst parseResult = $('ParseResponse').first().json;\n\n// Standard emoji mapping\nconst typeEmojis = {\n 'activity': '\ud83d\udd18',\n 'note': '\ud83d\udcdd',\n 'todo': '\ud83d\udd32'\n};\n\n// Map capture types to standard emojis\nconst emojis = parseResult.captures.map(c => typeEmojis[c.type] || '\ud83d\udce6');\n\n// Build verbose config query\nreturn [{\n json: {\n ctx: {\n ...parseResult.ctx,\n db_queries: [{\n key: 'verbose_config',\n sql: `SELECT value FROM config WHERE key = 'verbose'`,\n params: []\n }]\n },\n emojis: emojis,\n duration_ms: parseResult.duration_ms,\n projection_count: parseResult.total_captures\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-576,
1040
],
"id": "collect-results",
"name": "CollectResults"
},
{
"parameters": {
"method": "PUT",
"url": "=https://discord.com/api/v10/channels/{{ $json.ctx.event.channel_id }}/messages/{{ $json.ctx.event.message_id }}/reactions/{{ $json.emoji }}/@me",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "discordBotApi",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
-128,
528
],
"id": "add-emoji-reactions",
"name": "AddEmojiReactions",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 1000,
"credentials": {
"discordBotApi": {
"name": "<your credential>"
}
},
"onError": "continueRegularOutput"
},
{
"parameters": {
"resource": "message",
"guildId": {
"__rl": true,
"value": "={{ $json.ctx.event.guild_id }}",
"mode": "id"
},
"channelId": {
"__rl": true,
"value": "={{ $env.DISCORD_CHANNEL_KAIRON_LOGS }}",
"mode": "id"
},
"content": "={{ $json.ctx.event.clean_text }} {{ $json.duration_ms }}ms \u27a1\ufe0f {{ $json.emojis.join(' ') }}",
"options": {}
},
"type": "n8n-nodes-base.discord",
"typeVersion": 2,
"position": [
-352,
1232
],
"id": "log-to-kairon-logs",
"name": "LogToKaironLogs",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 1000,
"credentials": {
"discordBotApi": {
"name": "<your credential>"
}
},
"onError": "continueRegularOutput"
},
{
"parameters": {
"amount": 1
},
"type": "n8n-nodes-base.wait",
"typeVersion": 1.1,
"position": [
96,
560
],
"id": "wait-rate-limit",
"name": "Wait1s"
},
{
"parameters": {
"options": {}
},
"type": "n8n-nodes-base.splitInBatches",
"typeVersion": 3,
"position": [
-352,
560
],
"id": "2741faa1-e8ab-4588-b3b5-bc67839680a3",
"name": "LoopOverItems"
},
{
"parameters": {
"jsCode": "// Convert emojis array to individual items for batch processing\nconst parseResult = $('ParseResponse').first().json;\n\n// Standard emoji mapping\nconst typeEmojis = {\n 'activity': '\ud83d\udd18',\n 'note': '\ud83d\udcdd',\n 'todo': '\ud83d\udd32'\n};\n\n// Map capture types to standard emojis\nconst emojis = parseResult.captures.map(c => typeEmojis[c.type] || '\ud83d\udce6');\n\nreturn emojis.map(emoji => ({\n json: {\n ctx: parseResult.ctx,\n emoji: emoji\n }\n}));"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-576,
560
],
"id": "prepare-emoji-items",
"name": "PrepareEmojiItems"
},
{
"parameters": {
"workflowId": {
"__rl": true,
"value": "CgUAxK0i4YhrZ2Wp",
"mode": "list",
"cachedResultName": "Execute_Queries",
"cachedResultUrl": "/workflow/CgUAxK0i4YhrZ2Wp"
},
"workflowInputs": {
"mappingMode": "defineBelow",
"value": {
"ctx": "={{ $json.ctx }}"
}
},
"options": {
"waitForSubWorkflow": true
}
},
"type": "n8n-nodes-base.executeWorkflow",
"typeVersion": 1.3,
"position": [
-352,
1040
],
"id": "query-verbose-setting",
"name": "QueryVerboseSetting"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "f55070f3-80b6-4076-a05d-6799052b6555",
"leftValue": "={{ $json.ctx.verbose }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
96,
1040
],
"id": "if-verbose-true",
"name": "IfVerboseTrue"
},
{
"parameters": {
"workflowId": {
"__rl": true,
"value": "wVpslhMBnrsgDaOR",
"mode": "list",
"cachedResultName": "Show_Projection_Details",
"cachedResultUrl": "/workflow/wVpslhMBnrsgDaOR"
},
"workflowInputs": {
"mappingMode": "defineBelow",
"value": {
"ctx": "={{ $json.ctx }}"
}
},
"options": {
"waitForSubWorkflow": false
}
},
"type": "n8n-nodes-base.executeWorkflow",
"typeVersion": 1.3,
"position": [
320,
1040
],
"id": "trigger-show-details",
"name": "TriggerShowDetails"
},
{
"parameters": {
"jsCode": "// Merge verbose config result into ctx\nconst collectResults = $('CollectResults').first().json;\nconst ctx = $json.ctx;\nconst verboseValue = ctx.db?.verbose_config?.row?.value;\n\nreturn [{\n json: {\n ctx: {\n ...ctx,\n verbose: verboseValue === 'true' || verboseValue === true\n },\n emojis: collectResults.emojis,\n duration_ms: collectResults.duration_ms,\n projection_count: collectResults.projection_count\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-128,
1040
],
"id": "merge-ctx-verbose",
"name": "MergeCtxForVerbose"
},
{
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// Extract text for embedding from projection data\nconst ctx = $json.ctx;\nconst projection = ctx.db?.projection?.row || {};\nconst data = projection.data || {};\nconst embeddingText = data.description || data.text || '';\n\nreturn {\n projection_id: projection.id,\n embedding_text: embeddingText\n }"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
352,
848
],
"id": "prepare-embedding-text",
"name": "PrepareEmbeddingText"
},
{
"parameters": {
"method": "POST",
"url": "={{ $env.EMBEDDING_SERVICE_URL }}/embed",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"texts\": [{{ JSON.stringify($json.embedding_text || '') }}]\n}",
"options": {
"timeout": 10000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
576,
848
],
"id": "embed-projection-text",
"name": "EmbedProjectionText",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "// Build embedding insert query for Execute_Queries\nconst prepareData = $(\"PrepareEmbeddingText\").first().json;\nconst embeddings = $json.embeddings;\n\n// Check if we have a valid embedding\nif (!embeddings || !embeddings[0]) {\n // Return a pass-through item to keep the loop going\n return [{\n json: {\n ctx: {\n ...($json.ctx || {}),\n db_queries: [] // Empty queries = no-op in Execute_Queries\n }\n }\n }];\n}\n\nconst embeddingVector = \"[\" + embeddings[0].join(\",\") + \"]\";\n\nreturn [{\n json: {\n ctx: {\n ...($json.ctx || {}),\n db_queries: [{\n key: \"embedding\",\n sql: `-- Insert embedding for the projection (fire-and-forget)\nINSERT INTO embeddings (projection_id, model, embedding_data, embedded_text, embedding)\nSELECT \n $1::uuid,\n \"all-MiniLM-L6-v2\",\n \"{}\",\n $2,\n $3::vector\nWHERE $3 IS NOT NULL\nON CONFLICT DO NOTHING;`,\n params: [\n prepareData.projection_id,\n prepareData.embedding_text,\n embeddingVector\n ]\n }]\n }\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
800,
848
],
"id": "build-embedding-query",
"name": "BuildEmbeddingQuery"
},
{
"parameters": {
"workflowId": {
"__rl": true,
"value": "CgUAxK0i4YhrZ2Wp",
"mode": "list",
"cachedResultName": "Execute_Queries",
"cachedResultUrl": "/workflow/CgUAxK0i4YhrZ2Wp"
},
"workflowInputs": {
"mappingMode": "defineBelow",
"value": {
"ctx": "={{ $json.ctx }}"
}
},
"options": {
"waitForSubWorkflow": true
}
},
"type": "n8n-nodes-base.executeWorkflow",
"typeVersion": 1.3,
"position": [
1024,
848
],
"id": "insert-embedding",
"name": "InsertEmbedding",
"continueOnFail": true
},
{
"parameters": {
"options": {}
},
"type": "n8n-nodes-base.splitInBatches",
"typeVersion": 3,
"position": [
-128,
848
],
"id": "projection-loop",
"name": "ProjectionLoop"
}
],
"connections": {
"ExecuteWorkflowTrigger": {
"main": [
[
{
"node": "PrepareCapture",
"type": "main",
"index": 0
},
{
"node": "Remove\ud83d\udd35Reaction",
"type": "main",
"index": 0
}
]
]
},
"PrepareCapture": {
"main": [
[
{
"node": "MultiCapturer",
"type": "main",
"index": 0
}
]
]
},
"MultiCapturer": {
"main": [
[
{
"node": "ParseResponse",
"type": "main",
"index": 0
}
]
]
},
"StoreLlmTrace": {
"main": [
[
{
"node": "SplitCaptures",
"type": "main",
"index": 0
}
]
]
},
"StoreProjection": {
"main": [
[
{
"node": "PrepareEmbeddingText",
"type": "main",
"index": 0
}
]
]
},
"PrepareEmbeddingText": {
"main": [
[
{
"node": "EmbedProjectionText",
"type": "main",
"index": 0
}
]
]
},
"EmbedProjectionText": {
"main": [
[
{
"node": "BuildEmbeddingQuery",
"type": "main",
"index": 0
}
]
]
},
"BuildEmbeddingQuery": {
"main": [
[
{
"node": "InsertEmbedding",
"type": "main",
"index": 0
}
]
]
},
"CollectResults": {
"main": [
[
{
"node": "LogToKaironLogs",
"type": "main",
"index": 0
},
{
"node": "QueryVerboseSetting",
"type": "main",
"index": 0
}
]
]
},
"AddEmojiReactions": {
"main": [
[
{
"node": "Wait1s",
"type": "main",
"index": 0
}
]
]
},
"MimoV2Flash": {
"ai_languageModel": [
[
{
"node": "MultiCapturer",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"NemotronNano9b": {
"ai_languageModel": [
[
{
"node": "MultiCapturer",
"type": "ai_languageModel",
"index": 1
}
]
]
},
"Wait1s": {
"main": [
[
{
"node": "LoopOverItems",
"type": "main",
"index": 0
}
]
]
},
"LoopOverItems": {
"main": [
[],
[
{
"node": "AddEmojiReactions",
"type": "main",
"index": 0
}
]
]
},
"ParseResponse": {
"main": [
[
{
"node": "StoreLlmTrace",
"type": "main",
"index": 0
},
{
"node": "CollectResults",
"type": "main",
"index": 0
},
{
"node": "PrepareEmojiItems",
"type": "main",
"index": 0
}
]
]
},
"SplitCaptures": {
"main": [
[
{
"node": "ProjectionLoop",
"type": "main",
"index": 0
}
]
]
},
"PrepareEmojiItems": {
"main": [
[
{
"node": "LoopOverItems",
"type": "main",
"index": 0
}
]
]
},
"LogToKaironLogs": {
"main": [
[]
]
},
"QueryVerboseSetting": {
"main": [
[
{
"node": "MergeCtxForVerbose",
"index": 0,
"type": "main"
}
]
]
},
"IfVerboseTrue": {
"main": [
[
{
"node": "TriggerShowDetails",
"index": 0,
"type": "main"
}
]
]
},
"MergeCtxForVerbose": {
"main": [
[
{
"node": "IfVerboseTrue",
"index": 0,
"type": "main"
}
]
]
},
"ProjectionLoop": {
"main": [
[],
[
{
"node": "StoreProjection",
"type": "main",
"index": 0
}
]
]
},
"InsertEmbedding": {
"main": [
[
{
"node": "ProjectionLoop",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"callerPolicy": "workflowsFromSameOwner",
"errorWorkflow": "NOJ7FqVhVLqw0n8D",
"availableInMCP": false,
"executionOrder": "v1"
},
"staticData": null,
"meta": null,
"versionId": "5edea6c3-4c7e-46ee-90c3-ba9dd4b97587",
"activeVersionId": null,
"versionCounter": 231,
"triggerCount": 0,
"shared": [
{
"updatedAt": "2025-12-23T09:30:29.836Z",
"createdAt": "2025-12-23T09:30:29.836Z",
"role": "workflow:owner",
"workflowId": "DX0m48INGS7vEwbu",
"projectId": "erM3nntdLL53noWi",
"project": {
"updatedAt": "2025-12-23T09:23:39.658Z",
"createdAt": "2025-12-23T09:16:56.460Z",
"id": "erM3nntdLL53noWi",
"name": "Chris Irineo <chriskevini@gmail.com>",
"type": "personal",
"icon": null,
"description": null,
"projectRelations": [
{
"updatedAt": "2025-12-23T09:16:56.460Z",
"createdAt": "2025-12-23T09:16:56.460Z",
"userId": "2a851a2d-b7e5-4b3c-aefb-6eaaa79e0659",
"projectId": "erM3nntdLL53noWi",
"user": {
"updatedAt": "2025-12-24T08:40:46.063Z",
"createdAt": "2025-12-23T09:16:54.881Z",
"id": "2a851a2d-b7e5-4b3c-aefb-6eaaa79e0659",
"email": "chriskevini@gmail.com",
"firstName": "Chris",
"lastName": "Irineo",
"personalizationAnswers": {
"version": "v4",
"personalization_survey_submitted_at": "2025-12-23T09:23:43.723Z",
"personalization_survey_n8n_version": "1.123.5"
},
"settings": {
"userActivated": true,
"firstSuccessfulWorkflowId": "CgUAxK0i4YhrZ2Wp",
"userActivatedAt": 1766487000077,
"easyAIWorkflowOnboarded": true
},
"disabled": false,
"mfaEnabled": false,
"lastActiveAt": "2025-12-24",
"isPending": false
}
}
]
}
}
],
"tags": [],
"activeVersion": null
}
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.
discordBotApiopenRouterApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Multi_Capture. Uses executeWorkflowTrigger, httpRequest, chainLlm, lmChatOpenRouter. Event-driven trigger; 25 nodes.
Source: https://github.com/chriskevini/kairon/blob/ab924f228ceb22522b9a4dfa1ab4589eb86273ad/n8n-workflows/Multi_Capture.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.
Capture_Thread. Uses executeWorkflowTrigger, chainLlm, httpRequest, discord. Event-driven trigger; 26 nodes.
Capture_Projection. Uses executeWorkflowTrigger, httpRequest, chainLlm, lmChatOpenRouter. Event-driven trigger; 18 nodes.
Continue_Thread. Uses executeWorkflowTrigger, chainLlm, lmChatOpenRouter, discord. Event-driven trigger; 14 nodes.
Start_Thread. Uses executeWorkflowTrigger, httpRequest, chainLlm, lmChatOpenRouter. Event-driven trigger; 14 nodes.
This workflow is designed for n8n users who manage multiple production workflows and want to: Receive intelligent, actionable error alerts instead of raw stack traces Understand root causes without ma