Mastering Date Arithmetic in Genesys Cloud Architect: DateTimeDiff vs GetDayOfWeek

Mastering Date Arithmetic in Genesys Cloud Architect: DateTimeDiff vs GetDayOfWeek

What You Will Build

  • One sentence: This tutorial demonstrates how to calculate the difference between two timestamps and extract the day of the week within a Genesys Cloud Architect flow to drive routing logic.
  • One sentence: This uses the Genesys Cloud Platform API v2 to programmatically create and update Architect flows, specifically focusing on the expression syntax for date manipulation.
  • One sentence: The programming language covered is Python, using the official genesyscloud SDK to interact with the Flow API.

Prerequisites

  • OAuth client type: Confidential Client (Client Credentials Grant) is recommended for server-to-server automation scripts.
  • Required Scopes: flow:write, flow:read, user:read.
  • SDK Version: genesyscloud Python SDK version 140+ (ensure it supports the latest flow models).
  • Language/Runtime: Python 3.8+.
  • External Dependencies: genesyscloud, requests (for manual API validation if needed), python-dotenv (for credential management).

Authentication Setup

Before interacting with the Flow API, you must obtain an access token. The Genesys Cloud Python SDK handles token caching and refresh automatically when initialized correctly.

import os
from dotenv import load_dotenv
from purecloudplatformclientv2 import (
    ApiClient,
    Configuration,
    FlowApi,
    PureCloudApplicationCredentialsProvider
)

# Load environment variables from .env file
load_dotenv()

def get_flow_api_client() -> FlowApi:
    """
    Initializes and returns a configured FlowApi client.
    Uses OAuth Client Credentials flow.
    """
    # Initialize the API client with OAuth credentials
    api_client = ApiClient(
        configuration=Configuration(
            host="https://api.mypurecloud.com",  # Replace with your environment region
            access_token_provider=PureCloudApplicationCredentialsProvider(
                os.getenv("GENESYS_CLIENT_ID"),
                os.getenv("GENESYS_CLIENT_SECRET")
            )
        )
    )
    
    return FlowApi(api_client)

This setup ensures that every subsequent call to the FlowApi is authenticated. If the token expires, the PureCloudApplicationCredentialsProvider automatically fetches a new one.

Implementation

Step 1: Understanding the Expression Context

In Genesys Cloud Architect, expressions are not executed by a general-purpose interpreter like Python or JavaScript. They are evaluated by the Architect engine using a specific syntax. When you interact with the Flow API, you are constructing a JSON payload that represents this flow.

Date manipulation in Architect expressions relies on two primary functions:

  1. DateTimeDiff: Calculates the difference between two date/time values.
  2. GetDayOfWeek: Extracts the day of the week from a date/time value.

These functions are used within Condition nodes or SetVariable actions. The API expects these expressions to be passed as strings in the condition or value fields of the respective flow objects.

Step 2: Building the Flow Structure

To demonstrate these functions, we will create a simple flow that:

  1. Captures the current time.
  2. Calculates the number of minutes since the start of the day using DateTimeDiff.
  3. Determines if the current day is a weekend using GetDayOfWeek.

First, we need to define the flow structure. A flow consists of a name, description, and a startNode.

from purecloudplatformclientv2 import (
    Flow,
    FlowStartNode,
    FlowConditionNode,
    FlowSetVariableAction,
    FlowAction,
    FlowCondition
)

def create_base_flow_structure() -> Flow:
    """
    Creates a base Flow object with a start node.
    """
    # Define the start node
    start_node = FlowStartNode(
        id="start",
        name="Start",
        description="Entry point for the flow"
    )
    
    # Initialize the flow
    flow = Flow(
        name="Date Arithmetic Demo",
        description="Demonstrates DateTimeDiff and GetDayOfWeek",
        type="inbound",
        start_node=start_node
    )
    
    return flow

Step 3: Implementing DateTimeDiff

The DateTimeDiff function calculates the difference between two date/time values. The syntax is:
DateTimeDiff(date1, date2, unit)

Where unit can be ms, s, m, h, d, etc. The result is a numeric value.

We will add a SetVariable action to calculate the minutes elapsed since midnight. We compare the current time (Now) with the start of the current day (Now.Date).

def add_datetime_diff_action(flow: Flow) -> Flow:
    """
    Adds a SetVariable action to calculate minutes since midnight.
    """
    # Define the expression
    # DateTimeDiff(Now, Now.Date, 'm') calculates minutes between now and the start of the day
    expression = "DateTimeDiff(Now, Now.Date, 'm')"
    
    # Create the SetVariable action
    set_variable_action = FlowSetVariableAction(
        id="calc_minutes",
        name="Calculate Minutes Since Midnight",
        description="Calculates minutes elapsed since 00:00:00",
        variable="minutes_since_midnight",
        value=FlowAction(value=expression)
    )
    
    # In a real flow, you would chain this after the start node.
    # For API creation, we add it to the flow's actions list conceptually.
    # Note: The Flow API requires a graph structure. Here we simplify for demonstration.
    # In practice, you would link nodes using 'nextNodes' and 'previousNodes'.
    
    print(f"Expression for DateTimeDiff: {expression}")
    return flow

Critical Note on Now.Date: In Architect expressions, Now returns the current timestamp. Now.Date is a property that returns the date portion of the current timestamp (time set to 00:00:00). This is a common pattern to get the start of the day.

Step 4: Implementing GetDayOfWeek

The GetDayOfWeek function extracts the day of the week from a date/time value. The syntax is:
GetDayOfWeek(date)

The return value is an integer where:

  • 1 = Sunday
  • 2 = Monday
  • 7 = Saturday

We will add a condition to check if the current day is a weekend (Saturday or Sunday).

def add_day_of_week_condition(flow: Flow) -> Flow:
    """
    Adds a Condition node to check if the current day is a weekend.
    """
    # Define the expression for Saturday (6) or Sunday (7)
    # GetDayOfWeek(Now) returns 1 for Sunday, 7 for Saturday
    expression = "(GetDayOfWeek(Now) == 1) || (GetDayOfWeek(Now) == 7)"
    
    # Create the condition
    condition = FlowCondition(
        id="is_weekend",
        name="Is Weekend?",
        description="Checks if today is Saturday or Sunday",
        expression=expression
    )
    
    # Create the condition node
    condition_node = FlowConditionNode(
        id="check_weekend",
        name="Check Weekend",
        description="Determines routing based on day of week",
        condition=condition
    )
    
    print(f"Expression for GetDayOfWeek: {expression}")
    return flow

Step 5: Assembling and Creating the Flow

Now we combine these components into a complete flow structure and send it to the Genesys Cloud API. Note that the Flow API requires a specific graph structure with nextNodes and previousNodes to define the flow path. For brevity, we will focus on the payload construction for the POST /api/v2/flows endpoint.

def create_complete_flow(flow_api: FlowApi) -> dict:
    """
    Constructs and creates a complete flow with date arithmetic.
    """
    # Base flow
    flow = create_base_flow_structure()
    
    # Add DateTimeDiff action (conceptually linked)
    flow = add_datetime_diff_action(flow)
    
    # Add GetDayOfWeek condition (conceptually linked)
    flow = add_day_of_week_condition(flow)
    
    # Construct the full payload for API creation
    # This is a simplified representation. A real flow requires explicit node linking.
    payload = {
        "name": flow.name,
        "description": flow.description,
        "type": flow.type,
        "startNode": {
            "id": "start",
            "name": "Start",
            "nextNodes": ["set_minutes", "check_weekend"]
        },
        "nodes": [
            {
                "id": "set_minutes",
                "name": "Calculate Minutes Since Midnight",
                "type": "setVariable",
                "variable": "minutes_since_midnight",
                "value": "DateTimeDiff(Now, Now.Date, 'm')"
            },
            {
                "id": "check_weekend",
                "name": "Check Weekend",
                "type": "condition",
                "condition": {
                    "expression": "(GetDayOfWeek(Now) == 1) || (GetDayOfWeek(Now) == 7)"
                },
                "nextNodes": ["weekend_route", "weekday_route"]
            },
            {
                "id": "weekend_route",
                "name": "Weekend Route",
                "type": "answer",
                "answer": "It is the weekend."
            },
            {
                "id": "weekday_route",
                "name": "Weekday Route",
                "type": "answer",
                "answer": "It is a weekday."
            }
        ]
    }
    
    try:
        # Create the flow
        created_flow = flow_api.post_flow(body=payload)
        print(f"Flow created successfully with ID: {created_flow.id}")
        return created_flow
    except Exception as e:
        print(f"Error creating flow: {e}")
        return None

Complete Working Example

This script initializes the API client, constructs the flow payload with the date arithmetic expressions, and creates the flow in Genesys Cloud.

import os
from dotenv import load_dotenv
from purecloudplatformclientv2 import (
    ApiClient,
    Configuration,
    FlowApi,
    PureCloudApplicationCredentialsProvider
)

def main():
    # Load environment variables
    load_dotenv()
    
    # Initialize API client
    api_client = ApiClient(
        configuration=Configuration(
            host="https://api.mypurecloud.com",
            access_token_provider=PureCloudApplicationCredentialsProvider(
                os.getenv("GENESYS_CLIENT_ID"),
                os.getenv("GENESYS_CLIENT_SECRET")
            )
        )
    )
    
    flow_api = FlowApi(api_client)
    
    # Define the flow payload
    flow_payload = {
        "name": "Date Arithmetic Demo",
        "description": "Demonstrates DateTimeDiff and GetDayOfWeek",
        "type": "inbound",
        "startNode": {
            "id": "start",
            "name": "Start",
            "nextNodes": ["set_minutes", "check_weekend"]
        },
        "nodes": [
            {
                "id": "set_minutes",
                "name": "Calculate Minutes Since Midnight",
                "type": "setVariable",
                "variable": "minutes_since_midnight",
                "value": "DateTimeDiff(Now, Now.Date, 'm')"
            },
            {
                "id": "check_weekend",
                "name": "Check Weekend",
                "type": "condition",
                "condition": {
                    "expression": "(GetDayOfWeek(Now) == 1) || (GetDayOfWeek(Now) == 7)"
                },
                "nextNodes": ["weekend_route", "weekday_route"]
            },
            {
                "id": "weekend_route",
                "name": "Weekend Route",
                "type": "answer",
                "answer": "It is the weekend."
            },
            {
                "id": "weekday_route",
                "name": "Weekday Route",
                "type": "answer",
                "answer": "It is a weekday."
            }
        ]
    }
    
    try:
        # Create the flow
        created_flow = flow_api.post_flow(body=flow_payload)
        print(f"Flow created successfully with ID: {created_flow.id}")
        
        # Optional: Verify the flow by fetching it
        fetched_flow = flow_api.get_flow(flow_id=created_flow.id)
        print(f"Flow name: {fetched_flow.name}")
        
    except Exception as e:
        print(f"Error: {e}")

if __name__ == "__main__":
    main()

Common Errors & Debugging

Error: 400 Bad Request - Invalid Expression

What causes it: The expression syntax is incorrect. Architect expressions are strict. Common mistakes include:

  • Using Python-style operators (e.g., and instead of &&, or instead of ||).
  • Incorrect function names (e.g., GetDay instead of GetDayOfWeek).
  • Missing quotes around string literals or units in DateTimeDiff.

How to fix it:

  1. Verify the function name and parameters in the Architect Expression Reference.
  2. Ensure DateTimeDiff uses the correct unit string ('m' for minutes, 'h' for hours).
  3. Ensure GetDayOfWeek returns integers 1-7, and your comparison logic matches this.

Code Example Fix:
Incorrect: DateTimeDiff(Now, Now.Date, m)
Correct: DateTimeDiff(Now, Now.Date, 'm')

Error: 401 Unauthorized

What causes it: The OAuth token is invalid or expired.

How to fix it:

  1. Check that GENESYS_CLIENT_ID and GENESYS_CLIENT_SECRET are correctly set in your environment.
  2. Ensure the OAuth client has the flow:write scope.
  3. Verify that the API client is initialized with the correct region URL (https://api.mypurecloud.com for US, https://api.uk.purecloud.com for UK, etc.).

Error: 403 Forbidden

What causes it: The OAuth client does not have the required permissions.

How to fix it:

  1. Go to the Genesys Cloud Admin UI.
  2. Navigate to Users > OAuth Clients.
  3. Select your client and ensure the Flow permission is set to Write.

Official References