Parsing nested JSON in v2.analytics.conversation.aggregate EventBridge events

I’m trying to instrument Genesys Cloud analytics events in New Relic using EventBridge. The v2.analytics.conversation.aggregate events contain deeply nested JSON structures that are hard to map to custom attributes. Here’s a sample payload:

{
 "detail": {
 "aggregates": [
 {
 "entityId": "queue-123",
 "metrics": {
 "acd-handle-time": { "value": 120.5 }
 }
 }
 ]
 }
}

I’ve tried using a Lambda function to parse this, but the nested structure varies based on the query parameters sent from GC.

  • Using AWS Lambda with Python 3.9
  • EventBridge rule triggers on v2.analytics.conversation.aggregate
  • Attempted to flatten JSON using json.dumps with custom separators
  • New Relic Lambda layer installed for automatic instrumentation

The issue is that the aggregates array can contain different metric keys depending on the original analytics query. I need a reliable way to extract specific metrics like acd-handle-time and talk-time into New Relic custom attributes.

Is there a standard approach to handling this variability? I don’t want to hardcode metric names in the Lambda function since new metrics might be added. Any suggestions on how to dynamically parse this while maintaining performance?

The Lambda overhead is going to kill your latency if you’re just trying to flatten that JSON for New Relic. You don’t need a full compute step for basic aggregation parsing. EventBridge supports native transformation rules that can extract those nested fields directly into the target payload before it even hits your Lambda or HTTP endpoint.

You can define a rule that matches on event.detail.aggregates[*] and then use the dynamic input transformer to map metrics['acd-handle-time'].value to a clean attribute like nr.acd.handleTime. This keeps the payload lightweight and avoids the cold start penalty of spinning up a Node runtime just to read a number.

If you absolutely must use a Lambda because you’re doing complex metric normalization, here’s how I structure the handler in Node.js to keep it fast. The key is avoiding deep cloning the whole event object. Just destructure what you need.

exports.handler = async (event) => {
 const { aggregates } = event.detail || [];
 
 const nrAttributes = aggregates.map(agg => ({
 entityId: agg.entityId,
 handleTime: agg.metrics?.['acd-handle-time']?.value || 0,
 timestamp: event.time
 }));

 // Send to New Relic Insights API directly
 await fetch('https://insights-api.newrelic.com/v1/accounts/12345/events', {
 method: 'POST',
 headers: { 'Api-Key': process.env.NR_API_KEY },
 body: JSON.stringify({ data: nrAttributes })
 });

 return { statusCode: 200 };
};

Be careful with the acd-handle-time key. It has a hyphen, so bracket notation is mandatory in JS. Dot notation will throw a syntax error. Also, make sure your IAM role for the Lambda has events:InvokeRule if you’re triggering from another service, but for standard EventBridge targets, the permission is usually implicit. The payload structure changes slightly if you’re using the new v2 analytics format versus the legacy one, so double-check the entityId format. Queue IDs usually start with a UUID, not a friendly name, unless you’re using custom entities.