Implementing Automated After-Call Work Duration Analysis from Post-Interaction Desktop Activity

Implementing Automated After-Call Work Duration Analysis from Post-Interaction Desktop Activity

What This Guide Covers

This guide details the architectural implementation of automated After-Call Work (ACW) duration analysis using Genesys Cloud CX Architect flows and Event Streams. By the end of this process, you will have a system that captures ACW durations from agent desktop activity, evaluates them against dynamic thresholds based on interaction complexity, and triggers real-time alerts or data persistence for Quality Management review.

Prerequisites, Roles & Licensing

  • Licensing:
    • Genesys Cloud CX 2 or higher for standard Architect and Event Streams.
    • CX 3 or WEM Add-on license required if utilizing Workforce Engagement Management (WEM) dashboards for visualization.
    • Data Lake Add-on if you intend to persist raw ACW data for long-term trend analysis outside of standard reporting.
  • Permissions:
    • Flow > Edit (for Architect flow creation).
    • Event Streams > Edit (for stream configuration).
    • Routing > Queue > Edit (to modify queue settings if necessary).
    • Users > User > Edit (to assign agents to specific ACW rules).
  • Dependencies:
    • A configured Genesys Cloud instance with active telephony trunks.
    • Access to the Genesys Cloud Developer Portal for API integration if external middleware is used.
    • Understanding of the interaction object structure within Genesys Cloud.

The Implementation Deep-Dive

1. Defining the ACW Capture Mechanism in Architect

The foundation of accurate ACW analysis lies in how the platform records the transition from “Talking” to “Available” or “Not Ready.” Most organizations fail here by relying solely on the agent manually selecting an ACW reason code, which introduces human error and latency. Instead, you must instrument the flow to capture the exact timestamp of the interaction end and the subsequent desktop state change.

The Flow Structure

You need a dedicated sub-flow or a segment within your primary inbound/outbound flow that handles the post-interaction logic. This segment must execute after the End Interaction action but before the agent returns to the available pool.

  1. Create a New Flow: Name it ACW_Analysis_Engine.
  2. Add a “Start” Block: Set the trigger to Interaction End. This ensures the logic runs only when an interaction concludes.
  3. Capture Interaction Metadata: Use a Set Variable action to store critical data points:
    • interaction.id: The unique identifier for the call.
    • interaction.media.type: To distinguish between voice, chat, or email.
    • interaction.duration: The total talk time.
    • agent.id: The ID of the handling agent.
  4. Insert a “Wait” Block: This is critical. You cannot measure ACW instantly because the agent desktop state change is asynchronous relative to the flow execution. Set the wait duration to 0 seconds but add a condition that checks for the agent.state change. However, a more robust approach is to use the Get Agent Details action immediately after the interaction ends to fetch the current state.

The Trap: Relying on the interaction.acw.duration field directly from the interaction object. This field is often populated only after the ACW period has fully elapsed and the system has reconciled the data. If you query this field in real-time within the Architect flow, you will frequently receive null or 0 values, leading to false negatives in your analysis.

Architectural Reasoning: By capturing the interaction.end.timestamp and comparing it against the agent.state.change.timestamp via an Event Stream or a delayed flow action, you create a deterministic calculation. This bypasses the reconciliation lag inherent in the standard interaction object.

Code Snippet: Architect Set Variable Actions

[
  {
    "id": "set_var_1",
    "type": "setvariable",
    "name": "Capture Interaction ID",
    "variables": [
      {
        "name": "interactionId",
        "value": "{{ interaction.id }}"
      },
      {
        "name": "interactionEndTimestamp",
        "value": "{{ interaction.end.timestamp }}"
      },
      {
        "name": "agentId",
        "value": "{{ interaction.routing.agents[0].id }}"
      }
    ]
  }
]

2. Configuring Event Streams for Real-Time State Monitoring

Architect flows are event-driven but not always state-aware in real-time. To accurately measure ACW, you need to monitor the agent’s desktop activity events. Genesys Cloud provides Event Streams that push data to webhooks or internal endpoints.

Setting Up the Event Stream

  1. Navigate to Admin > Event Streams.
  2. Create a New Stream: Name it ACW_State_Changes.
  3. Select Event Types:
    • agent.state.change: This event fires every time an agent changes their state (e.g., from “Available” to “Not Ready - ACW”).
    • interaction.end: This event confirms the interaction has closed.
  4. Define the Filter:
    • Use the JSON filter to ensure you only receive events for agents currently in an ACW state.
    • Filter criteria: $.state.id contains the ID of your ACW Not Ready reason.

The Trap: Subscribing to all agent.state.change events without filtering. In a large contact center, this generates thousands of events per minute. If your downstream processor (or internal webhook) cannot handle the throughput, it will drop events, leading to missing ACW data. Always apply strict filters based on reason codes and queue associations.

Architectural Reasoning: Event Streams provide a decoupled architecture. The flow does not need to poll for agent state; instead, the platform pushes the state change to your analysis engine. This reduces latency and ensures that the ACW duration is calculated from the precise moment the agent selects the ACW reason, not when the flow finally executes a check.

Webhook Payload Example

When an agent enters ACW, the Event Stream sends a payload like this:

{
  "id": "evt_123456",
  "type": "agent.state.change",
  "timestamp": "2023-10-27T10:15:30.000Z",
  "data": {
    "agent": {
      "id": "agent_abc123",
      "name": "John Doe"
    },
    "state": {
      "id": "nr_acw_reason_1",
      "name": "After Call Work",
      "type": "not_ready"
    },
    "previousState": {
      "id": "available",
      "name": "Available",
      "type": "available"
    }
  }
}

3. Building the Analysis Engine with Data Actions

Now that you have the interaction end timestamp and the agent state change timestamp, you need to calculate the duration and evaluate it against thresholds. This is done using a combination of Architect Data Actions and external processing if complex logic is required.

Using Architect Data Actions for Simple Thresholds

For simple rules (e.g., “Alert if ACW > 5 minutes”), you can use the Evaluate Data Action node in Architect.

  1. Add a “Data Action” Node: Select “Evaluate” and choose a pre-built or custom data action.
  2. Define the Logic:
    • Input: interactionEndTimestamp, agentStateChangeTimestamp.
    • Calculation: duration = agentStateChangeTimestamp - interactionEndTimestamp.
    • Condition: if duration > 300 seconds (5 minutes).
  3. Trigger Action: If true, send a notification to the supervisor or log the event to a custom object.

The Trap: Using static thresholds for all agents and all interaction types. A 5-minute ACW for a simple password reset is excessive, but for a complex insurance claim, it might be normal. Static thresholds lead to alert fatigue and miss genuine inefficiencies.

Architectural Reasoning: Dynamic thresholds require context. You must enrich the ACW data with interaction complexity scores. This can be derived from the number of transfers, the duration of the talk time, or the specific queue the agent was in. By integrating these factors, your analysis becomes predictive rather than reactive.

Implementing Dynamic Thresholds via Custom Data Action

If your logic is complex, use a Custom Data Action. This allows you to write JavaScript or integrate with an external API.

  1. Create a Custom Data Action: Name it Evaluate_ACW_Complexity.
  2. Input Parameters:
    • interactionId
    • acwDuration
    • queueId
    • talkTime
  3. Logic:
    • Fetch the average ACW for the specific queue from a database or cache.
    • Calculate a Z-score: (acwDuration - averageACW) / standardDeviation.
    • If Z-score > 2, flag as outlier.
// Pseudo-code for Custom Data Action
function evaluateAcw(interactionId, acwDuration, queueId, talkTime) {
  const queueStats = getQueueStats(queueId); // Fetch from external DB or Genesys Analytics
  const avgAcw = queueStats.avgAcw;
  const stdDev = queueStats.stdDev;
  
  const zScore = (acwDuration - avgAcw) / stdDev;
  
  if (zScore > 2) {
    return {
      isOutlier: true,
      riskLevel: "High",
      message: `ACW duration ${acwDuration}s is significantly higher than average for queue ${queueId}`
    };
  } else {
    return {
      isOutlier: false,
      riskLevel: "Normal",
      message: "ACW duration within normal bounds"
    };
  }
}

4. Persisting Data for Long-Term Analytics

Real-time alerts are useful for immediate intervention, but long-term trend analysis requires persistent storage. Genesys Cloud provides several options for this.

Option A: Custom Objects

Use Genesys Cloud Custom Objects to store ACW analysis results.

  1. Create a Custom Object: Name it ACW_Analysis_Records.
  2. Define Fields:
    • interactionId (Text)
    • agentId (Text)
    • acwDuration (Integer)
    • isOutlier (Boolean)
    • timestamp (Date)
  3. Update the Custom Object: In your Architect flow, use the Update Custom Object action to insert the analysis result.

The Trap: Overloading Custom Objects with high-frequency data. Each write operation has a cost and rate limit. If you have 1,000 agents with 50 calls a day, that is 50,000 writes per day. Ensure your object design is efficient and consider batching writes if possible.

Architectural Reasoning: Custom Objects are integrated into the Genesys Cloud UI, allowing supervisors to view ACW outliers directly in the Admin console or via custom dashboards. This provides visibility without requiring external BI tools.

Option B: Data Lake and BigQuery

For enterprise-scale analysis, push data to the Genesys Cloud Data Lake.

  1. Configure Data Lake: Enable the interactions and agent_activity data sets.
  2. Export to BigQuery/Snowflake: Use the native integration to stream data to your warehouse.
  3. Build SQL Queries: Create queries that join interaction data with agent activity data to calculate ACW durations at scale.
-- Example SQL for BigQuery
SELECT 
  i.id AS interaction_id,
  a.id AS agent_id,
  TIMESTAMP_DIFF(a.end_timestamp, i.end_timestamp, SECOND) AS acw_duration_seconds
FROM 
  `genosys_interactions` i
JOIN 
  `genosys_agent_activity` a
ON 
  i.routing.agents[0].id = a.agent_id
WHERE 
  a.state = 'not_ready'
  AND a.reason_id = 'nr_acw_reason_1'
  AND TIMESTAMP_DIFF(a.end_timestamp, i.end_timestamp, SECOND) > 300;

The Trap: Ignoring data latency. Data Lake exports are not real-time. They are typically delayed by 15-30 minutes. Do not use this for real-time alerts. Use it for historical trend analysis and monthly performance reviews.

Architectural Reasoning: Separating real-time operational logic (Architect/Event Streams) from historical analytical logic (Data Lake) ensures that your system remains performant. Real-time systems must be lightweight; analytical systems can be heavy and complex.

Validation, Edge Cases & Troubleshooting

Edge Case 1: Agent State Race Conditions

The Failure Condition: An agent ends a call and immediately returns to “Available” without selecting an ACW reason. The system records an ACW duration of 0 seconds, but the agent actually spent 10 seconds reviewing notes on their screen.

The Root Cause: The interaction.end event fires before the agent has a chance to change their state. If the flow checks for ACW duration immediately, it misses the brief period where the agent was technically “on call” but not talking.

The Solution: Implement a “Grace Period” in your analysis logic. Define a minimum ACW threshold (e.g., 10 seconds) below which no alert is triggered. Additionally, use the agent.state.change event to capture the exact moment the agent leaves the “Talking” state, even if they do not select a specific ACW reason. If they go directly to “Available,” log this as “Zero ACW” rather than “Missing Data.”

Edge Case 2: Multi-Interaction Overlap

The Failure Condition: An agent handles two calls in rapid succession. The ACW for the first call overlaps with the talk time of the second call. The system calculates the ACW duration as negative or zero.

The Root Cause: The interaction.end.timestamp of the first call is later than the agent.state.change.timestamp for the second call’s start. This is a common scenario in high-volume centers.

The Solution: Use the interaction.routing.agents array to link interactions to agents correctly. In your analysis engine, ensure that you are calculating ACW duration based on the gap between interaction.end.timestamp and the next interaction.start.timestamp or agent.available.timestamp. If the gap is negative, set ACW duration to 0 and flag the interaction as “Overlapped.” This prevents skewed averages.

Edge Case 3: Timezone Discrepancies

The Failure Condition: Agents are spread across multiple time zones. ACW duration analysis shows anomalies during shift changes.

The Root Cause: Timestamps are stored in UTC. If your analysis dashboard does not convert timestamps to the agent’s local time, you may see artificial spikes in ACW duration at the end of a shift in one timezone while another starts.

The Solution: Always store and analyze timestamps in UTC. When presenting data to supervisors, convert to the agent’s local timezone using the agent.timezone property. Ensure your SQL queries or Custom Data Actions explicitly handle timezone conversion using libraries like moment.js or SQL’s AT TIME ZONE function.

Official References