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
publicorconfidentialgrant type. - Required Scopes:
webmessaging:deployment:write(to create/update deployments) andwebmessaging:deployment:read(to list existing deployments). - SDK Version: Genesys Cloud Python SDK
version >= 180.0.0. - Dependencies:
genesys-cloud-sdk-pythonrequests(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:readscope. - 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: Acceptstop-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
WebMessagingLauncherStyleandWebMessagingChatWindowStyleuse 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_scopeslist 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
namefield 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.")