Filtering EventBridge conversation.end by queue ID in pattern matching

We’ve got a Terraform setup managing our Genesys Cloud webhooks, and I’m trying to configure an EventBridge rule that only triggers on conversation.end events for a specific queue. The goal is to keep the consumer lambda lean, but the pattern matching syntax is giving me a headache. I know EventBridge doesn’t support deep nested lookups like detail.queue.id directly in the rule, but I figured I’d try using the detail-type and some basic structure matching. Here’s the JSON pattern I dropped into the aws_cloudwatch_event_rule resource:

{
 "source": ["genesys.cloud"],
 "detail-type": ["conversation.end"],
 "detail": {
 "queue": {
 "id": ["550e8400-e29b-41d4-a716-446655440000"]
 }
 }
}

The problem is that this rule fires for literally every conversation end, regardless of the queue. I’ve verified the queue ID is correct by checking the /api/v2/queues endpoint, and the events definitely contain the queue object in the payload. Is the queue object just not part of the filterable attributes in the EventBridge schema for this event type? It feels like I’m missing a key field or the structure is slightly different than the raw JSON payload suggests.

I’ve already tried adding "detail": {"conversation": {"channel": ["voice"]}} to narrow it down, and that part works fine. The channel filter sticks, but the queue ID filter seems to be ignored entirely by the rule engine. I’m wondering if I need to use a different attribute, maybe something under routing or analytics? Or is this a known limitation where I just have to accept the noise and filter everything in the lambda handler? I’d really rather not process thousands of irrelevant events just to drop them a second later. Anyone else hit this wall with the CX-as-Code provider?

EventBridge doesn’t support deep nesting. You’ll need to filter in the Lambda. Here’s the handler snippet:

def handler(event, context):
 target_queue = event['detail']['routing'].get('queueId')
 if target_queue != 'your-queue-id':
 return {'statusCode': 200, 'body': 'ignored'}
 # process

Just check the routing object in the detail payload.

The suggestion above works fine for the handler, but I’d argue you shouldn’t let the Lambda run at all if you can help it. EventBridge supports filtering on nested JSON attributes, you just have to use the correct syntax in the rule definition. It’s not as straightforward as a simple key match, but it saves you a lot of cold starts and processing time.

You need to define the pattern in the EventPattern block of your Terraform aws_cloudwatch_event_rule resource. Specifically, you’ll target the detail object. Here is how I structure it in my Terraform files to catch a specific queue. Make sure the queueId value is the actual ID string, not the name.

resource "aws_cloudwatch_event_rule" "genesys_queue_filter" {
 name = "genesys-conversation-end-queue-filter"
 description = "Filter conversation.end events for Queue X"
 event_pattern = jsonencode({
 "source" = ["genesys.cloud"]
 "detail-type" = ["Conversation Ended"]
 "detail" = {
 "routing" = {
 "queueId" = ["<YOUR-QUEUE-ID>"] 
 }
 }
 })
}

This pushes the filtering logic down to the event bus level. The Lambda only fires when that specific queue ID is present in the routing object. It’s a bit more verbose to set up in Terraform compared to a simple string match, but it keeps your compute costs low. Just double-check that the detail-type matches exactly what Genesys sends, which is usually “Conversation Ended” for the end event.