AWS Contact Center

Route inbound Salesforce email using Apex triggers and Amazon Connect Tasks

Several organizations today integrate Amazon Connect with Salesforce within their contact centers for voice and chat interactions. They also use Salesforce to handle inbound email communications. While Amazon Connect Salesforce CTI adapter provides a seamless integration between the two, some companies prefer a single routing mechanism for all channels and a unified reporting view for voice, chat and third-party tasks.

Amazon Connect Tasks solve for the above challenge as it allows you to manage, prioritize and report across other agent tasks from a single unified user interface.

In this blog post, we will walk you on how to route inbound Salesforce emails using Amazon Connect Tasks, allowing your organization to manage workloads more efficiently across channels. We will use Amazon Connect Tasks and an Apex trigger to seamlessly integrate Salesforce Email-to-Case with Amazon Connect .

Overview of solution

The following architecture diagram offers a high-level view of the solution, its key components and the general end-to-end flow.

Summary

  1. An end customer sends an email to a published support email address.
  2. The organization’s mail server forwards the email to an email service address managed by Salesforce.
  3. A new case is automatically created by the Email-to-Case service.
  4. The case record is inserted into the underlying Salesforce database.
  5. A custom Apex trigger is executed after the record is inserted.
  6. The custom Apex trigger:
    1. Retrieves the AWS endpoint, access key ID and secret access key from a Named Credential.
    2. Sends a StartTaskContact request to Amazon Connect via HTTPS.
  7. Amazon Connect:
    1. Validates the request authorization credentials
    2. Creates a new task contact
  8. An Amazon Connect Contact Flow is executed to handle the new task.
  9. The task is routed to an agent with a screen-pop based on routing rules.
  10. The agent uses Salesforce to respond to the customer and close out the case based on the organization’s workflow.

Walkthrough

The high-level steps for this solution are as follows:

  1. Create Amazon Connect resources
  2. Create AWS Identity and Access Management (IAM) policy and user
  3. Create a named credentials in Salesforce
  4. Create custom settings in Salesforce
  5. Create queues in Salesforce
  6. Update email routing addresses in Salesforce
  7. Create an Amazon Connect Apex client class
  8. Create a Custom Apex trigger
  9. Create a Computer Telephony Integration (CTI) Flow to automate the agent screen-pop
  10. Try it out

Prerequisites

For this walkthrough, you should have the following prerequisites:

Step 1: Create Amazon Connect resources

    1. Create the Outbound, Sales and Support queues in Amazon Connect as shown below:
    2. Create a routing profile in Amazon Connect as shown below:
      1. Select the Task channel
      2. Add the Sales Queue with a Priority of 1 and select Task channel.
      3. Add the Support Queue with a Priority of 2 and select the Task Channel.
      4. Select the Outbound Queue as the Default outbound queue.
  1. Create an agent user and assign her to the newly created routing profile. Also, for testing purposes, you will need to attach the Agent and QualityAnalyst security profiles. For example:
  2. Create a contact flow such as the one below for handling task contacts:Note that the above flow expects to receive a contact attribute called queue to be present in the incoming Task contact. Supplying the value for this attribute will be covered in a later step. For now, just be sure to configure the Check contact attribute block as follows:

Step 2: Create an IAM policy and user

  1. Create an IAM policy called SF-Email2Case-Policy to allow access to the StartTaskContact API as shown below. For example:Here you will need to provide your contact flow’s ARN as the resource, which is accessible from the contact flow designer view. From the ARN you can obtain your Amazon Connect instance and Contact Flow IDs, which you’ll need in a later step. See Find the Flow ID for more information.
  2. Create an IAM user called sfuser with programmatic access and attach the newly created policy as shown below. Be sure to save the access key ID and secret access key, which is required in the next step.

Step 3: Create named credentials in Salesforce

In this step, we create named credentials in your Salesforce domain to securely store the AWS access key ID and secret key needed to authenticate against the Amazon Connect service.

  1. From Setup, enter Named Credentials in the Quick Find Box and press enter.
  2. Select Named Credentials from the results and click New Named Credential.
  3. Enter AWS Connect Credentials for the Label.
  4. Enter AWS_Connect_Credentials for the Name.
  5. Enter the appropriate Amazon Connect service endpoint URL based on your target AWS region.
  6. Select Named Principal as the Identity Type.
  7. Select AWS Signature Version 4 as the Authentication Protocol.
  8. Enter the AWS Access Key ID and Secret Access Key for the IAM user created earlier (sfuser).
  9. Enter your target region as the AWS Region (e.g. us-east-1).
  10. Enter connect as the AWS Service.
  11. Ensure Generate Authorization Header is checked and click Save.

Step 4: Create custom settings in Salesforce

In this step, we create custom settings in Salesforce to store the target Amazon Connect instance ID and contact flow ID to avoid hardcoding them within the Apex trigger.

  1. From Setup, enter Schema Settings in the Quick Find Box and press enter.
  2. Select Schema Settings from the results.
  3. Ensure the Manage list custom settings type option is enabled:
  4. From Setup, enter Custom Settings in the Quick Find Box and press enter.
  5. Select Custom Settings from the results and click New.
  6. Enter Amazon Connect as the Label.
  7. Enter Amazon_Connect as the Object Name.
  8. Select List as the Setting Type and click Save.
  9. From the Custom Setting Definition view, click New in the Custom Fields section.
  10. Select Text as the Data Type and click Next.
  11. Enter Instance ID as the Field Label and press the tab key, which automatically populates the Field Name as Instance_ID.
  12. Enter 64 as the Length and click Next.
  13. Confirm the information and click Save.
  14. Repeat steps 9 – 13 for a second custom field labeled Contact Flow ID.
  15. From the Amazon Connect Custom Setting Definition view, click Manage.
  16. Next, click New to configure the Amazon Connect instance and contact flow ID.
  17. On the Amazon Connect Edit form, enter Email as the Name.
  18. Enter your Amazon Connect Instance ID.
  19. Enter your Contact Flow ID.
  20. Click Save as shown here:As noted in Step 2, The connect instance and contact flow ID may be obtained from the Contact Flow ARN.

Step 5: Create queues in Salesforce

In this step, we create 2 queues in Salesforce that will be used as the initial case owners when new emails arrive.

  1. From Setup, enter Queues in the Quick Find Box and select Queues from the results.
  2. Click New.
  3. Enter Sales Queue as the Label.
  4. Enter Sales_Queue as the Queue Name.
  5. Add Case to the list of Supported Objects.
  6. Save the queue.
  7. Repeat steps 2 – 6 entering Support Queue as the Label and Support_Queue as the Queue Name.

Step 6: Update email routing addresses in Salesforce

This step assumes Email-to-Case has been enabled with 2 verified routing addresses that customers can email for sales or support related inquiries. We will now update the routing addresses to ensure new cases are assigned to the appropriate holding queues.

  1. From Setup, enter Email-to-Case in the Quick Find Box and press enter.
  2. Select Email-to-Case.
  3. Under Routing Addresses, identify the address you have designated as the sales address and click on the Edit link. For example:
  4. Under Case Settings, select Queue and Sales Queue as the Case Owner.
  5. Confirm Email is selected as the Case Origin.
  6. Click Save.
  7. Repeat steps 3 – 6 for the designated support address selecting the Support Queue as the Case Owner.

Step 7: Create an Amazon Connect Apex client class

In this step we create an Apex class that includes a callout to the Amazon Connect service to start a new Task contact. This class is needed since Apex triggers do not support callouts directly unless they are done asynchronously (hence the @Future annotation seen below).

  1. From the Salesforce Developer Console, select File > New > Apex Class.
  2. Enter AmazonConnectClient as the class Name and click OK.
  3. Copy and paste the following code to the Apex code editor:
    public class AmazonConnectClient {
    
    	@Future(callout=true)
    	public static void createTask(
    		string id,
    		string caseNumber,
    		string queue,
    		string subject,
    		string contactId,
    		string accountId
    	) {
    		try {
    			// validate input parameters
    			id = id == null ? '' : id.trim();
    			if(''.equals(id)) {
    				throw new IllegalArgumentException('Case ID is null!');
    			}
    
    			queue = queue == null ? '' : queue.trim();
    			if(''.equals(queue)) {
    				throw new IllegalArgumentException('queue is null!');
    			}
    
    			// fetch custom settings from Salesforce
    			Amazon_Connect__c connect = Amazon_Connect__c.getValues('Email');
    
    			// format request payload:
    			string body = '{'
    				+ '\"Attributes\": { '
    					+ '\"caseId\":\"' + id + '\", '
    					+ '\"caseNumber\":\"' + caseNumber + '\",'
    					+ '\"queue\":\"' + queue + '\",'
    					+ '\"subject\":\"' + subject + '\",'
    					+ '\"contactId\":\"' + contactId + '\",'
    					+ '\"accountId\":\"' + accountId + '\"'
    				+ '},'
    				+ '\"InstanceId\":\"' + connect.Instance_ID__c + '\",'
    				+ '\"ContactFlowId\":\"' + connect.Contact_Flow_ID__c + '\",'
    				+ '\"ClientToken\":\"' + id + '\",'
    				+ '\"Name\":\"CASE-' + caseNumber + '\"'
    			+ '}';
    
    			System.debug('AmazonConnectClient: Req body =' + body);
    
    			// Send out HTTP request (referencing stored Named Credentials)
    			HttpRequest req = new HttpRequest();
    			req.setEndpoint('callout:AWS_Connect_Credentials/contact/task');
    			req.setMethod('PUT');
    			req.setBody(body);
    
    			Http h = new Http();
    			HttpResponse resp = h.send(req);
    
    			integer status = resp.getStatusCode();
    			System.debug('AmazonConnectClient: status = ' + status);
    			System.debug('AmazonConnectClient: response = ' + resp.getBody());
    
    		} catch(Exception e) {
    			System.debug(LoggingLevel.ERROR, 'AmazonConnectClient: ' + e);
    		}
    
    	}
    
    }
    			

    Note that the createTask method above references the Amazon Connect custom setting created earlier in Step 4.

  4. Select File > Save.

Step 8: Create an Apex trigger

In this step we create an Apex Trigger to execute after a case record is created in Salesforce that calls on the AmazonConnectClient to submit a new Task contact to Amazon Connect.

  1. From the Salesforce Developer Console, select File > New > Apex Trigger.
  2. Enter Email2CaseTrigger as the Name
  3. Select Case as the sObject.
  4. Click OK.
  5. Copy and paste the following code to the Apex code editor:
    trigger Email2CaseTrigger on Case (after insert) {
    
    	for(Case c : Trigger.new) {
    
    		System.debug(LoggingLevel.FINEST, 'Email2CaseTrigger: ' + c);
    		if(!'email'.equalsIgnoreCase(c.Origin)) continue;
    
    		// Query Salesforce for case ID now that it's been inserted into DB
    		List<Case> cases = [
    			select CaseNumber, Subject, ContactId, AccountId from Case
    			where Id = :c.Id limit 1
    		];
    
    		// get owner ID based on initial assignment Email-to-Case setup:
    		string ownerId = string.valueOf(c.OwnerId);
    		System.debug('Email2CaseTrigger: OwnerId ['+ ownerId + ']');
    
    		// query for target queue owner (based on Email-to-Case setup):
    		List<Group> queues = [
    			select Name from Group
    			where Type = 'Queue' and Id = :ownerId limit 1
    		];
    
    		if(queues == null || queues.size() != 1 || queues[0].Name == null)
    		continue;
    
    		string queue = queues[0].Name.toLowerCase();
    		System.debug('Email2CaseTrigger: queue ['+ queue + ']');
    
    		if(!'sales queue'.equals(queue) && !'support queue'.equals(queue))
    		continue;
    
    		// Send asynchronous request to Amazon Connect API
    		AmazonConnectClient.createTask(
    			c.Id,
    			cases[0].CaseNumber,
    			queue,
    			cases[0].Subject,
    			cases[0].ContactId,
    			cases[0].AccountId
    		);
    	}
    
    } // trigger
    
  6. Select File > Save.

Step 9: Create a Salesforce CTI Adapter flow to automate an agent screen-pop

In this step, we create a new Salesforce CTI Adapter flow to automate the agent screen-pop using the case ID submitted through the Apex trigger in Step 8.

The following procedure assumes you are familiar with the Amazon Connect Salesforce CTI Adapter setup and configuration.

  1. From the Service Console in Salesforce, select AC CTI Adapters from dropdown as shown below. If AC CTI Adapters is not visible, click on the Edit option to add it to the list of options.
  2. Next, search for an select ACLightningAdapter. If not visible, select All from the AC CTI Adapters list if Recently Viewed is currently selected.
  3. Scroll down and click on the CTI Flows tab, then click on New to create a new flow.
  4. In the following view, enter a descriptive name as CTI Script Name. For example, Default Task Contact Screenpop.
  5. Select Amazon Connect Task Contact as the Source.
  6. Select onConnecting as the Event (this may be changed later to meet on your requirements).
  7. Enter a Description (optional).
  8. Click Save.
  9. Scroll down to CTI Flow section and drag and drop the Start block over to the canvas.
  10. Drag and drop a CTI block to the canvas and select Get Contact Attribute as the type.
  11. Connect Start to the Get Contact Attribute block and enter caseId as the attributeName.
  12. Drag and drop a second CTI block to the canvas and select Screenpop Object as the type.
  13. Connect the Get Contact Attribute block to the Screenpop Object block and select value as the recordId for the Screenpop Object block.
  14. Drag and drop a third CTI block to the canvas and select Log to Console as the type.
  15. Connect the error exit point of the Screenpop Object block to the Log to Console block and select error as the level.
  16. Enter a descriptive error as the message.
  17. Drag and drop the End block to the canvas and connect the Screenpop Object and Log to Console blocks to it.
  18. Click Save.

Step 10: Try it out

  1. Sign into the Amazon Connect console as the user from Step 1.
  2. From the console, navigate to Real-time Metrics and click on Queues.
  3. Send a message to each of the 2 email addresses configured in Salesforce for Email-to-Case.
  4. Refresh the Queue stats until you see 2 queued contacts, 1 for sales and 1 for support:
  5. Sign into the Salesforce Service Console and the Contact Control Panel (CCP).
  6. Set the agent status to Available in the CCP.
  7. Upon receipt, click Accept task to accept the incoming Task contact.
  8. Notice the Salesforce case screen pop in the background as the Task was received.
  9. Click on Show all task information.
  10. Confirm that the caseNumber and queue listed in the CCP match the corresponding values in the case that was displayed in Salesforce.
  11. Click End task.
  12. Repeat steps 7 – 10 to verify that target queue is support queue.
  13. Logout of Amazon Connect.

Cleaning up

To avoid incurring future AWS or Salesforce charges and for security purposes:

    1. Delete the IAM user and policy
    2. Delete the Amazon Connect instance
    3. Delete the Apex trigger
    4. Delete the Sales and Support email routing addresses:
      1. In Salesforce, navigate to Setup
      2. Use Quick Find to navigate to your Email-to-Case settings
      3. Scroll down to the Routing Addresses section and use the Del link to delete as shown below
  1. Disable or delete the forwarding rules created in your mail server for the email addresses used in this exercise.

Considerations

Conclusion

In this post, you learned how to seamlessly integrate Salesforce Email-to-Case with Amazon Connect tasks to automatically assign customer email cases to contact center agents. You also learned how to use an Apex trigger to customize the behavior and pass along contact attributes that agents can use to deliver faster service and thereby enhance the customer experience.

We encourage you to explore other Amazon Connect features and integration options based on your customer needs.

Join us for AWS Contact Center Day, a free virtual event where you’ll learn about the future of customer service, how machine learning can optimize customer and agent experiences—and more. Register now »

About the authors

Ed Valdez

Ed Valdez is a Specialty Consultant with Amazon Web Services. As a software development professional with over 23 years of experience, he specializes on designing and delivering customer-centric solutions within the contact center domain.

Manish Suvarna

Manish Suvarna is a Sr. Engagement Manager at Amazon Web Services. As part of AWS Energy team, he works with various customers helping them accelerate their adoption of AWS Cloud.