How to Configure Web Messaging Deployment Colors and Position via API

How to Configure Web Messaging Deployment Colors and Position via API

What You Will Build

  • A Python script that programmatically creates or updates a Genesys Cloud Web Messaging deployment with specific visual styles (launcher button color, background color) and positioning (top/bottom, left/right).
  • This tutorial uses the Genesys Cloud PureCloudPlatformClientV2 SDK.
  • The programming language covered is Python 3.8+.

Prerequisites

  • OAuth Client: A Genesys Cloud OAuth client with public or confidential grant type.
  • Required Scopes: webmessaging:deployment:write (to create/update deployments) and webmessaging:deployment:read (to list existing deployments).
  • SDK Version: Genesys Cloud Python SDK version >= 180.0.0.
  • Dependencies:
    • genesys-cloud-sdk-python
    • requests (for raw HTTP examples if needed, though SDK is preferred here)

Authentication Setup

Before interacting with the Web Messaging APIs, you must authenticate. The Genesys Cloud Python SDK handles OAuth token management internally when initialized with your client credentials.

import os
from purecloudplatformclientv2 import (
    Configuration,
    ApiClient,
    WebMessagingApi
)

def get_web_messaging_api_instance():
    """
    Initializes and returns a configured WebMessagingApi instance.
    """
    # Load credentials from environment variables
    client_id = os.environ.get("GENESYS_CLIENT_ID")
    client_secret = os.environ.get("GENESYS_CLIENT_SECRET")
    environment = os.environ.get("GENESYS_ENVIRONMENT", "mypurecloud.com")

    if not client_id or not client_secret:
        raise ValueError("GENESYS_CLIENT_ID and GENESYS_CLIENT_SECRET environment variables are required.")

    config = Configuration()
    config.host = f"https://{environment}"
    config.oauth_client_id = client_id
    config.oauth_client_secret = client_secret
    config.oauth_scopes = ["webmessaging:deployment:write", "webmessaging:deployment:read"]

    api_client = ApiClient(configuration=config)
    return WebMessagingApi(api_client)

This setup ensures that every subsequent API call includes a valid Authorization: Bearer <token> header. The SDK automatically refreshes tokens when they expire, preventing 401 Unauthorized errors during long-running scripts.

Implementation

Step 1: Retrieve Existing Deployments or Prepare for Creation

Web Messaging deployments are identified by a unique ID. If you intend to update an existing deployment, you must first retrieve its ID. If you are creating a new one, you can skip directly to the creation payload.

The following code lists all existing deployments to help you identify the target ID.

def list_deployments(api_instance: WebMessagingApi):
    """
    Retrieves all web messaging deployments.
    """
    try:
        # Expand parameter is optional but helpful to see related entities
        deployments_response = api_instance.post_webmessaging_deployments_query(
            body={
                "expand": ["all"]
            }
        )
        
        if deployments_response.deployments:
            for deployment in deployments_response.deployments:
                print(f"ID: {deployment.id}, Name: {deployment.name}, Type: {deployment.type}")
            return deployments_response.deployments
        else:
            print("No deployments found.")
            return []
            
    except Exception as e:
        print(f"Error retrieving deployments: {e}")
        return []

Expected Response:
The API returns a WebMessagingDeploymentQueryResponse object. The deployments attribute is a list of WebMessagingDeployment objects.

Error Handling:

  • 403 Forbidden: Ensure the OAuth client has the webmessaging:deployment:read scope.
  • 401 Unauthorized: Check your client ID and secret.

Step 2: Construct the Deployment Payload with Custom Styles

The core of this tutorial is constructing the WebMessagingDeployment object. The visual customization is handled within the settings object, specifically under the launcher and chatWindow sections.

Key properties for customization:

  • launcher.position: Accepts top-left, top-right, bottom-left, bottom-right.
  • launcher.style.backgroundColor: Hex color code for the launcher button.
  • launcher.style.iconColor: Hex color code for the icon inside the launcher.
  • chatWindow.style.headerBackgroundColor: Hex color for the chat header.
  • chatWindow.style.userMessageBackgroundColor: Hex color for messages sent by the user.
  • chatWindow.style.agentMessageBackgroundColor: Hex color for messages received from the agent.
from purecloudplatformclientv2 import (
    WebMessagingDeployment,
    WebMessagingDeploymentSettings,
    WebMessagingLauncherSettings,
    WebMessagingChatWindowSettings,
    WebMessagingLauncherStyle,
    WebMessagingChatWindowStyle
)

def build_custom_deployment_payload(name: str, existing_id: str = None):
    """
    Constructs a WebMessagingDeployment object with custom visual settings.
    
    Args:
        name: The name of the deployment.
        existing_id: Optional ID if updating an existing deployment.
    
    Returns:
        WebMessagingDeployment object ready for API submission.
    """
    
    # 1. Configure Launcher Styles
    launcher_style = WebMessagingLauncherStyle(
        background_color="#0056b3",  # Blue background
        icon_color="#ffffff",        # White icon
        border_color="#004494",      # Darker blue border
        border_radius="50%"          # Circular button
    )
    
    launcher_settings = WebMessagingLauncherSettings(
        style=launcher_style,
        position="bottom-right",     # Position: bottom-right
        show_message=True,           # Show "Chat with us" bubble
        message_text="Need Help?",   # Custom tooltip text
        message_background_color="#ff5722" # Orange bubble background
    )
    
    # 2. Configure Chat Window Styles
    chat_window_style = WebMessagingChatWindowStyle(
        header_background_color="#0056b3", # Matches launcher
        header_text_color="#ffffff",
        user_message_background_color="#0056b3",
        user_message_text_color="#ffffff",
        agent_message_background_color="#f1f1f1",
        agent_message_text_color="#333333",
        background_color="#ffffff"
    )
    
    chat_window_settings = WebMessagingChatWindowSettings(
        style=chat_window_style,
        title="Support Chat"
    )
    
    # 3. Assemble the Full Settings Object
    settings = WebMessagingDeploymentSettings(
        launcher=launcher_settings,
        chat_window=chat_window_settings
    )
    
    # 4. Create the Deployment Object
    deployment = WebMessagingDeployment(
        name=name,
        settings=settings,
        type="standard" # Standard web messaging type
    )
    
    # If updating, ensure the ID is set. 
    # Note: The SDK usually handles ID mapping, but explicitly setting it 
    # clarifies intent for PUT operations.
    if existing_id:
        deployment.id = existing_id
        
    return deployment

Step 3: Create or Update the Deployment

Now that the payload is constructed, you must send it to the API. Use POST for creation and PUT for updates.

def deploy_messaging_config(api_instance: WebMessagingApi, deployment: WebMessagingDeployment, is_update: bool = False):
    """
    Creates or updates a web messaging deployment.
    
    Args:
        api_instance: The WebMessagingApi client.
        deployment: The WebMessagingDeployment object.
        is_update: Boolean flag indicating if this is an update (PUT) or create (POST).
    
    Returns:
        The response object from the API.
    """
    try:
        if is_update:
            if not deployment.id:
                raise ValueError("Deployment ID is required for updates.")
            
            # PUT /api/v2/webmessaging/deployments/{deploymentId}
            response = api_instance.put_webmessaging_deployment(
                deployment_id=deployment.id,
                body=deployment
            )
            print(f"Successfully updated deployment: {response.id}")
            
        else:
            # POST /api/v2/webmessaging/deployments
            response = api_instance.post_webmessaging_deployments(
                body=deployment
            )
            print(f"Successfully created deployment: {response.id}")
            
        return response
        
    except Exception as e:
        # Handle specific HTTP errors
        if hasattr(e, 'status') and e.status == 400:
            print(f"Bad Request: Check your payload structure. Details: {e.body}")
        elif hasattr(e, 'status') and e.status == 409:
            print(f"Conflict: A deployment with this name or configuration already exists.")
        else:
            print(f"Error deploying configuration: {e}")
        return None

Complete Working Example

This script combines all steps. It checks for an existing deployment by name. If found, it updates the styles. If not, it creates a new one.

import os
import sys
from purecloudplatformclientv2 import (
    Configuration,
    ApiClient,
    WebMessagingApi,
    WebMessagingDeployment,
    WebMessagingDeploymentSettings,
    WebMessagingLauncherSettings,
    WebMessagingChatWindowSettings,
    WebMessagingLauncherStyle,
    WebMessagingChatWindowStyle
)

def get_web_messaging_api_instance():
    client_id = os.environ.get("GENESYS_CLIENT_ID")
    client_secret = os.environ.get("GENESYS_CLIENT_SECRET")
    environment = os.environ.get("GENESYS_ENVIRONMENT", "mypurecloud.com")

    if not client_id or not client_secret:
        raise ValueError("GENESYS_CLIENT_ID and GENESYS_CLIENT_SECRET environment variables are required.")

    config = Configuration()
    config.host = f"https://{environment}"
    config.oauth_client_id = client_id
    config.oauth_client_secret = client_secret
    config.oauth_scopes = ["webmessaging:deployment:write", "webmessaging:deployment:read"]

    api_client = ApiClient(configuration=config)
    return WebMessagingApi(api_client)

def build_custom_deployment_payload(name: str, existing_id: str = None):
    launcher_style = WebMessagingLauncherStyle(
        background_color="#0056b3",
        icon_color="#ffffff",
        border_color="#004494",
        border_radius="50%"
    )
    
    launcher_settings = WebMessagingLauncherSettings(
        style=launcher_style,
        position="bottom-right",
        show_message=True,
        message_text="Need Help?",
        message_background_color="#ff5722"
    )
    
    chat_window_style = WebMessagingChatWindowStyle(
        header_background_color="#0056b3",
        header_text_color="#ffffff",
        user_message_background_color="#0056b3",
        user_message_text_color="#ffffff",
        agent_message_background_color="#f1f1f1",
        agent_message_text_color="#333333",
        background_color="#ffffff"
    )
    
    chat_window_settings = WebMessagingChatWindowSettings(
        style=chat_window_style,
        title="Support Chat"
    )
    
    settings = WebMessagingDeploymentSettings(
        launcher=launcher_settings,
        chat_window=chat_window_settings
    )
    
    deployment = WebMessagingDeployment(
        name=name,
        settings=settings,
        type="standard"
    )
    
    if existing_id:
        deployment.id = existing_id
        
    return deployment

def main():
    deployment_name = "Custom Styled Widget"
    api_instance = get_web_messaging_api_instance()
    
    # Step 1: Check if deployment exists
    try:
        deployments_response = api_instance.post_webmessaging_deployments_query(
            body={"expand": ["all"]}
        )
        
        target_deployment = None
        for dep in deployments_response.deployments:
            if dep.name == deployment_name:
                target_deployment = dep
                break
        
        # Step 2: Build Payload
        payload = build_custom_deployment_payload(
            name=deployment_name,
            existing_id=target_deployment.id if target_deployment else None
        )
        
        # Step 3: Deploy
        is_update = target_deployment is not None
        deploy_messaging_config(api_instance, payload, is_update)
        
    except Exception as e:
        print(f"Fatal error: {e}")
        sys.exit(1)

def deploy_messaging_config(api_instance, deployment, is_update):
    try:
        if is_update:
            if not deployment.id:
                raise ValueError("Deployment ID is required for updates.")
            response = api_instance.put_webmessaging_deployment(
                deployment_id=deployment.id,
                body=deployment
            )
            print(f"Successfully updated deployment: {response.id}")
        else:
            response = api_instance.post_webmessaging_deployments(
                body=deployment
            )
            print(f"Successfully created deployment: {response.id}")
        return response
    except Exception as e:
        if hasattr(e, 'status') and e.status == 400:
            print(f"Bad Request: {e.body}")
        elif hasattr(e, 'status') and e.status == 409:
            print(f"Conflict: {e.body}")
        else:
            print(f"Error: {e}")
        return None

if __name__ == "__main__":
    main()

Common Errors & Debugging

Error: 400 Bad Request - Invalid Color Format

  • Cause: The API expects hex color codes (e.g., #FF0000). Named colors like "red" or RGB strings like "rgb(255,0,0)" are often rejected by the Web Messaging settings parser.
  • Fix: Ensure all color fields in WebMessagingLauncherStyle and WebMessagingChatWindowStyle use strict hex format.
  • Code Fix:
    # Incorrect
    background_color="blue"
    
    # Correct
    background_color="#0000FF"
    

Error: 403 Forbidden - Scope Mismatch

  • Cause: The OAuth client lacks webmessaging:deployment:write.
  • Fix: Go to the Genesys Cloud Admin Console > Platform > OAuth Clients > Edit your client > Scopes. Add webmessaging:deployment:write.
  • Debugging: Check the config.oauth_scopes list in your initialization code.

Error: 409 Conflict - Duplicate Name

  • Cause: You attempted to create a deployment with a name that already exists in the organization. Deployment names must be unique.
  • Fix: Either update the existing deployment (using the ID retrieved in Step 1) or change the name field in the payload.

Error: 429 Too Many Requests

  • Cause: You are hitting the API rate limit.
  • Fix: Implement exponential backoff. The Genesys Cloud Python SDK does not automatically retry 429s in all versions. You may need to wrap the call in a retry loop.
  • Code Fix:
    import time
    
    def retry_on_429(api_call_func, *args, max_retries=3, **kwargs):
        for attempt in range(max_retries):
            try:
                return api_call_func(*args, **kwargs)
            except Exception as e:
                if hasattr(e, 'status') and e.status == 429:
                    wait_time = 2 ** attempt  # Exponential backoff
                    print(f"Rate limited. Waiting {wait_time} seconds...")
                    time.sleep(wait_time)
                else:
                    raise e
        raise Exception("Max retries exceeded.")
    

Official References