Yes, this works.
I’ll try to optimize, but if anyone want to help…
{
"name": "",
"nodes": [
{
"parameters": {},
"name": "Start",
"type": "n8n-nodes-base.start",
"typeVersion": 1,
"position": [
250,
300
]
},
{
"parameters": {
"httpMethod": "POST",
"path": "f1eb9c3a-5a02-4f3e-9c86-0784115c03d9",
"responseMode": "lastNode",
"options": {}
},
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [
250,
150
],
"webhookId": "f1eb9c3a-5a02-4f3e-9c86-0784115c03d9"
},
{
"parameters": {
"operation": "set",
"key": "=debounce-{{$json[\"id\"]}}",
"value": "hit",
"keyType": "string",
"expire": true,
"ttl": "={{$node[\"Debounce Time\"].parameter[\"values\"][\"number\"][0][\"value\"]}}"
},
"name": "Redis",
"type": "n8n-nodes-base.redis",
"typeVersion": 1,
"position": [
820,
150
],
"credentials": {
"redis": "Redis Local"
},
"notes": "Edit {{$json[\"id\"]}} to match on different properties"
},
{
"parameters": {
"functionCode": "const waitTimeSeconds = $items(\"Debounce Time\")[0].json[\"debounce_seconds\"];\nreturn new Promise((resolve) => {\n setTimeout(() => {\n resolve(items);\n }, waitTimeSeconds * 1000+100);\n});\n"
},
"name": "Sleep",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [
990,
150
]
},
{
"parameters": {
"values": {
"number": [
{
"name": "debounce_seconds",
"value": 30
}
]
},
"options": {}
},
"name": "Debounce Time",
"type": "n8n-nodes-base.set",
"typeVersion": 1,
"position": [
630,
150
]
},
{
"parameters": {
"functionCode": "return items[0].json.body\n.map(i => { return { json: i}});"
},
"name": "GetIds",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [
440,
150
]
},
{
"parameters": {
"operation": "keys",
"keyPattern": "debounce-*"
},
"name": "Redis1",
"type": "n8n-nodes-base.redis",
"typeVersion": 1,
"position": [
1150,
150
],
"credentials": {
"redis": "Redis Local"
}
},
{
"parameters": {
"functionCode": "const debounced = items[0].json;\n//return debounced;\nreturn $items(\"Sleep\").filter(it => {\n return !debounced.hasOwnProperty(\"debounce-\"+it.json.id);\n});"
},
"name": "RemoveBouncedItems",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [
1330,
150
]
}
],
"connections": {
"Redis": {
"main": [
[
{
"node": "Sleep",
"type": "main",
"index": 0
}
]
]
},
"Debounce Time": {
"main": [
[
{
"node": "Redis",
"type": "main",
"index": 0
}
]
]
},
"GetIds": {
"main": [
[
{
"node": "Debounce Time",
"type": "main",
"index": 0
}
]
]
},
"Webhook": {
"main": [
[
{
"node": "GetIds",
"type": "main",
"index": 0
}
]
]
},
"Sleep": {
"main": [
[
{
"node": "Redis1",
"type": "main",
"index": 0
}
]
]
},
"Redis1": {
"main": [
[
{
"node": "RemoveBouncedItems",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {}
}