{"meta":{"instanceId":"workflow-787fbfca","versionId":"1.0.0","createdAt":"2025-09-29T07:07:59.020097","updatedAt":"2025-09-29T07:07:59.020120","owner":"n8n-user","license":"MIT","category":"automation","status":"active","priority":"high","environment":"production"},"nodes":[{"id":"be902a85-fc31-442c-b308-a2350ec5aabb","name":"When clicking ‘Test workflow’","type":"n8n-nodes-base.manualTrigger","position":[-760,440],"parameters":{},"typeVersion":1,"notes":"This manualTrigger node performs automated tasks as part of the workflow."},{"id":"d229b686-9de4-4633-9dba-3e1fe71eedf1","name":"No Operation, do nothing1","type":"n8n-nodes-base.noOp","position":[1820,800],"parameters":{},"typeVersion":1,"notes":"This noOp node performs automated tasks as part of the workflow."},{"id":"f583bc97-8da8-488e-ab04-5167dc7a7701","name":"Information Extractor","type":"n8n-nodes-base.noOp","position":[2420,540],"parameters":{"text":"={{ $json.buffer.reverse().toJsonString() }}","options":{"systemPromptTemplate":"Eres un experto extrayendo información, tu objetivo es recolectar todos los mensajes. Procura no dejar duplicados. como resultado debes retornar un solo párrafo con todo los mensajes."},"schemaType":"fromJson","jsonSchemaExample":"{\n\t\"message\": \"all consolidated messages\"\n}"},"typeVersion":1,"notes":"This informationExtractor node performs automated tasks as part of the workflow."},{"id":"5b719416-4886-4d38-9d00-30b6237db168","name":"OpenAI Chat Model","type":"n8n-nodes-base.noOp","position":[2440,760],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4.1-nano","cachedResultName":"gpt-4.1-nano"},"options":{}},"credentials":{"openAiApi":{"id":"IogsrRzOBSmZJS5C","name":"OpenAi account"}},"typeVersion":1,"notes":"This lmChatOpenAi node performs automated tasks as part of the workflow."},{"id":"3d149fc0-caa7-4361-9bf9-33b6252b39eb","name":"get wait seconds","type":"n8n-nodes-base.code","position":[-260,500],"parameters":{"jsCode":"// Function: Compute waitSeconds\nconst wordCount = $json.message.split(' ').filter(w=>w).length;\nreturn [{ json: { \n  context_id: $json.context_id,\n  message: $json.message,\n  waitSeconds: wordCount < 5 ? 45 : 30 \n}}];\n"},"typeVersion":2,"notes":"This code node performs automated tasks as part of the workflow."},{"id":"cc670735-d126-465f-b0a3-3a4c5e390fd7","name":"Set last_seen","type":"n8n-nodes-base.redis","position":[280,380],"parameters":{"key":"YOUR_CREDENTIAL_HERE","ttl":"={{ $json.waitSeconds + 60 }}","value":"={{$now.toMillis()}}","expire":true,"keyType":"YOUR_CREDENTIAL_HERE","operation":"set"},"credentials":{"redis":{"id":"zJtRI38KhsyVjUvP","name":"Redis account"}},"typeVersion":1,"alwaysOutputData":true,"notes":"This redis node performs automated tasks as part of the workflow."},{"id":"20d97d1d-70d4-4c3c-aa12-b1aa31795240","name":"Get waiting_reply","type":"n8n-nodes-base.redis","position":[180,780],"parameters":{"key":"YOUR_CREDENTIAL_HERE","options":{},"operation":"get","propertyName":"waiting_reply"},"credentials":{"redis":{"id":"zJtRI38KhsyVjUvP","name":"Redis account"}},"typeVersion":1,"notes":"This redis node performs automated tasks as part of the workflow."},{"id":"7a2fc681-692f-4f72-9fab-f3ada4bda54b","name":"Mod input","type":"n8n-nodes-base.set","position":[340,800],"parameters":{"options":{},"assignments":{"assignments":[{"id":"7ff99444-753d-4ef7-865c-7115761526b8","name":"waiting_reply","type":"string","value":"={{ $json.waiting_reply }}"},{"id":"58ad6981-c35a-4dd6-b1cd-7c446b85e738","name":"context_id","type":"string","value":"={{$('When Executed by Another Workflow').item.json.context_id  }}"},{"id":"bd0535a2-be03-436b-8a2e-222c3e26fd04","name":"message","type":"string","value":"={{$('When Executed by Another Workflow').item.json.message }}"},{"id":"2f583f32-f231-4407-b773-c08b38d464f0","name":"waitSeconds","type":"number","value":"={{ $('get wait seconds').item.json.waitSeconds }}"}]},"includeOtherFields":true},"typeVersion":3.4,"notes":"This set node performs automated tasks as part of the workflow."},{"id":"84213bef-32be-4cd9-8387-cd76aff5cb38","name":"waiting_reply?","type":"n8n-nodes-base.if","position":[540,800],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"8136ea21-d798-41fd-81ed-5c0e7fda73c5","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ $json.waiting_reply != null}}","rightValue":""}]}},"typeVersion":2.2,"notes":"This if node performs automated tasks as part of the workflow."},{"id":"a8472217-aa83-4247-9d7d-3a471e24478a","name":"When chat message received","type":"n8n-nodes-base.noOp","position":[-740,640],"webhookId":"85115343-bb86-4bb8-b7a8-c4efded80b3f","parameters":{"options":{}},"typeVersion":1,"notes":"This chatTrigger node performs automated tasks as part of the workflow."},{"id":"ba4c81ba-92e2-4bef-a9e2-6f8d4c0aa722","name":"Set waiting_reply","type":"n8n-nodes-base.redis","position":[840,720],"parameters":{"key":"YOUR_CREDENTIAL_HERE","ttl":"={{ $json.waitSeconds }}","value":"true","expire":true,"operation":"set"},"credentials":{"redis":{"id":"zJtRI38KhsyVjUvP","name":"Redis account"}},"typeVersion":1,"notes":"This redis node performs automated tasks as part of the workflow."},{"id":"0ce783b6-b76b-4a5d-96ae-11708b7532ba","name":"Get buffer","type":"n8n-nodes-base.redis","position":[1820,600],"parameters":{"key":"YOUR_CREDENTIAL_HERE","options":{},"operation":"get","propertyName":"buffer"},"credentials":{"redis":{"id":"zJtRI38KhsyVjUvP","name":"Redis account"}},"typeVersion":1,"notes":"This redis node performs automated tasks as part of the workflow."},{"id":"21864061-1d1f-4528-a03f-1237e9c69a31","name":"Delete buffer_in","type":"n8n-nodes-base.redis","position":[2940,680],"parameters":{"key":"YOUR_CREDENTIAL_HERE","operation":"delete"},"credentials":{"redis":{"id":"zJtRI38KhsyVjUvP","name":"Redis account"}},"typeVersion":1,"notes":"This redis node performs automated tasks as part of the workflow."},{"id":"8828aa7b-6153-4677-84a8-3ef2f884792c","name":"Delete waiting_reply","type":"n8n-nodes-base.redis","position":[2940,840],"parameters":{"key":"YOUR_CREDENTIAL_HERE","operation":"delete"},"credentials":{"redis":{"id":"zJtRI38KhsyVjUvP","name":"Redis account"}},"typeVersion":1,"notes":"This redis node performs automated tasks as part of the workflow."},{"id":"fc369067-7213-4d8c-b515-c34c4db997e4","name":"WaitSeconds","type":"n8n-nodes-base.wait","position":[1020,720],"webhookId":"c218d471-2f0f-4bd7-87d1-5431ac602211","parameters":{"amount":"={{ $json.waitSeconds }} "},"typeVersion":1.1,"notes":"This wait node performs automated tasks as part of the workflow."},{"id":"2daa2ab9-756a-4fdb-8573-b4570c58d6e5","name":"Buffer messages","type":"n8n-nodes-base.redis","position":[-40,440],"parameters":{"list":"=buffer_in:{{$json.context_id}}","operation":"push","messageData":"={\"text\": \"{{ $json.message }}\", \"timestamp\": \"{{$now}}\"}"},"credentials":{"redis":{"id":"zJtRI38KhsyVjUvP","name":"Redis account"}},"typeVersion":1,"notes":"This redis node performs automated tasks as part of the workflow."},{"id":"4d5bc5f0-11ce-4f7f-b44b-0514a5ab5671","name":"Set buffer_count increment","type":"n8n-nodes-base.redis","position":[280,560],"parameters":{"key":"YOUR_CREDENTIAL_HERE","expire":"={{$json.waitSeconds + 60}}","operation":"incr"},"credentials":{"redis":{"id":"zJtRI38KhsyVjUvP","name":"Redis account"}},"typeVersion":1,"alwaysOutputData":true,"notes":"This redis node performs automated tasks as part of the workflow."},{"id":"dcaee1a8-ea32-4a9d-b32f-f0418644027c","name":"Get last_seen","type":"n8n-nodes-base.redis","position":[1220,720],"parameters":{"key":"YOUR_CREDENTIAL_HERE","options":{},"operation":"get","propertyName":"last_seen"},"credentials":{"redis":{"id":"zJtRI38KhsyVjUvP","name":"Redis account"}},"typeVersion":1,"notes":"This redis node performs automated tasks as part of the workflow."},{"id":"908c4a4c-1c60-4e90-827a-064a0b4d6bfd","name":"Get buffer_count","type":"n8n-nodes-base.redis","position":[1400,720],"parameters":{"key":"YOUR_CREDENTIAL_HERE","options":{},"operation":"get","propertyName":"count"},"credentials":{"redis":{"id":"zJtRI38KhsyVjUvP","name":"Redis account"}},"typeVersion":1,"notes":"This redis node performs automated tasks as part of the workflow."},{"id":"1ceb472b-3944-4d74-994b-867ade006e4e","name":"Map ouput","type":"n8n-nodes-base.set","position":[3140,380],"parameters":{"options":{},"assignments":{"assignments":[{"id":"e8d80ab4-74a2-4c30-8500-8dddc5802eec","name":"message","type":"string","value":"={{ $json.output.message }}"},{"id":"7e7fcee4-14b3-4393-b516-b07a53c018b3","name":"context_id","type":"string","value":"={{$('get wait seconds').item.json.context_id }}"}]}},"typeVersion":3.4,"notes":"This set node performs automated tasks as part of the workflow."},{"id":"0be7e5eb-1972-4a95-b5bf-4e564fc4ef7c","name":"Check Inactivity + Count","type":"n8n-nodes-base.if","position":[1580,720],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"loose"},"combinator":"and","conditions":[{"id":"0f294c51-0629-4ae1-a009-68c2f5fd30b5","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{$json.count != null && Number($json.count) >= 1}}","rightValue":""},{"id":"1626238d-fb00-4ce8-89df-a40a4f29f52a","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{$('Get last_seen').item.json.last_seen != null}}","rightValue":""},{"id":"df819099-1f6e-4bee-a017-32b729c836a3","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{($now.toMillis() - $('Get last_seen').item.json.last_seen) >= $('Mod input').item.json.waitSeconds * 1000}}","rightValue":""}]},"looseTypeValidation":true},"typeVersion":2.2,"notes":"This if node performs automated tasks as part of the workflow."},{"id":"0c3bd62b-8cf6-4b34-8010-ebe819db9667","name":"Delete waiting_reply1","type":"n8n-nodes-base.redis","position":[2940,1000],"parameters":{"key":"YOUR_CREDENTIAL_HERE","operation":"delete"},"credentials":{"redis":{"id":"zJtRI38KhsyVjUvP","name":"Redis account"}},"typeVersion":1,"notes":"This redis node performs automated tasks as part of the workflow."},{"id":"bbf45966-833b-4f5f-ae11-0578614eb156","name":"No Operation, do nothing2","type":"n8n-nodes-base.noOp","position":[720,540],"parameters":{},"typeVersion":1,"notes":"This noOp node performs automated tasks as part of the workflow."},{"id":"5683eebf-ba51-4a6b-a803-de6acf1b1ea8","name":"Wait","type":"n8n-nodes-base.wait","position":[2080,880],"webhookId":"b8e2e214-f82b-49c2-96e2-91e093137857","parameters":{"amount":"={{ Math.max(0, Math.ceil(( $('Mod input').item.json.waitSeconds * 1000 - ($now.toMillis() - $('Get last_seen').item.json.last_seen)) / 1000)) }}"},"typeVersion":1.1,"notes":"This wait node performs automated tasks as part of the workflow."},{"id":"c0478f60-944e-4c85-bb9c-9abe0d4238c0","name":"When Executed by Another Workflow","type":"n8n-nodes-base.executeWorkflowTrigger","position":[-480,720],"parameters":{"workflowInputs":{"values":[{"name":"context_id"},{"name":"message"}]}},"typeVersion":1.1,"notes":"This executeWorkflowTrigger node performs automated tasks as part of the workflow."},{"id":"91a650b7-ddd4-4dbf-a300-523f72f0bdb5","name":"Mock input data","type":"n8n-nodes-base.set","position":[-500,500],"parameters":{"options":{},"assignments":{"assignments":[{"id":"0543fdb7-4a22-4530-bdb7-ae7064732fae","name":"context_id","type":"string","value":"={{ $json.sessionId1 || '1lap075ha12' }}"},{"id":"bead5646-a689-4deb-8f4b-b22aa97b51ca","name":"message","type":"string","value":"={{ $json.chatInput || 'Chat 2'}}"}]}},"typeVersion":3.4,"notes":"This set node performs automated tasks as part of the workflow."},{"id":"cb450e32-7e19-469c-9a5c-3d9da5bf1dfa","name":"No Operation, do nothing3","type":"n8n-nodes-base.noOp","position":[3320,840],"parameters":{},"typeVersion":1,"notes":"This noOp node performs automated tasks as part of the workflow."},{"id":"b463e405-3355-48a2-a043-42941d7025c3","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[2880,660],"parameters":{"color":7,"width":700,"height":780,"content":"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n### 🧹 Buffer Cleanup\n\nAfter consolidation and reply:\n\n* **DELETE** keys:\n\n  * `buffer_in:{{context_id}}`\n  * `buffer_count:{{context_id}}`\n  * `waiting_reply:{{context_id}}`\n"},"typeVersion":1,"notes":"This stickyNote node performs automated tasks as part of the workflow."},{"id":"1b5397f8-aa7e-4b2b-afb9-5da97d99e049","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[-80,60],"parameters":{"color":7,"width":920,"height":940,"content":"### 📥 Input Buffer\n\n1. **Save incoming message**\n\n   * Push the new message into Redis list `buffer_in:{{context_id}}`.\n2. **Update metadata**\n\n   * Set `last_seen:{{context_id}}` to the current timestamp (with a TTL of `waitSeconds + 60`).\n   * INCR the counter key `buffer_count:{{context_id}}` (also expiring after `waitSeconds + 60`).\n3. **Check “waiting” flag**\n\n   * GET `waiting_reply:{{context_id}}`.\n   * If it’s null (no batch in flight), SET it to `true` with TTL `waitSeconds` to block concurrent triggers."},"typeVersion":1,"notes":"This stickyNote node performs automated tasks as part of the workflow."},{"id":"edc07500-ccad-4e72-adc1-1a63a3a06609","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[1180,340],"parameters":{"color":7,"width":1200,"height":820,"content":"### ⏳ Inactivity & Threshold Check\n\n1. **Fetch state**\n\n   * GET `last_seen:{{context_id}}` (when the last message arrived)\n   * GET `buffer_count:{{context_id}}` (how many messages are queued)\n2. **Evaluate trigger**\n\n   * **Inactivity:** `(now – last_seen) ≥ waitSeconds * 1000`\n   * **Or threshold:** `buffer_count ≥ 1` (or your desired batch size)\n3. **Branch**\n\n   * **True:** proceed to “Get buffer” and consolidate.\n   * **False:** exit (noOp) and let the waiting‐node/flag mechanism retry later."},"typeVersion":1,"notes":"This stickyNote node performs automated tasks as part of the workflow."},{"id":"error-ebf1478e","name":"Error Handler","type":"n8n-nodes-base.stopAndError","typeVersion":1,"position":[1000,400],"parameters":{"message":"Workflow execution error","options":{}}}],"connections":{"OpenAI Chat Model":{"main":[[]]}},"name":"Manualtrigger Workflow","settings":{"executionOrder":"v1","saveManualExecutions":true,"callerPolicy":"workflowsFromSameOwner","errorWorkflow":null,"timezone":"UTC","executionTimeout":3600,"maxExecutions":1000,"retryOnFail":true,"retryCount":3,"retryDelay":1000},"description":"Automated workflow: Manualtrigger Workflow. This workflow integrates 13 different services: stickyNote, wait, code, informationExtractor, redis. It contains 31 nodes and follows best practices for error handling and security.","notes":"Excellent quality workflow: Manualtrigger Workflow. This workflow has been optimized for production use with comprehensive error handling, security, and documentation."}