EventBridge deduplication: How to filter duplicate Genesys Cloud events?

Here is the raw JSON I’m getting in my Lambda handler. I see the exact same event twice with millisecond differences in the timestamp.

{
 "id": "1234-5678-90ab-cdef",
 "source": "genesys.cloud",
 "account_id": "my-account-id",
 "detail": {
 "event_type": "conversation.analyzed",
 "timestamp": 1700000001123,
 "conversation_id": "abc-123"
 }
}

The second one comes in with 1700000001124 but the conversation_id and event_type are identical. It’s driving me crazy because my WFM script processes it twice and doubles our adherence penalties.

I tried adding a conditional in my Python code to check if the ID exists in a local set before processing, but that doesn’t scale well when the Lambda runs concurrently. I don’t want to store state in memory.

Is there a way to configure the Genesys Cloud EventBridge integration to not send duplicates in the first place? Or is there a standard pattern for deduplicating these in AWS?

I’m using the boto3 SDK to query the conversation details after receiving the event. The API call itself is fine, but the volume of duplicate triggers is killing my costs.

def handler(event, context):
 detail = event['detail']
 conv_id = detail.get('conversation_id')
 # How do I check if this was already processed?
 process_conversation(conv_id)

Any advice would be appreciated. I’m just trying to get accurate data for our Central Time shift reports.

EventBridge doesn’t deduplicate based on the payload content by default, so you’re stuck with what the source sends. Genesys Cloud retries on failure, which explains the millisecond shift. You need to handle this downstream.

In your Lambda, cache the conversation_id + event_type combination. A simple Redis or DynamoDB TTL-based check works best. Here’s how I structure the filter in Python:

import boto3
import time

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('EventDedup')

def handler(event, context):
 detail = event['detail']
 dedup_key = f"{detail['conversation_id']}_{detail['event_type']}"
 
 # Check if we've seen this recently
 response = table.get_item(Key={'id': dedup_key})
 
 if 'Item' in response:
 return {"statusCode": 200, "body": "Duplicate ignored"}
 
 # Process event
 process_event(detail)
 
 # Set TTL for 5 minutes (adjust based on retry window)
 table.put_item(Item={
 'id': dedup_key,
 'timestamp': time.time(),
 'ttl': int(time.time()) + 300
 })

Make sure your table has a TTL attribute configured. The retry window is usually short, so 5 minutes is safe.