Implementing Microsoft Dynamics 365 Screen Pop Using the Genesys Cloud Embeddable Framework
What This Guide Covers
This guide details the architectural implementation of an automated screen pop mechanism that retrieves Microsoft Dynamics 365 customer records upon initiation of a voice call or chat session within Genesys Cloud. Upon completion, the engineer will have a production-ready integration where the correct account record opens automatically in the Dynamics interface without manual lookup, utilizing the Genesys Cloud Embeddable Framework for secure context passing.
Prerequisites, Roles & Licensing
Successful implementation requires specific licensing tiers and permission configurations on both the Genesys Cloud platform and the Microsoft Dynamics 365 environment.
Genesys Cloud Requirements:
- Licensing Tier: Genesys Cloud CX Platform Edition or higher. The Embeddable Framework SDK is available on all supported plans, but API access for OAuth token generation requires a valid license for the user account performing the authentication.
- OAuth Application: You must create a custom OAuth Client within the Genesys Cloud Administration Console under
Integrations > OAuth Apps. This application type should be designated asPublicif running entirely in the browser, orConfidentialif utilizing a backend proxy for token storage. - Required Permissions: The following specific permission strings must be granted to the user account associated with the integration:
contactcenter:webchat:write(Required for chat context retrieval)integration:oauth:read(Required for token acquisition)integration:oauth:write(Required for token refresh operations if applicable)user:read(Required to resolve user IDs from the session context)
- OAuth Scopes: The authorization request must request the following scopes in the query string:
openid,contactcenter:webchat:write,integration:oauth:read.
Microsoft Dynamics 365 Requirements:
- Environment Version: Dynamics 365 Customer Engagement (Online) version 9.x or later. On-premises deployments require specific security token service configuration which is outside the scope of this guide.
- Web Resource: A new Web Resource must be created within the Dynamics solution to host the JavaScript SDK and integration logic. The resource type must be
Script (Web Resources). - Security Role: The user executing the screen pop must have the
System Customizersecurity role or equivalent privileges to modify forms and web resources if customizing the account view layout. - External Dependencies: A stable outbound connection from the Dynamics environment to the Genesys Cloud CDN (
*.genesys.cloud) is required for SDK loading.
The Implementation Deep-Dive
1. Genesys Cloud OAuth Application Configuration
The foundation of this integration relies on a secure handshake between the browser-based Embeddable Framework and the Genesys backend. You must configure the OAuth Client to allow the Dynamics Web Resource to initiate the authentication flow.
Configuration Steps:
- Navigate to Administration > Integrations > OAuth Apps in Genesys Cloud.
- Click Create App and provide a descriptive name such as
Dynamics365-Integration. - Set the Client Type to
Publicfor browser-based flows, though aConfidentialtype is preferred if a backend proxy exists to handle token storage. - In the Redirect URIs field, enter the exact URL of the Dynamics Web Resource or the form where the script will execute. For example:
https://your-org.crm.dynamics.com/Main.aspx?etc=108&pagetype=entityrecord. Note that if using a Web Resource, this is typically theWebResourceURI path. - Ensure Scopes are mapped correctly. The default scopes should include
openid,contactcenter:webchat:write, andintegration:oauth:read.
The Trap:
A common misconfiguration occurs when the Redirect URI in the Genesys OAuth App does not exactly match the callback URL expected by the Dynamics environment or vice versa. If the Redirect URI contains trailing slashes, query parameters, or different casing compared to the actual execution context, the authentication handshake fails immediately with a 403 Forbidden error from the Identity Provider. This results in silent failures where the screen pop does not trigger because no valid session token is established.
Architectural Reasoning:
We use a Public OAuth application for browser-based interactions to avoid requiring a backend proxy for every user interaction, which reduces latency. However, this requires that the client secret be managed carefully if the flow involves sensitive data transmission. The Redirect URI validation ensures that only trusted origins can receive authorization codes, preventing open redirect vulnerabilities where an attacker could capture tokens via a malicious domain.
2. Dynamics 365 Web Resource and SDK Initialization
The next step involves embedding the Genesys Cloud JavaScript SDK into the Dynamics environment and initializing the connection. This requires modifying the Dynamics form or creating a custom Web Resource that loads on specific entity views.
Configuration Steps:
- In Microsoft Power Apps, navigate to Solutions > [Your Solution] > Web Resources.
- Create a new Web Resource with type
Script. Upload the Genesys Cloud Embeddable Framework script file (typically namedgenesys.min.js). - Add the following initialization code to the Web Resource:
/*
* Dynamics 365 Screen Pop Initialization Script
* Loads Genesys Cloud SDK and binds context events
*/
(function() {
var GenesysConfig = {
cloudName: 'aws-1234567890', // Replace with your specific cloud name
clientId: 'YOUR_CLIENT_ID', // From OAuth App configuration
scope: 'openid contactcenter:webchat:write integration:oauth:read',
redirectUri: window.location.href
};
var script = document.createElement('script');
script.src = 'https://static.genesys.cloud/sdk/v1/gc-sdk.js';
script.onload = function() {
Genesys.init(GenesysConfig);
};
document.head.appendChild(script);
// Listen for context updates after initialization
Genesys.on('INITIALIZED', function() {
console.log('Genesys SDK Initialized');
Genesys.subscribe('CONTEXT_UPDATED', onContextUpdate);
});
function onContextUpdate(context) {
if (context && context.type === 'call') {
handleCallScreenPop(context);
} else if (context && context.type === 'chat') {
handleChatScreenPop(context);
}
}
function handleCallScreenPop(context) {
var phoneNumber = context.externalNumber; // The caller's number
lookupCustomer(phoneNumber);
}
function handleChatScreenPop(context) {
var chatId = context.id; // Unique identifier for the chat session
console.log('Chat session detected:', chatId);
}
})();
- Add this Web Resource to the Account form or a specific command bar action within Dynamics. Set the execution scope to
OnLoadorOnClickdepending on whether you want the pop to trigger automatically upon record load or via a button click.
The Trap:
The most frequent failure mode in this step is the lack of proper Content Security Policy (CSP) configuration. If your Dynamics environment enforces strict CSP headers that block scripts from loading external domains, the Genesys SDK will fail to load, and no events will fire. The browser console will report a Refused to load the script... error. Additionally, failing to wrap the code in an IIFE (Immediately Invoked Function Expression) creates global namespace pollution which can conflict with existing Dynamics JavaScript libraries, causing unpredictable behavior during form rendering.
Architectural Reasoning:
We initialize the SDK immediately upon document load to ensure event listeners are attached before any Genesys context events fire. The CONTEXT_UPDATED event is critical because it fires whenever the interaction state changes (e.g., a call starts, ends, or transfers). By subscribing to this event rather than polling for data, we reduce CPU overhead and ensure near real-time responsiveness. We use window.location.href for the redirect URI to dynamically capture the current context in case the URL structure varies across different Dynamics entities or environments.
3. Context Mapping and Data Retrieval Logic
Once the SDK is initialized and events are captured, you must map the Genesys context data (such as phone numbers) to the corresponding identifiers in Microsoft Dynamics (such as Account GUIDs). This step requires a secure method to query your CRM without exposing credentials on the client side.
Configuration Steps:
- Create a Web API endpoint within Dynamics or use the standard
Xrm.WebApiobject exposed to web resources. - Implement the
lookupCustomerfunction to query theAccountentity based on the phone number retrieved from Genesys. - Ensure the script handles cases where multiple accounts match a phone number or no account exists.
function lookupCustomer(phoneNumber) {
var queryString = `?$filter=phone1 eq '${phoneNumber}'`;
Xrm.WebApi.retrieveMultipleRecords('account', queryString)
.then(function(success) {
if (success.entities.length > 0) {
var accountId = success.entities[0].id;
navigateToRecord(accountId);
} else {
console.warn('No account found for phone number:', phoneNumber);
createNewAccount(phoneNumber);
}
})
.catch(function(error) {
console.error('Dynamics API Error:', error);
});
}
function navigateToRecord(accountId) {
var recordUrl = window.location.origin + '/Main.aspx?etn=account&id=' + accountId;
window.open(recordUrl, '_blank');
}
function createNewAccount(phoneNumber) {
// Logic to trigger the Create Account wizard or pre-populate a new form
console.log('Initiating new record creation for:', phoneNumber);
}
The Trap:
A critical security and performance trap involves passing PII (Personally Identifiable Information) like phone numbers in URL query parameters during navigation. If you attempt to pass the phone number directly in the window.open URL as a parameter, it may be logged in server access logs or browser history, violating PCI-DSS compliance requirements for certain data retention policies. Furthermore, using string interpolation in the Xrm.WebApi.retrieveMultipleRecords query without sanitization exposes the integration to SQL injection-like attacks if the phone number is malformed.
Architectural Reasoning:
We use Xrm.WebApi because it handles authentication tokens automatically within the Dynamics context and respects user security roles. We do not hardcode API keys or secrets in this script; instead, we rely on the authenticated Dynamics session token. The fallback logic (createNewAccount) ensures business continuity if a record does not exist, preventing agent frustration when no data is returned. This separation of concerns keeps the Genesys SDK responsible for telephony context and the Web Resource responsible for CRM logic, adhering to the Single Responsibility Principle.
4. Error Handling and Fallback Mechanisms
Production environments are subject to network latency, API timeouts, and transient authentication failures. The integration must include robust error handling to prevent the agent from being left in a degraded state where the screen pop fails silently.
Configuration Steps:
- Implement a retry mechanism for failed Web API calls within the
lookupCustomerfunction. - Add a fallback UI notification or toast message if the record retrieval fails after retries.
- Log all errors to a centralized monitoring system (e.g., Application Insights) for post-mortem analysis.
async function lookupCustomer(phoneNumber, maxRetries = 3) {
for (var i = 0; i < maxRetries; i++) {
try {
var queryString = `?$filter=phone1 eq '${phoneNumber}'`;
var result = await Xrm.WebApi.retrieveMultipleRecords('account', queryString);
if (result.entities.length > 0) {
return result.entities[0].id;
} else {
console.warn('No account found for phone number:', phoneNumber);
break; // Stop retrying, record does not exist
}
} catch (error) {
if (i === maxRetries - 1) {
throw error; // Re-throw on last attempt
}
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1))); // Exponential backoff
}
}
}
The Trap:
Developers often implement simple try-catch blocks that swallow errors to prevent page crashes. This leads to “silent failures” where the agent sees no error message but also sees no screen pop, leading them to believe the system is broken. In this scenario, the Genesys context event fires successfully, but the subsequent Web API call fails due to a timeout or network blip. Without explicit logging and user feedback, troubleshooting becomes impossible in production.
Architectural Reasoning:
We use asynchronous/await patterns for better readability and error propagation compared to nested callbacks. The exponential backoff strategy prevents overwhelming the Dynamics API during transient spikes while ensuring eventual consistency. By throwing errors on the final retry, we force the calling code to handle the failure state explicitly, allowing us to display a user-friendly message rather than letting the browser hang.
Validation, Edge Cases & Troubleshooting
Edge Case 1: Authentication Token Expiry During Session
The Failure Condition: An agent is actively in a call or chat session when their Genesys Cloud OAuth token expires due to idle time. The screen pop logic fails to execute because the SDK cannot refresh the token automatically in the background without user interaction in some configurations.
The Root Cause: The Embeddable Framework relies on the browser storing the access token. If the token expires while the script is running, subsequent API calls fail with 401 Unauthorized. This is exacerbated if the Genesys Cloud OAuth App is configured for a short token lifespan without automatic refresh logic in the SDK integration.
The Solution: Configure the Genesys Cloud OAuth App to issue longer-lived tokens (up to 60 minutes) or implement a heartbeat mechanism that checks Genesys.auth status periodically. If authentication fails, trigger a re-authentication flow by redirecting the user back to the login page or refreshing the session via the Genesys.login() method if supported in your version.
Edge Case 2: Call Context Mismatch (External vs Internal)
The Failure Condition: The screen pop triggers for internal transfer calls where no phone number is available, resulting in a search failure or an error message being displayed to the agent.
The Root Cause: Genesys Cloud sometimes passes internalNumber or systemNumber instead of externalNumber during transfers or queue routing events. The script logic strictly expects context.externalNumber, which may be null or undefined for internal interactions.
The Solution: Add a validation check in the handleCallScreenPop function to verify if context.externalNumber exists. If it does not, attempt to use context.internalNumber or query based on the user ID associated with the call (context.userId). This ensures that screen pops occur for all call types, not just inbound external calls.
Edge Case 3: Cross-Origin Resource Sharing (CORS) Issues in Dynamics
The Failure Condition: The Genesys SDK loads successfully, but API calls to the Dynamics Web API fail with a CORS error in the browser console (Access to XMLHttpRequest at... has been blocked by CORS policy).
The Root Cause: This occurs when the script is loaded from one domain (Genesys CDN) and attempts to make requests to another domain (Dynamics CRM Online) without proper CORS headers configured on the Dynamics tenant. While standard Web Resources usually bypass this, custom API endpoints or specific browser configurations can trigger this blockage.
The Solution: Verify that the Dynamics environment is configured to allow cross-origin requests for the Genesys CDN domains. In most cases, using Xrm.WebApi avoids CORS issues because it handles authentication headers automatically. If using a custom endpoint, ensure the response headers include Access-Control-Allow-Origin: * or the specific domain of the Genesys SDK.