Writing a CXone Studio Script That Performs a Database Lookup via DBConnector

Writing a CXone Studio Script That Performs a Database Lookup via DBConnector

What You Will Build

  • You will build a NICE CXone Studio Snippet script that connects to an external SQL database, executes a parameterized query, and retrieves a single record based on a caller identifier.
  • This implementation uses the DBConnector action within the CXone Studio scripting environment, which relies on a pre-configured database connection profile in the CXone Admin console.
  • The tutorial covers JavaScript/TypeScript logic within the CXone Studio Snippet editor, focusing on error handling, timeout configuration, and data extraction from the result set.

Prerequisites

OAuth and Permissions

  • User Role: You must have the Administrator or Developer role in NICE CXone to create and manage Database Connections in the Admin console.
  • Scope: The script runs in the context of the interaction. Ensure the associated Application or User has permissions to access the specific Database Connection profile you are referencing.

Environment Setup

  • CXone Admin Console Access: You must already have a valid database connection configured.
    • Navigate to Admin > Integrations > Database Connections.
    • Create a new connection (e.g., named CustomerDB) pointing to your SQL Server, PostgreSQL, or MySQL instance.
    • Verify connectivity using the “Test Connection” button in the Admin console.
  • CXone Studio Access: You need access to the Studio application to create a Snippet.

External Dependencies

  • No external npm packages are required. The DBConnector action is a native runtime action provided by the CXone Studio engine.
  • Ensure your target database allows connections from the NICE CXone IP ranges (listed in the NICE CXone Network Security documentation).

Authentication Setup

CXone Studio snippets do not require manual OAuth token generation in the code. The script executes within the secure CXone runtime environment. Authentication is handled implicitly by the platform using the credentials defined in the Database Connection profile you configured in the Admin console.

The critical “authentication” step is ensuring the DBConnector action references the correct Connection Profile Name (or ID). If the name is incorrect, the runtime will throw a ConnectionNotFound error.

Implementation

Step 1: Define the Script Structure and Variables

In CXone Studio, a Snippet script is a JavaScript function. You must define the input parameters that allow the caller to pass data into the script, and the output parameters that return data from the database.

Input Parameters:

  • lookupKey: A string representing the identifier to search for (e.g., Phone Number, Account ID).

Output Parameters:

  • dbResult: An object containing the database record or an error message.

Create a new Snippet in Studio and define the signature as follows:

/**
 * @param {string} lookupKey - The identifier to search in the database.
 * @returns {object} result - An object containing { success: boolean, data: object|null, error: string|null }
 */
function performDatabaseLookup(lookupKey) {
    // Initialize the return object
    var result = {
        success: false,
        data: null,
        error: null
    };

    // Validate input
    if (!lookupKey || lookupKey.trim() === "") {
        result.error = "Invalid lookup key provided. Value cannot be empty.";
        return result;
    }

    // Declare variables for the DBConnector action
    var connectionName = "CustomerDB"; // Must match the Name in Admin > Database Connections
    var sqlQuery = "SELECT customer_id, first_name, last_name, loyalty_tier FROM customers WHERE phone_number = ? LIMIT 1";
    var parameters = [lookupKey];
    
    // Execute the lookup
    return executeLookup(connectionName, sqlQuery, parameters);
}

Step 2: Configure and Execute the DBConnector Action

The DBConnector action is asynchronous in nature but blocks the script execution until the database responds or times out. You must configure the timeout explicitly to prevent hanging interactions.

Critical Parameters:

  • connectionName: The exact name of the database connection profile defined in the Admin console.
  • sql: The SQL query string. Use ? for placeholders to prevent SQL injection.
  • params: An array of values corresponding to the ? placeholders.
  • timeout: The maximum time in milliseconds to wait for the database response. Default is often 30,000ms, but explicit definition is best practice.
/**
 * Helper function to execute the DBConnector action
 */
function executeLookup(connectionName, sqlQuery, params) {
    var result = {
        success: false,
        data: null,
        error: null
    };

    try {
        // Configure the DBConnector action
        var dbAction = new DBConnector();
        
        // Set the connection profile
        dbAction.setConnectionName(connectionName);
        
        // Set the SQL query
        dbAction.setSql(sqlQuery);
        
        // Set the parameters (array of values)
        dbAction.setParams(params);
        
        // Set timeout (e.g., 10 seconds)
        dbAction.setTimeout(10000);

        // Execute the query
        // The execute() method returns a Result object
        var dbResponse = dbAction.execute();

        // Check if the execution was successful at the connection level
        if (dbResponse.isError()) {
            result.error = "Database execution error: " + dbResponse.getErrorMessage();
            return result;
        }

        // Check if rows were returned
        var rowCount = dbResponse.getRowCount();
        
        if (rowCount === 0) {
            result.success = true; // Query ran, but no data found
            result.data = null;
            result.error = "No records found for the given key.";
            return result;
        }

        // Extract the first row
        // getRow(0) returns the first row as an object with column names as keys
        var firstRow = dbResponse.getRow(0);
        
        result.success = true;
        result.data = firstRow;
        result.error = null;

    } catch (e) {
        // Catch runtime errors (e.g., malformed script, unexpected exceptions)
        result.error = "Runtime exception: " + e.toString();
        return result;
    }

    return result;
}

Expected Response Structure:
If the query returns a record, dbResponse.getRow(0) will yield an object like:

{
  "customer_id": "12345",
  "first_name": "John",
  "last_name": "Doe",
  "loyalty_tier": "Gold"
}

Step 3: Process Results and Handle Edge Cases

Database lookups can fail for many reasons: network latency, authentication failure on the DB side, syntax errors, or no data found. You must distinguish between a “successful query with no results” and a “failed query.”

Edge Case: Multiple Rows
The LIMIT 1 in the SQL query ensures only one row is returned. If you remove LIMIT 1, dbResponse.getRowCount() may return > 1. You must decide how to handle this. The code above assumes a single primary key lookup.

Edge Case: Timeout
If the database does not respond within timeout milliseconds, dbAction.execute() will throw an exception or return an error status. The try-catch block handles unexpected crashes, while dbResponse.isError() handles logical errors returned by the DBConnector engine.

Refined Error Handling Logic:

// Inside executeLookup, after dbAction.execute():

if (dbResponse.isError()) {
    var errorCode = dbResponse.getErrorCode();
    var errorMessage = dbResponse.getErrorMessage();
    
    if (errorCode === "TIMEOUT") {
        result.error = "Database query timed out after " + dbAction.getTimeout() + "ms.";
    } else if (errorCode === "CONNECTION_FAILED") {
        result.error = "Failed to connect to database profile: " + connectionName;
    } else {
        result.error = "Database error (" + errorCode + "): " + errorMessage;
    }
    return result;
}

Complete Working Example

This is the full, copy-pasteable script for a CXone Studio Snippet. Save this as a new Snippet named LookupCustomerByPhone.

/**
 * Snippet: LookupCustomerByPhone
 * Description: Performs a secure database lookup for a customer by phone number using the DBConnector action.
 * 
 * Input Parameters:
 *   - lookupKey (string): The phone number to search for.
 * 
 * Output Parameters:
 *   - result (object): Contains success status, data object, and error message.
 */
function performDatabaseLookup(lookupKey) {
    
    // 1. Input Validation
    if (!lookupKey || typeof lookupKey !== 'string' || lookupKey.trim() === "") {
        return {
            success: false,
            data: null,
            error: "Invalid input: lookupKey must be a non-empty string."
        };
    }

    // 2. Configuration
    // IMPORTANT: This name must exactly match the 'Name' field in Admin > Integrations > Database Connections
    var connectionProfileName = "CustomerDB"; 
    
    // Use parameterized query to prevent SQL injection. 
    // Note: Syntax for parameters varies slightly by DB type (SQL Server uses @p1, Oracle uses :1, MySQL/Postgres use ?).
    // DBConnector abstracts this, but usually expects ? for generic SQL or follows the specific DB driver rules.
    // For this example, we assume standard JDBC-style ? placeholders which DBConnector typically handles.
    var sqlStatement = "SELECT customer_id, first_name, last_name, loyalty_tier FROM customers WHERE phone_number = ? LIMIT 1";
    
    var queryParams = [lookupKey.trim()];
    var requestTimeoutMs = 10000; // 10 seconds

    // 3. Execution
    var dbConnector = new DBConnector();
    
    try {
        dbConnector.setConnectionName(connectionProfileName);
        dbConnector.setSql(sqlStatement);
        dbConnector.setParams(queryParams);
        dbConnector.setTimeout(requestTimeoutMs);

        // Execute the query
        var response = dbConnector.execute();

        // 4. Response Processing
        if (response.isError()) {
            return {
                success: false,
                data: null,
                error: "DB Error [" + response.getErrorCode() + "]: " + response.getErrorMessage()
            };
        }

        var rowCount = response.getRowCount();

        if (rowCount === 0) {
            // Query succeeded, but no matching record found
            return {
                success: true,
                data: null,
                error: "No customer found with this phone number."
            };
        }

        // Retrieve the first row
        // getRow(0) returns a JavaScript object where keys are column names
        var customerData = response.getRow(0);

        return {
            success: true,
            data: customerData,
            error: null
        };

    } catch (exception) {
        // Catch any unexpected runtime errors
        return {
            success: false,
            data: null,
            error: "Script Runtime Error: " + exception.toString()
        };
    }
}

Common Errors & Debugging

Error: ConnectionNotFound or InvalidConnectionName

  • Cause: The connectionProfileName variable in the script does not exactly match the Name field of the Database Connection in the Admin console. Note that this is case-sensitive.
  • Fix: Go to Admin > Integrations > Database Connections, select your connection, and copy the “Name” field exactly. Paste it into the setConnectionName() call.

Error: TIMEOUT

  • Cause: The database query took longer than the specified setTimeout() value. This is common with large tables, missing indexes, or network latency.
  • Fix:
    1. Increase the timeout in the script: dbConnector.setTimeout(30000);.
    2. Optimize the SQL query. Ensure the column used in the WHERE clause (e.g., phone_number) has an index.
    3. Check the database server load.

Error: SQLSyntaxErrorException or InvalidParameter

  • Cause: The SQL query contains syntax errors, or the number of ? placeholders does not match the length of the params array.
  • Fix:
    1. Test the SQL query directly in your database client (e.g., SSMS, pgAdmin) to verify syntax.
    2. Ensure queryParams array length equals the number of ? in the SQL string.

Error: AccessDenied or AuthenticationFailed

  • Cause: The credentials stored in the Database Connection profile are incorrect, expired, or the user lacks permissions to execute SELECT on the target table.
  • Fix: Update the username/password in the Database Connection profile in the Admin console. Verify the DB user has SELECT privileges on the customers table.

Error: NoRowsReturned vs NullData

  • Cause: Confusion between a failed query and a successful query with no results.
  • Fix: Always check response.getRowCount() === 0 separately from response.isError(). A rowCount of 0 is a valid success state for lookup queries.

Official References