From Bright Pattern Documentation
Jump to: navigation, search
• 5.19

How to Create Bright Pattern Tasks from a Salesforce Flow

You can trigger the creation of Bright Pattern tasks using Salesforce Flow and a custom Apex action. This guide provides an example for configuring an Apex action and invoking it from a Salesforce Flow

Prerequisites

  • Administrator access to your Salesforce organization.
  • Administrator access to your Bright Pattern Contact Center.
  • Configured a Bright Pattern user for API usage, with an API Secret and the Use Task Routing API user privilege enabled.
  • A configured Task Scenario Entry in Bright Pattern, and its Unique Identifier to use as the taskLaunchPointId.


Step 1: Securely Store API Configurations

A single Protected Custom Setting will hold all the necessary configuration. This keeps secrets secure and makes the integration easy to manage from one location.

  1. In Salesforce Setup, search for and select Custom Settings.

  2. Click New.

  3. Enter the following details:
    • Label: Bright Pattern Config
    • Object Name: Bright_Pattern_Config
    • Setting Type: Hierarchy
    • Visibility: Protected

  4. Click Save.

  5. On the Custom Setting page, in the Custom Fields section, click New and add the following fields:
    • Data Type: Text, Field Label: Client ID (Username), Length: 255
    • Data Type: Text, Field Label: Client Secret (API Secret), Length: 255
    • Data Type: Text, Field Label: Task Launch Point ID, Length: 255
    • Data Type: URL, Field Label: Token Endpoint, Length: 255
    • Data Type: URL, Field Label: Task API Endpoint, Length: 255

  6. After creating the fields, click the Manage button at the top of the Bright Pattern Config page.

  7. Click New (at the top, next to "Default Organization Level Value").

  8. Populate the fields with your Bright Pattern contact center details:
    • Client ID (Username): The username of the Bright Pattern user.
    • Client Secret (API Secret): API Secret of the Bright Pattern user.
    • Task Launch Point ID: The Unique Identifier from your Task Scenario Entry in Bright Pattern.
    • Token Endpoint: The URL for the get access token endpoint of your contact center, of the format https://<your-contact-center>.brightpattern.com/configapi/v2/oauth/token.
    • Task API Endpoint: The URL for the queue task endpoint of your contact center, of the format https://<your-contact-center>.brightpattern.com/taskroutingapi/v1/task.

  9. Click Save.


Step 2: Create the Invocable Apex Class

This Apex class contains the logic to create a task in Bright Pattern. It retrieves all configuration from the Protected Custom Setting created in the previous step, including the taskLaunchPointId, to handle authentication and routing securely.

  1. In Salesforce Setup, search for and select Apex Classes.

  2. Click New and use the following code as an example for creating a class:

    /*
    This class contains an Invocable Apex Action for a Salesforce Flow. Its purpose is
    to queue a task in the Bright Pattern system by making a callout to their API.
    
    An important security note: The user running the Flow that calls this Apex action 
    must have the appropriate permissions to the Bright_Pattern_Config__c custom setting.
    */
    public with sharing class BrightPatternTaskController {
    
        // This is a custom exception class to provide more specific error details from this controller.
        public class BrightPatternException extends Exception {}
    
        // This inner class defines the input variables that will be exposed in the Flow Builder.
        // The Flow will pass data into an instance of this class.
        public class FlowRequest {
    
          @InvocableVariable(label="Case ID for Screenpop" required=true)
          public String caseId;
    
          @InvocableVariable(label="Case Number" required=true)
          public String caseNumber;
    
          @InvocableVariable(label="Contact ID" required=true)
          public String contactId;
    
          @InvocableVariable(label="Task Subject" required=true)
          public String subject;
    
          @InvocableVariable(label="Task Priority")
          public String priority;
        }
    
        /*
        This method is exposed to the Flow Builder as an Apex Action.
        It takes a list of requests from the Flow and queues a corresponding task in Bright Pattern.
        */
        @InvocableMethod(label="Queue Bright Pattern Task", description="Queues a task in Bright Pattern via the API." category="Bright Pattern")
        public static void queueTaskInBrightPattern(List<FlowRequest> requests) {
    
          // Retrieve all configuration from the Protected Custom Setting.
          Bright_Pattern_Config__c bpConfig = Bright_Pattern_Config__c.getOrgDefaults();
    
          // Check for valid configuration and throw a clear error if anything is missing.
          // This provides immediate feedback to the Flow administrator if the setup is incomplete.
          if (bpConfig == null || String.isBlank(bpConfig.Task_Launch_Point_ID__c) || String.isBlank(bpConfig.Task_API_Endpoint__c) || String.isBlank(bpConfig.Token_Endpoint__c) || String.isBlank(bpConfig.Client_ID__c) || String.isBlank(bpConfig.Client_Secret__c)) {
            throw new AuraHandledException("Bright Pattern configuration is missing or incomplete in Custom Settings. Please check the configuration.");
          }
    
          try {
              // Get the access token once for this entire transaction.
              String accessToken = getAccessToken(bpConfig);
              if (String.isBlank(accessToken)) {
                // Throw an exception that the Flow can handle if the token request fails.
                throw new BrightPatternException("Failed to obtain a Bright Pattern Access Token.");
              }
    
              // Even though we often expect one request per invocation from a Flow,
              // we loop through the list, as this is the best practice for Invocable Methods.
              for (FlowRequest req : requests) {
                
                Http http = new Http();
                HttpRequest apiRequest = new HttpRequest();
                
                apiRequest.setEndpoint(bpConfig.Task_API_Endpoint__c);
                apiRequest.setMethod("POST");
                apiRequest.setHeader("Authorization", "Bearer " + accessToken);
                apiRequest.setHeader("Content-Type", "application/json;charset=UTF-8");
    
                // Construct the request body from the Flow inputs.
                Map<String, Object> bodyMap = new Map<String, Object>{
                  "taskLaunchPointId" => bpConfig.Task_Launch_Point_ID__c,
                  "extTaskId" => req.caseNumber,
                  "extContactId" => req.contactId,
                  "priority" => req.priority,
                  "taskInfo" => new Map<String, String>{ "subject" => req.subject },
                  "screenpop" => "SHOW_OBJECT:" + req.caseId + ":Case"
                };
                
                apiRequest.setBody(JSON.serialize(bodyMap));       
    
                HttpResponse response = http.send(apiRequest);
    
                // Check the response and throw an exception on failure.
                // This will halt the Flow and display an error, preventing silent failures.
                if (response.getStatusCode() != 200) {
                    String errorMessage = "Failed to queue task in Bright Pattern. Status: " + response.getStatus() + ". Body: " + response.getBody();
                    System.debug(errorMessage);
                    throw new BrightPatternException(errorMessage);
                } else {
                    System.debug("Successfully queued task: " + response.getBody());
                }
              }
          } catch (Exception e) {
              // This is a centralized exception handler.
              // It catches any exceptions thrown from the logic above (like CalloutException or our custom BrightPatternException).
              // It then re-throws them as an AuraHandledException to make them visible in the Flow's fault path.
              System.debug("An error occurred in BrightPatternTaskController: " + e.getMessage() + " Stacktrace: " + e.getStackTraceString());
              throw new AuraHandledException(e.getMessage());
          }
        }
    
        // This is a helper method to get the access token using securely stored credentials.
        // It takes the Bright Pattern configuration custom setting as its input.
        // It returns the access token string.
        private static String getAccessToken(Bright_Pattern_Config__c config) {
    
          HttpRequest tokenRequest = new HttpRequest();
          tokenRequest.setEndpoint(config.Token_Endpoint__c);
          tokenRequest.setMethod("POST");
          tokenRequest.setHeader("Content-Type", "application/x-www-form-urlencoded");
    
          // The scope is derived from the Token Endpoint URL. For Bright Pattern, this is the tenant URL.
          String tenantUrl = new URL(config.Token_Endpoint__c).getHost();
    
          String requestBody = "grant_type=client_credentials"
                   + "&client_id=" + EncodingUtil.urlEncode(config.Client_ID__c, "UTF-8")
                   + "&client_secret=" + EncodingUtil.urlEncode(config.Client_Secret__c, "UTF-8")
                   + "&scope=" + EncodingUtil.urlEncode(tenantUrl, "UTF-8");
    
          tokenRequest.setBody(requestBody);
          
          Http http = new Http();
          HttpResponse tokenResponse = http.send(tokenRequest);
    
          if (tokenResponse.getStatusCode() == 200) {
            Map<String, Object> result = (Map<String, Object>) JSON.deserializeUntyped(tokenResponse.getBody());
            return (String) result.get("access_token");
          } else {
            // Log the detailed error but return null so it can be handled by the calling method.
            System.debug("Token request failed. Status: " + tokenResponse.getStatus() + ". Body: " + tokenResponse.getBody());
            return null;
          }
        }
    }
    
  3. Save the class.

Step 3: Create the Salesforce Flow

The Flow defines the business process that will trigger the Apex action. This example shows how to use a record-triggered flow to create a task whenever a new Case is created or updated.

  1. In Setup, search for and select Flows.

  2. Click New Flow and select Record-Triggered Flow.

  3. Configure the trigger:
    • Object: Case
    • Trigger the Flow When: A record is created
    • Optimize the Flow for: Actions and Related Records

  4. Click Done.

  5. On the Flow canvas, click the + icon and select the Action element.

  6. In the Action search box, select the Apex category and choose Queue Bright Pattern Task.

  7. Fill in the action details.
    • Label: Give the action a descriptive name, like Create BP Task for New Case.
    • Map Input Values: Map the fields from the triggering Case record ($Record) to the inputs of your Apex Action.
      • Case ID for Screenpop: $Record.Id
      • Contact ID: $Record.ContactId
      • Case Number: $Record.CaseNumber
      • Task Subject: $Record.Subject
      • Task Priority: Optionally, set a Queueing priority to override the priority set in the Task Scenario Entry.

  8. Click Done.

  9. Click Save, give your Flow a name (e.g., New Case to Bright Pattern Task), and click Activate.

  10. When a new record is created, a task should be queued automatically in Agent Desktop.
    < Previous