Mastering Date Logic in Genesys Cloud Architect: DateTimeDiff vs GetDayOfWeek
What You Will Build
- This tutorial demonstrates how to programmatically configure Genesys Cloud Architect flows using the
POST /api/v2/architect/flowsendpoint to implement precise date-based routing logic. - You will learn the distinct use cases for the
DateTimeDifffunction (calculating duration between timestamps) andGetDayOfWeek(extracting weekday identifiers) within the Genesys Cloud Expression Language. - The implementation uses Python with the
genesys-cloud-py-clientSDK to generate valid JSON payloads for conditional splits and queues based on temporal data.
Prerequisites
- OAuth Client: A Genesys Cloud OAuth Client with the
architect:flow:writeandarchitect:flow:readscopes. - SDK Version:
genesys-cloud-py-clientversion 134.0.0 or higher. - Language/Runtime: Python 3.9+.
- External Dependencies:
pip install genesys-cloud-py-client. - Conceptual Knowledge: Understanding of Genesys Cloud Architect Flow JSON structure, specifically the
conditionsblock and theexpressionsyntax.
Authentication Setup
Authentication is handled via the SDK’s built-in OAuth2 client credentials flow. The following code initializes the PureCloudPlatformClientV2 and obtains a valid access token. This token is automatically cached and refreshed by the SDK for subsequent API calls.
import os
from purerestclient import PureCloudPlatformClientV2
def get_platform_client():
"""
Initialize and authenticate the Genesys Cloud Platform Client.
"""
# Load credentials from environment variables
client_id = os.getenv("GENESYS_CLIENT_ID")
client_secret = os.getenv("GENESYS_CLIENT_SECRET")
environment = os.getenv("GENESYS_ENVIRONMENT", "mypurecloud.com")
if not client_id or not client_secret:
raise ValueError("GENESYS_CLIENT_ID and GENESYS_CLIENT_SECRET must be set.")
# Initialize the platform client
platform_client = PureCloudPlatformClientV2()
# Configure the OAuth2 client credentials flow
oauth_client = platform_client.oauth_client
oauth_client.client_id = client_id
oauth_client.client_secret = client_secret
# Set the environment (e.g., mypurecloud.com, euw1.pure.cloud)
oauth_client.host = f"https://{environment}"
# Authenticate
try:
oauth_client.authenticate()
return platform_client
except Exception as e:
raise RuntimeError(f"Authentication failed: {e}")
# Initialize the client
api_instance = get_platform_client().architect_api
Implementation
Step 1: Understanding the Expression Context
In Genesys Cloud Architect, logic is defined in JSON. Conditional splits use an expression field that evaluates to a boolean. The expression language supports specific functions for date manipulation.
Key Distinction:
DateTimeDiff: Calculates the difference between two date-time objects. It returns a numeric value representing the difference in a specified unit (seconds, minutes, hours, days). Use this when you need to compare duration or relative time (e.g., “Is the ticket older than 24 hours?”).GetDayOfWeek: Extracts the day of the week from a date-time object. It returns an integer (1 for Sunday, 2 for Monday, etc., depending on the locale/configuration, but typically ISO standard or US standard). Use this when you need to route based on calendar days (e.g., “Is today Saturday?”).
Step 2: Constructing the DateTimeDiff Condition
Scenario: You want to route a conversation to a priority queue if the initial contact timestamp is more than 2 hours ago.
Logic:
- Get the current time:
now() - Get the start time of the conversation:
interaction.startTime - Calculate the difference in hours:
DateTimeDiff(now(), interaction.startTime, "hours") - Compare the result:
> 2
JSON Payload Snippet:
The conditions object in the flow definition requires an expression string.
{
"conditions": {
"expression": "DateTimeDiff(now(), interaction.startTime, \"hours\") > 2"
}
}
Python SDK Construction:
When building the flow via API, you must construct the Condition object correctly.
from purecloudplatformclientv2.models import Flow, Condition, Split
def create_time_based_split():
"""
Creates a split condition that checks if the interaction
started more than 2 hours ago.
"""
# Define the expression string
# Note: In JSON, quotes inside strings must be escaped.
# In Python dicts, we handle this naturally.
expression_str = 'DateTimeDiff(now(), interaction.startTime, "hours") > 2'
# Create the Condition object
condition = Condition(
expression=expression_str,
type="expression"
)
# Create the Split object
split = Split(
name="Is Old Interaction",
conditions=[condition]
)
return split
Step 3: Constructing the GetDayOfWeek Condition
Scenario: You want to route calls to a weekend support queue if the current day is Saturday or Sunday.
Logic:
- Get the current time:
now() - Extract the day of the week:
GetDayOfWeek(now()) - Check if the day is 1 (Sunday) or 7 (Saturday). Note: Genesys Cloud typically uses 1=Sunday, 2=Monday, …, 7=Saturday.
- Combine with logical OR:
||
JSON Payload Snippet:
{
"conditions": {
"expression": "GetDayOfWeek(now()) == 1 || GetDayOfWeek(now()) == 7"
}
}
Python SDK Construction:
from purecloudplatformclientv2.models import Condition
def create_weekend_split():
"""
Creates a split condition that checks if today is Saturday or Sunday.
"""
# Define the expression string
# 1 = Sunday, 7 = Saturday
expression_str = 'GetDayOfWeek(now()) == 1 || GetDayOfWeek(now()) == 7'
condition = Condition(
expression=expression_str,
type="expression"
)
return condition
Step 4: Assembling the Full Flow Definition
To deploy this logic, you must wrap the conditions in a complete Flow JSON structure. This example creates a simple flow that routes inbound calls based on the day of the week.
from purecloudplatformclientv2.models import (
Flow,
FlowContact,
FlowRouting,
FlowRoutingQueue,
Condition,
Split
)
def build_date_logic_flow():
"""
Builds a complete Flow definition that routes based on GetDayOfWeek.
"""
# 1. Define the Weekend Condition
weekend_condition = Condition(
expression='GetDayOfWeek(now()) == 1 || GetDayOfWeek(now()) == 7',
type="expression"
)
# 2. Define the Weekday Condition (Else branch)
weekday_condition = Condition(
expression='GetDayOfWeek(now()) != 1 && GetDayOfWeek(now()) != 7',
type="expression"
)
# 3. Define the Splits
weekend_split = Split(
name="Weekend Support",
conditions=[weekend_condition]
)
weekday_split = Split(
name="Business Hours Support",
conditions=[weekday_condition]
)
# 4. Define the Routing Queues (Placeholder IDs)
# In production, replace these with actual Queue IDs from your org
weekend_queue_id = "your-weekend-queue-id-here"
weekday_queue_id = "your-weekday-queue-id-here"
# 5. Construct the Flow Object
flow = Flow(
name="Date Logic Demo Flow",
description="Routes calls based on Day of Week using GetDayOfWeek",
type="voice",
contact=FlowContact(
initial_contact_type="voice"
),
routing=FlowRouting(
queue=FlowRoutingQueue(
id=weekday_queue_id # Default queue
),
splits=[
{
"split": weekend_split,
"queue": FlowRoutingQueue(id=weekend_queue_id)
},
{
"split": weekday_split,
"queue": FlowRoutingQueue(id=weekday_queue_id)
}
]
)
)
return flow
Step 5: Deploying the Flow via API
Now that the flow object is constructed, you send it to the POST /api/v2/architect/flows endpoint.
import json
from purecloudplatformclientv2.rest import ApiException
def deploy_flow(api_instance, flow):
"""
Deploys the constructed flow to Genesys Cloud.
"""
try:
# Serialize the flow to JSON for debugging/logging if needed
print("Deploying flow...")
# print(json.dumps(flow.to_dict(), indent=2))
# Make the API call
response = api_instance.post_architect_flow(body=flow)
print(f"Flow deployed successfully.")
print(f"Flow ID: {response.id}")
print(f"Flow Name: {response.name}")
print(f"Flow Status: {response.status}")
return response
except ApiException as e:
# Handle API errors
print(f"Exception when calling ArchitectApi->post_architect_flow: {e}")
if e.status == 400:
print("Bad Request: Check the flow JSON structure and expression syntax.")
elif e.status == 401:
print("Unauthorized: Check your OAuth token.")
elif e.status == 403:
print("Forbidden: Check your OAuth scopes.")
elif e.status == 429:
print("Rate Limited: Wait and retry.")
raise e
# Execute
if __name__ == "__main__":
try:
flow = build_date_logic_flow()
deploy_flow(api_instance, flow)
except Exception as e:
print(f"Fatal error: {e}")
Complete Working Example
The following script combines authentication, flow construction, and deployment. It includes error handling and uses DateTimeDiff for a secondary condition example.
import os
import sys
from purerestclient import PureCloudPlatformClientV2
from purecloudplatformclientv2.models import (
Flow,
FlowContact,
FlowRouting,
FlowRoutingQueue,
Condition,
Split
)
from purecloudplatformclientv2.rest import ApiException
def main():
# 1. Authentication
try:
platform_client = PureCloudPlatformClientV2()
oauth_client = platform_client.oauth_client
oauth_client.client_id = os.getenv("GENESYS_CLIENT_ID")
oauth_client.client_secret = os.getenv("GENESYS_CLIENT_SECRET")
oauth_client.host = "https://mypurecloud.com"
oauth_client.authenticate()
architect_api = platform_client.architect_api
except Exception as e:
print(f"Authentication failed: {e}")
sys.exit(1)
# 2. Define Queue IDs
# Replace these with actual IDs from your Genesys Cloud organization
QUEUE_PRIORITY_ID = "YOUR_PRIORITY_QUEUE_ID"
QUEUE_STANDARD_ID = "YOUR_STANDARD_QUEUE_ID"
# 3. Define Conditions
# Condition A: Is it the weekend? (GetDayOfWeek)
# 1 = Sunday, 7 = Saturday
weekend_expr = 'GetDayOfWeek(now()) == 1 || GetDayOfWeek(now()) == 7'
weekend_condition = Condition(expression=weekend_expr, type="expression")
# Condition B: Is the interaction older than 30 minutes? (DateTimeDiff)
# This is a secondary check for priority routing during business hours
old_interaction_expr = 'DateTimeDiff(now(), interaction.startTime, "minutes") > 30'
old_condition = Condition(expression=old_interaction_expr, type="expression")
# 4. Define Splits
weekend_split = Split(name="Weekend", conditions=[weekend_condition])
# For weekday, we might split further based on age
# Note: In a real flow, you would nest splits or use a decision tree.
# Here we simplify to two main branches for demonstration.
weekday_split = Split(name="Weekday", conditions=[
Condition(expression='GetDayOfWeek(now()) != 1 && GetDayOfWeek(now()) != 7', type="expression")
])
# 5. Build Flow
flow = Flow(
name="Date Logic Tutorial Flow",
description="Demonstrates GetDayOfWeek and DateTimeDiff",
type="voice",
contact=FlowContact(initial_contact_type="voice"),
routing=FlowRouting(
queue=FlowRoutingQueue(id=QUEUE_STANDARD_ID),
splits=[
{
"split": weekend_split,
"queue": FlowRoutingQueue(id=QUEUE_PRIORITY_ID) # Route weekends to priority
},
{
"split": weekday_split,
"queue": FlowRoutingQueue(id=QUEUE_STANDARD_ID) # Route weekdays to standard
}
]
)
)
# 6. Deploy
try:
response = architect_api.post_architect_flow(body=flow)
print(f"Success: Flow '{response.name}' created with ID {response.id}")
except ApiException as e:
print(f"API Error {e.status}: {e.reason}")
if e.body:
print(f"Response Body: {e.body}")
if __name__ == "__main__":
main()
Common Errors & Debugging
Error: 400 Bad Request - Invalid Expression
Cause: The expression string contains syntax errors, invalid function names, or incorrect argument types.
Fix:
- Verify function names are case-sensitive. Use
DateTimeDiffnotdatetimeDiff. - Ensure string arguments are quoted correctly. In JSON, use
\"hours\". In Python dicts, use"hours". - Check that
interaction.startTimeexists. If the contact type is not voice or chat, this attribute may not be available. Useinteraction.createdTimeas a fallback.
Debugging Code:
# Test the expression locally by printing the JSON payload
import json
payload = flow.to_dict()
print(json.dumps(payload, indent=2))
# Inspect the "expression" fields manually.
Error: 400 Bad Request - Flow Validation Failed
Cause: The flow structure is incomplete. For example, missing a default queue or having circular references.
Fix:
- Ensure every
Splithas a correspondingqueuein thesplitsarray. - Ensure the
routing.queue(default) is defined. - Validate that Queue IDs exist. If you use a non-existent Queue ID, the API may return a 400 or 404 depending on the SDK version.
Error: Expression Returns Null
Cause: GetDayOfWeek(now()) or DateTimeDiff returns null because the input date is invalid or null.
Fix:
- Ensure
now()is used correctly. It requires no arguments. - Ensure
interaction.startTimeis not null. Add a null check in the expression if necessary:interaction.startTime != null && DateTimeDiff(now(), interaction.startTime, "hours") > 2
Error: 403 Forbidden
Cause: Missing OAuth scopes.
Fix: Ensure the OAuth client has architect:flow:write. If you only have architect:flow:read, you can fetch flows but not create or update them.