Designing Employee Net Promoter Score (eNPS) Survey Integration with Agent Desktop Delivery

Designing Employee Net Promoter Score (eNPS) Survey Integration with Agent Desktop Delivery

What This Guide Covers

This guide details the architecture and implementation of a production-grade eNPS survey system delivered natively within the Genesys Cloud Agent Desktop. You will configure a secure OAuth integration with a third-party survey provider, design a non-blocking Flow trigger mechanism, develop a desktop extension that renders the survey in-context, and build a server-side scoring pipeline that pushes validated eNPS metrics to your analytics warehouse. The end result is a compliant, sub-second delivery mechanism that captures agent interaction context without degrading wrap-up performance.

Prerequisites, Roles & Licensing

  • Licensing Tier: Genesys Cloud CX 3 or CX 4 (required for Advanced Desktop Extensions, Integrator, Flow Designer, and Data Hub)
  • Granular Permissions:
    • Desktop Extension > Manage
    • Integration > Edit
    • Flow > Edit
    • Interaction > View
    • Reporting > View
    • User > View (for agent context mapping)
  • OAuth Scopes: urn:gen:apps:desktop, urn:gen:apps:integrations, urn:gen:flows:edit, urn:gen:interactions:view, urn:gen:users:view
  • External Dependencies:
    • Enterprise survey platform (Qualtrics, Medallia, or custom REST API)
    • Corporate identity provider supporting OAuth 2.0 Client Credentials flow
    • Target analytics warehouse or data lake endpoint (Snowflake, BigQuery, or Genesys Data Hub)

The Implementation Deep-Dive

1. Establishing the Secure Integration Layer & OAuth Handshake

The foundation of this architecture is a decoupled integration layer that authenticates with your survey provider without exposing credentials to Flow logic or client-side code. You will configure a Genesys Cloud Integrator connection that handles token rotation and secure payload transformation.

Create a new Integration in Genesys Cloud with the REST API connector type. Configure the authentication method as OAuth 2.0 Client Credentials. Input your survey provider client ID, client secret, and token endpoint. Define two primary actions: FetchSurveyToken and SubmitSurveyResponse.

The FetchSurveyToken action must return a short-lived, single-use token bound to the agent ID and interaction ID. Your survey provider should support claim-based token generation to prevent replay attacks. Configure the request body in the Integrator action as follows:

POST https://api.survey-provider.com/v1/tokens/generate
Content-Type: application/json
Authorization: Bearer <integrator-oauth-token>

{
  "grant_type": "client_credentials",
  "scope": "survey:read survey:write",
  "claims": {
    "sub": "{{agent_id}}",
    "interaction_id": "{{interaction_id}}",
    "exp_offset_seconds": 300
  }
}

The Trap: Storing the survey provider API keys directly within Flow data nodes or desktop extension environment variables. When you export a Flow for migration or enable debug logging, plain-text credentials are serialized into the JSON backup. This causes credential leakage during audit reviews or when sharing flows across environments.

Architectural Reasoning: We isolate credentials within the Integrator because it supports encrypted secret storage and automatic token rotation. The Integrator acts as a reverse proxy that strips sensitive headers before passing sanitized responses to the Flow. This separation of concerns ensures that business logic developers never handle raw secrets, and security teams can rotate credentials without triggering Flow redeployments or desktop extension cache invalidation.

2. Designing the Flow-Driven Trigger Mechanism

Survey delivery must occur during the agent wrap-up phase, but it must never block the desktop UI. You will design a Flow that triggers on Interaction Ended, calls the Integrator action asynchronously, and attaches the survey token to the interaction context for the desktop extension to consume.

In Flow Designer, create a new Flow with the Wrap-up trigger type. Set the trigger condition to Wrap-up Code Selected or Interaction Status Changed to Ended. Add a Call External API block that references the FetchSurveyToken Integrator action. Map the agent_id and interaction_id from the trigger payload to the action parameters.

Configure the API call block with a strict timeout of 3000 milliseconds. Route the success path to a Set Data block that writes the returned token to Interaction.eNPS_SurveyToken. Route the failure path to a Log block that records the error code without halting the wrap-up process.

{
  "action": "CallExternalAPI",
  "name": "FetchSurveyToken",
  "timeout": 3000,
  "parameters": {
    "agent_id": "{{trigger.user.id}}",
    "interaction_id": "{{trigger.interaction.id}}"
  },
  "output": {
    "token": "{{response.body.token}}",
    "expires_at": "{{response.body.expires_at}}"
  }
}

The Trap: Using a synchronous API call without a fallback timeout or error routing. Under peak wrap-up volume, the survey provider endpoint may experience latency spikes. A synchronous block waits indefinitely, freezing the agent desktop, triggering session timeouts, and causing queue abandonment metrics to degrade artificially.

Architectural Reasoning: We enforce a hard timeout and async routing because agent wrap-up experience directly impacts handle time and agent satisfaction. The Flow must complete within 200 milliseconds to maintain desktop responsiveness. By decoupling token generation from the critical UI path, we guarantee that survey failures never impact core telephony operations. The token is cached in the interaction object, allowing the desktop extension to poll or render immediately upon wrap-up completion.

3. Building the Desktop Extension for In-Context Delivery

The survey must render within the agent desktop without navigating away from the interaction summary. You will develop a Genesys Cloud Desktop Extension using the official SDK, which injects a secure iframe or embedded component into the wrap-up panel.

Initialize a new extension project using the Genesys Cloud CLI. Configure the manifest.json to target the wrap-up panel and declare the required permissions:

{
  "name": "eNPS Survey Delivery",
  "version": "1.0.0",
  "permissions": [
    "interaction:view",
    "user:view"
  ],
  "panels": [
    {
      "id": "wrap-up",
      "type": "panel",
      "title": "eNPS Feedback",
      "component": "src/components/SurveyPanel.tsx"
    }
  ]
}

In SurveyPanel.tsx, retrieve the survey token from the interaction context using the SDK. Validate the token expiration before rendering. Use a strict Content Security Policy to restrict iframe communication.

import { useInteractionContext } from '@genesyscloud/desktop-sdk';
import { useEffect, useState } from 'react';

export const SurveyPanel = () => {
  const { interaction } = useInteractionContext();
  const [surveyToken, setSurveyToken] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    if (!interaction?.eNPS_SurveyToken) {
      setError('Survey token not available. Wrap-up may have expired.');
      return;
    }

    const expiresAt = new Date(interaction.eNPS_SurveyExpiresAt);
    if (expiresAt.getTime() < Date.now()) {
      setError('Survey token expired. Please contact support.');
      return;
    }

    setSurveyToken(interaction.eNPS_SurveyToken);
  }, [interaction]);

  if (error) return <div className="error-state">{error}</div>;
  if (!surveyToken) return <div className="loading-state">Initializing survey...</div>;

  return (
    <iframe
      src={`https://secure.survey-provider.com/embed?token=${surveyToken}`}
      title="eNPS Survey"
      sandbox="allow-scripts allow-same-origin allow-forms"
      style={{ width: '100%', height: '400px', border: 'none' }}
    />
  );
};

The Trap: Implementing cross-origin message passing without strict origin validation. Developers often use window.addEventListener('message', handler) to receive survey completion events. If you do not verify event.origin, a compromised survey provider domain or a malicious iframe injection can execute arbitrary JavaScript within the desktop sandbox. This breaks the platform security model and exposes session tokens.

Architectural Reasoning: We rely on the browser’s native iframe sandboxing and CSP headers instead of custom postMessage handlers. The survey provider submits responses directly to their backend, which triggers a webhook to Genesys Cloud. This eliminates client-side data handling entirely. The desktop extension acts solely as a presentation layer, reducing attack surface and ensuring that survey logic remains isolated from the core desktop runtime.

4. Implementing the eNPS Scoring & Telemetry Pipeline

Raw survey responses must be normalized, scored, and routed to your analytics pipeline before they become actionable. You will configure a webhook receiver in Genesys Cloud that calculates eNPS server-side and pushes structured telemetry to Data Hub.

Create a new Flow with the Webhook trigger type. Set the endpoint to a dedicated Genesys Cloud webhook listener. Parse the incoming JSON payload to extract the raw score, agent ID, interaction ID, and timestamp. Apply the standard eNPS classification logic:

  • Promoter: 9-10
  • Passive: 7-8
  • Detractor: 0-6

Add a Set Data block to calculate the category and a Call External API block to push the record to your target warehouse. Use the Integrator to handle authentication with the analytics endpoint.

{
  "action": "SetData",
  "name": "CalculateENPSCategory",
  "data": {
    "raw_score": "{{trigger.body.score}}",
    "category": "{{#if (gte trigger.body.score 9)}}Promoter{{else if (gte trigger.body.score 7)}}Passive{{else}}Detractor{{/if}}",
    "agent_id": "{{trigger.body.agent_id}}",
    "interaction_id": "{{trigger.body.interaction_id}}",
    "timestamp": "{{trigger.body.timestamp}}"
  }
}

Configure the downstream API call to POST to your analytics warehouse. Ensure the payload includes the interaction metadata required for WFM and Speech Analytics correlation.

POST https://analytics.internal/api/v1/enps_events
Content-Type: application/json
Authorization: Bearer <warehouse-oauth-token>

{
  "event_type": "enps_submission",
  "agent_id": "{{data.agent_id}}",
  "interaction_id": "{{data.interaction_id}}",
  "raw_score": "{{data.raw_score}}",
  "category": "{{data.category}}",
  "submitted_at": "{{data.timestamp}}",
  "metadata": {
    "queue_id": "{{trigger.body.queue_id}}",
    "wrap_up_code": "{{trigger.body.wrap_up_code}}"
  }
}

The Trap: Calculating eNPS categories on the client side or within the survey provider UI before transmission. Client-side scoring allows network interception and score manipulation. It also fragments the audit trail, making it impossible to verify that the original raw score matches the categorized metric during compliance reviews.

Architectural Reasoning: We enforce server-side classification within Genesys Cloud because eNPS is a regulated workforce metric in healthcare and finance verticals. Centralized calculation ensures a single source of truth. The Flow acts as the authoritative scoring engine, guaranteeing that all downstream reports, dashboards, and WFM integrations reference identical categorization logic. This approach also enables real-time anomaly detection, such as flagging agents with sudden detractor spikes for coaching interventions.

Validation, Edge Cases & Troubleshooting

Edge Case 1: Concurrent Interaction Context Collision

  • The failure condition: An agent handles multiple wrap-ups simultaneously. The desktop extension fetches the survey token from the wrong interaction object, displaying a survey bound to a closed interaction.
  • The root cause: The extension reads from a global interaction store without filtering by the active wrap-up session ID. Genesys Cloud desktop context switches can race with token polling.
  • The solution: Bind the extension component to the specific interaction.id passed in the wrap-up trigger. Implement a version check on Interaction.eNPS_SurveyToken that validates against the active session UUID. If the IDs mismatch, suppress rendering and log a context collision warning.

Edge Case 2: Survey Provider Rate Limiting During Peak Wrap-Up

  • The failure condition: During post-campaign surges, the survey provider returns HTTP 429 responses. The Flow fails to attach tokens, and agents receive an empty survey panel.
  • The root cause: Synchronous token requests flood the provider endpoint. The Integrator lacks retry logic with exponential backoff.
  • The solution: Configure the Integrator action with a retry policy of 3 attempts, 500ms initial delay, and 2x backoff multiplier. Implement a token pre-fetch pattern in the Flow that requests tokens 15 seconds before wrap-up begins. Cache tokens in a short-lived data node and invalidate them after 300 seconds. This smooths request distribution and prevents endpoint throttling.

Edge Case 3: Desktop Extension Lifecycle Mismatch

  • The failure condition: The agent closes the wrap-up panel before the survey iframe fully loads. The extension throws unhandled promise rejections and crashes the desktop panel.
  • The root cause: The extension does not implement cleanup hooks. React components remain mounted in memory after panel dismissal, attempting to fetch data from destroyed interaction contexts.
  • The solution: Implement a useEffect cleanup function that aborts pending API calls using AbortController. Subscribe to the Genesys Cloud desktop panel:unmount event and forcefully clear the iframe DOM node. Add try-catch wrappers around all SDK context calls to prevent unhandled exceptions from bubbling to the desktop runtime.

Official References