Deploying the Genesys Cloud Web Messaging Widget with Custom Guest Attributes for Authenticated Users

Deploying the Genesys Cloud Web Messaging Widget with Custom Guest Attributes for Authenticated Users

What You Will Build

  • You will initialize the Genesys Cloud Web Messaging widget via JavaScript and inject custom guest attributes (such as user_id, email, and account_tier) for a user who has already authenticated in your application.
  • You will use the Genesys Cloud Web Messaging JavaScript SDK (genesys-cloud-messaging-widget).
  • You will cover the implementation in JavaScript (browser-side) and demonstrate how to verify the data flow using the Genesys Cloud API (Python) to retrieve conversation details.

Prerequisites

  • Genesys Cloud Organization: An active Genesys Cloud CX organization with Web Messaging enabled.
  • Web Messaging Configuration: A configured Web Messaging channel with a defined Organization ID and Widget Configuration ID.
  • JavaScript Environment: A modern web application (React, Vue, Angular, or vanilla HTML/JS) where you can inject scripts.
  • Python Environment: Python 3.9+ with requests installed for the verification step.
  • API Credentials: A Genesys Cloud API key or OAuth client credentials for the Python verification script.
  • Required Scopes:
    • For Widget Initialization: None (client-side).
    • For API Verification: analytics:query or conversations:read.

Authentication Setup

The Web Messaging widget itself does not require an OAuth token for initialization. It uses the organizationId and widgetConfigId to identify the channel. However, the Python verification script requires an OAuth token.

Python OAuth Token Acquisition

Use this code to obtain a token for the verification step. Replace placeholders with your API key and secret.

import requests
import json
import os

def get_genesys_token():
    """
    Acquires an OAuth token from Genesys Cloud using API Key/Secret.
    """
    api_key = os.getenv("GENESYS_API_KEY")
    api_secret = os.getenv("GENESYS_API_SECRET")
    
    if not api_key or not api_secret:
        raise ValueError("GENESYS_API_KEY and GENESYS_API_SECRET environment variables are required.")

    url = "https://api.mypurecloud.com/api/v2/authorization/token"
    headers = {
        "Content-Type": "application/x-www-form-urlencoded"
    }
    payload = f"grant_type=client_credentials&client_id={api_key}&client_secret={api_secret}"

    response = requests.post(url, data=payload, headers=headers)
    
    if response.status_code != 200:
        raise Exception(f"Failed to get token: {response.status_code} - {response.text}")
        
    data = response.json()
    return data["access_token"]

# Token caching is recommended in production. For this tutorial, we fetch it once.
TOKEN = get_genesys_token()

Implementation

Step 1: Initialize the Web Messaging Widget

The first step is to load the Genesys Cloud Web Messaging SDK and configure it with your organization and widget IDs. This code must run in the browser context.

Create a file named init-widget.js.

/**
 * Initializes the Genesys Cloud Web Messaging widget.
 * 
 * @param {string} orgId - The Genesys Cloud Organization ID.
 * @param {string} widgetConfigId - The Widget Configuration ID from the Genesys Cloud Admin UI.
 */
function initMessagingWidget(orgId, widgetConfigId) {
    // Load the SDK if not already loaded
    if (!window.GenesysCloudMessagingWidget) {
        const script = document.createElement('script');
        script.src = 'https://cdn.genesys.cloud/messaging-widget/1.0.0/genesys-cloud-messaging-widget.js';
        script.async = true;
        script.onload = () => configureWidget(orgId, widgetConfigId);
        document.head.appendChild(script);
    } else {
        configureWidget(orgId, widgetConfigId);
    }
}

function configureWidget(orgId, widgetConfigId) {
    const widget = window.GenesysCloudMessagingWidget;
    
    widget.configure({
        organizationId: orgId,
        widgetConfigId: widgetConfigId,
        // Optional: Set initial UI settings
        theme: {
            primaryColor: '#007bff',
            backgroundColor: '#ffffff'
        }
    });

    // Show the widget
    widget.show();
}

// Example Usage
// initMessagingWidget('YOUR_ORG_ID', 'YOUR_WIDGET_CONFIG_ID');

Expected Behavior:
The widget UI appears on the page. The conversation is not yet started. The widget is in a “ready” state, waiting for user interaction or programmatic message sending.

Step 2: Inject Custom Guest Attributes for Authenticated Users

When a user logs into your application, you should inject their identity and custom attributes into the widget. This ensures that when the conversation starts, the agent sees the user’s context immediately.

Genesys Cloud Web Messaging supports guestAttributes which are key-value pairs. These are visible to agents in the conversation sidebar and can be used for routing or IVR logic.

Create a file named set-guest-attributes.js.

/**
 * Sets custom guest attributes on the Web Messaging widget.
 * 
 * @param {Object} userData - The authenticated user's data.
 */
function setGuestAttributes(userData) {
    const widget = window.GenesysCloudMessagingWidget;
    
    if (!widget) {
        console.error("Widget not initialized.");
        return;
    }

    // Define the attributes to send
    // Note: Keys should be alphanumeric and underscored. Avoid spaces.
    const attributes = {
        user_id: userData.id,
        email: userData.email,
        account_tier: userData.accountTier,
        customer_since: userData.customerSince // ISO 8601 date string
    };

    try {
        // The setGuestAttributes method updates the current session's attributes
        widget.setGuestAttributes(attributes);
        console.log("Guest attributes set successfully:", attributes);
    } catch (error) {
        console.error("Failed to set guest attributes:", error);
    }
}

// Example Usage after user login:
// const loggedInUser = {
//     id: "usr_12345",
//     email: "john.doe@example.com",
//     accountTier: "premium",
//     customerSince: "2020-01-01T00:00:00Z"
// };
// setGuestAttributes(loggedInUser);

Critical Parameter Explanation:

  • setGuestAttributes: This method is part of the GenesysCloudMessagingWidget instance. It does not start the conversation. It only prepares the metadata.
  • Data Types: Values must be strings. If you need to send numbers or booleans, convert them to strings explicitly (e.g., String(true)).

Step 3: Start the Conversation Programmatically

To ensure the attributes are sent with the initial message, you can start the conversation programmatically. This is useful if you want to pre-fill the first message or trigger the chat without user clicking “Start Chat”.

/**
 * Starts the conversation with an optional initial message.
 * 
 * @param {string} initialMessage - The first message to send to the agent.
 */
function startConversation(initialMessage) {
    const widget = window.GenesysCloudMessagingWidget;
    
    if (!widget) {
        console.error("Widget not initialized.");
        return;
    }

    try {
        // startConversation initiates the WebSocket connection and sends the message
        widget.startConversation({
            message: initialMessage
        });
        console.log("Conversation started.");
    } catch (error) {
        console.error("Failed to start conversation:", error);
    }
}

// Example Usage:
// setGuestAttributes(loggedInUser);
// startConversation("Hello, I need help with my premium account.");

Edge Case Handling:
If the widget is already in an active conversation, startConversation may throw an error or be ignored. Always check the widget state if your application allows re-engagement.

function isConversationActive() {
    const widget = window.GenesysCloudMessagingWidget;
    // The SDK does not expose a direct 'isActive' boolean in all versions.
    // You may need to track state locally or listen for events.
    // For this tutorial, we assume a single session per page load.
    return false; // Placeholder for local state management
}

Step 4: Verify Attributes via Genesys Cloud API (Python)

After the conversation has been initiated and a message sent, you can verify that the guest attributes were correctly attached by querying the Genesys Cloud API.

Use the /api/v2/conversations/messaging/details endpoint to retrieve conversation details.

Create a file named verify_attributes.py.

import requests
import json
import os
from datetime import datetime, timedelta

def get_conversation_details(access_token, conversation_id):
    """
    Retrieves detailed information about a messaging conversation, including guest attributes.
    
    :param access_token: OAuth token for Genesys Cloud.
    :param conversation_id: The ID of the conversation to inspect.
    """
    url = f"https://api.mypurecloud.com/api/v2/conversations/messaging/details/{conversation_id}"
    
    headers = {
        "Authorization": f"Bearer {access_token}",
        "Content-Type": "application/json"
    }

    response = requests.get(url, headers=headers)
    
    if response.status_code == 404:
        print(f"Conversation {conversation_id} not found.")
        return None
        
    if response.status_code != 200:
        print(f"Error: {response.status_code}")
        print(response.text)
        return None

    return response.json()

def print_guest_attributes(conversation_data):
    """
    Extracts and prints guest attributes from the conversation details.
    """
    if not conversation_data:
        return

    # The guest attributes are nested within the 'participants' array
    # The guest is typically the participant with 'role': 'customer'
    participants = conversation_data.get("participants", [])
    
    for participant in participants:
        if participant.get("role") == "customer":
            guest_attributes = participant.get("guestAttributes", {})
            print("Found Guest Attributes:")
            for key, value in guest_attributes.items():
                print(f"  {key}: {value}")
            return

    print("No guest attributes found for the customer participant.")

# Example Usage
# 1. Trigger a conversation in the browser
# 2. Capture the conversation ID from the browser console or network tab
# 3. Run this script
# conversation_id = "YOUR_CONVERSATION_ID"
# details = get_conversation_details(TOKEN, conversation_id)
# print_guest_attributes(details)

Expected Response Structure:
The API response will contain a participants array. The customer participant will have a guestAttributes object containing the keys you set (user_id, email, etc.).

{
  "id": "conv_123456",
  "participants": [
    {
      "id": "part_789",
      "role": "customer",
      "guestAttributes": {
        "user_id": "usr_12345",
        "email": "john.doe@example.com",
        "account_tier": "premium",
        "customer_since": "2020-01-01T00:00:00Z"
      }
    }
  ]
}

Complete Working Example

Frontend (HTML/JS)

Create index.html.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Genesys Cloud Web Messaging with Custom Attributes</title>
    <style>
        body { font-family: sans-serif; padding: 20px; }
        button { padding: 10px 20px; cursor: pointer; }
    </style>
</head>
<body>
    <h1>Web Messaging Demo</h1>
    <button id="loginBtn">Simulate User Login</button>
    <button id="chatBtn" disabled>Start Chat</button>
    <p id="status">Status: Not logged in</p>

    <script>
        // Configuration
        const CONFIG = {
            organizationId: 'YOUR_ORG_ID', // Replace with your Org ID
            widgetConfigId: 'YOUR_WIDGET_CONFIG_ID' // Replace with your Widget Config ID
        };

        // State
        let widget = null;

        // Initialize Widget on Load
        window.addEventListener('load', () => {
            initMessagingWidget(CONFIG.organizationId, CONFIG.widgetConfigId);
        });

        function initMessagingWidget(orgId, widgetConfigId) {
            if (!window.GenesysCloudMessagingWidget) {
                const script = document.createElement('script');
                script.src = 'https://cdn.genesys.cloud/messaging-widget/1.0.0/genesys-cloud-messaging-widget.js';
                script.async = true;
                script.onload = () => {
                    widget = window.GenesysCloudMessagingWidget;
                    widget.configure({
                        organizationId: orgId,
                        widgetConfigId: widgetConfigId
                    });
                    document.getElementById('status').innerText = "Status: Widget Initialized";
                };
                document.head.appendChild(script);
            } else {
                widget = window.GenesysCloudMessagingWidget;
                widget.configure({
                    organizationId: orgId,
                    widgetConfigId: widgetConfigId
                });
                document.getElementById('status').innerText = "Status: Widget Initialized";
            }
        }

        // Simulate Login
        document.getElementById('loginBtn').addEventListener('click', () => {
            const userData = {
                id: "usr_" + Math.floor(Math.random() * 10000),
                email: "user@example.com",
                accountTier: "premium",
                customerSince: new Date().toISOString()
            };

            if (widget) {
                widget.setGuestAttributes({
                    user_id: userData.id,
                    email: userData.email,
                    account_tier: userData.accountTier,
                    customer_since: userData.customerSince
                });
                
                document.getElementById('status').innerText = "Status: Logged in. Attributes set.";
                document.getElementById('chatBtn').disabled = false;
            } else {
                document.getElementById('status').innerText = "Error: Widget not ready.";
            }
        });

        // Start Chat
        document.getElementById('chatBtn').addEventListener('click', () => {
            if (widget) {
                widget.startConversation({
                    message: "Hello, I am a premium customer."
                });
                document.getElementById('status').innerText = "Status: Chat started.";
            }
        });
    </script>
</body>
</html>

Backend Verification (Python)

Create verify.py.

import requests
import json
import os

def get_token():
    api_key = os.getenv("GENESYS_API_KEY")
    api_secret = os.getenv("GENESYS_API_SECRET")
    url = "https://api.mypurecloud.com/api/v2/authorization/token"
    headers = {"Content-Type": "application/x-www-form-urlencoded"}
    payload = f"grant_type=client_credentials&client_id={api_key}&client_secret={api_secret}"
    response = requests.post(url, data=payload, headers=headers)
    return response.json()["access_token"]

def check_conversation(conv_id, token):
    url = f"https://api.mypurecloud.com/api/v2/conversations/messaging/details/{conv_id}"
    headers = {"Authorization": f"Bearer {token}"}
    response = requests.get(url, headers=headers)
    
    if response.status_code == 200:
        data = response.json()
        for p in data.get("participants", []):
            if p.get("role") == "customer":
                attrs = p.get("guestAttributes", {})
                print(json.dumps(attrs, indent=2))
                return True
    else:
        print(f"Error: {response.status_code}")
    return False

if __name__ == "__main__":
    token = get_token()
    # Replace with actual conversation ID from browser network tab
    CONVERSATION_ID = input("Enter Conversation ID: ")
    check_conversation(CONVERSATION_ID, token)

Common Errors & Debugging

Error: 401 Unauthorized in API Verification

Cause: The OAuth token is expired or invalid. Genesys Cloud tokens expire after 1 hour.
Fix: Implement token caching and refresh logic. In the Python example, re-run get_token() if you receive a 401.

# Improved token handling
def get_token_cached():
    # Check local storage or memory for valid token
    # If expired, call get_token()
    pass

Error: Guest Attributes Not Showing in Agent UI

Cause: The attributes were set after the conversation started, or the widget configuration does not display custom attributes.
Fix: Ensure setGuestAttributes is called before startConversation. Check the Genesys Cloud Admin UI under Messaging > Widget Configuration to ensure the “Guest Attributes” section is enabled in the agent desktop layout.

Error: TypeError: widget.setGuestAttributes is not a function

Cause: The SDK has not fully loaded, or the version is incompatible.
Fix: Ensure the script tag loads successfully. Check the browser console for network errors loading genesys-cloud-messaging-widget.js. Verify the SDK version in the script URL matches the documentation for your organization.

Error: 429 Too Many Requests

Cause: You are hitting the API rate limit when verifying conversations.
Fix: Implement exponential backoff in your Python script.

import time

def get_conversation_with_retry(url, headers, retries=3):
    for i in range(retries):
        response = requests.get(url, headers=headers)
        if response.status_code == 429:
            wait_time = 2 ** i
            print(f"Rate limited. Waiting {wait_time} seconds...")
            time.sleep(wait_time)
            continue
        return response
    return None

Official References