We’ve got a Node.js service listening to Genesys Cloud events via EventBridge. Lately, we’re seeing duplicate CONVERSATION_STARTED events for the same interaction ID. The event_id in the EventBridge payload is unique, but the underlying interactionId from Genesys is identical.
Here’s the payload structure:
{
"id": "abc-123-unique",
"detail": {
"interactionId": "xyz-789",
"eventType": "CONVERSATION_STARTED"
}
}
My current handler just processes everything it receives. I need a way to drop duplicates without storing every interaction ID in memory forever. Redis seems like the go-to, but I’m worried about the overhead of setting TTLs for millions of interactions.
Has anyone implemented a dedup layer for this? Are you using a bloom filter or just a simple Redis SET with a short TTL? Also, is there a chance Genesys retries the webhook if my endpoint times out, causing these duplicates?
doesn’t natively dedup, so you’ll need to track interactionId in a map with a TTL. If the ID exists and the timestamp is within your window, drop it. Otherwise, process and store. Simple enough.
You’re looking at this the wrong way. A simple in-memory map with a TTL is fine for dev, but it’s a memory leak waiting to happen in prod. If your Node process arts, you lose the state. If you scale out to multiple instances, they don’t share that map.
In my .NET integrations, I never trust client-side deduplication for critical event streams. I use an idempotency key stored in a distributed cache like Azure Redis or even DynamoDB. The key should be the interactionId combined with the event type.
Here’s how I handle it in C# using StackExchange.Redis. It’s basically the same logic in Node, just swap the client library.
// Pseudo-code for the concept
var cacheKey = $"event:{interactionId}:{eventType}";
var exists = await redisDb.StringAsync(cacheKey);
if (exists.HasValue)
{
// Already processed, ignore
Log.Warn($"Duplicate event detected for {interactionId}");
return;
}
// Process the event
await ProcessEvent(payload);
// Set key with a short TTL (e.g., 5 mins)
// Genesys rarely re-sends exact same event that fast, but covers network jitter
await redisDb.StringSetAsync(cacheKey, "1", TimeSpan.FromMinutes(5));
The doc quote that always trips people up is from the EventBridge spec: “Events may be delivered more than once. Consumers must be idempotent.” They aren’t joking. You can’t just hope the map works.
Also, check your subscription filter. Sometimes duplicates come from overlapping filters in the EventBridge console. If you have two subscriptions catching the same event pattern, you’ll get double hits before your code even runs.
I’ve seen this break queues when the cache is slow. If Redis is down, your system either blocks or drops events. You need a fallback. Maybe write to a dead-letter queue if the cache check fails, then retry later.
Don’t rely on event_id being unique if the business logic depends on interactionId. Two events can have different IDs but represent the same state change. Always dedup on the business key.