AWS Contact Center

Dynamically setting outbound numbers for contact centers with Amazon Connect

If a caller ID is local, customers are more likely to answer an incoming call. Because it’s unlikely that contact center agents are always local, our partners wanted to use Amazon Connect to place outbound calls using a local number, picked dynamically by the agent.

This post presents a simple way to accomplish this, using the following AWS services:

Solution overview

At a high level, the solution covers the following steps:

  1. An agent places an outbound call to a customer located in a different state within the US. The agent:
    1. Enters the customer’s phone number in the Amazon Connect Contact Control Panel (CCP) phone number field.
    2. Chooses the Dial button in the CCP.
  2. Clicking the CCP dial button invokes an ‘Outbound Whisper contact flow’ within Amazon Connect.
  3. This flow invokes a Lambda function. Amazon Connect passes the customers’ phone number to the Lambda function. The Lambda function retrieves the area code from the phone number. Using the NANPA standard, for example, if the customers’ phone number is +1-808-555-1212 then the Area Code is ‘808’.
  4. The Lambda function queries a DynamoDB lookup table and retrieves the outbound dial number corresponding to this area code (which is 808, in the example above). For example, if the outbound dial number for the area code 808 is +1-808-666-1212 – The Lambda function will return this number to Amazon Connect.
  5. The Amazon Connect contact flow uses this number to place a phone call to the customer’s phone number entered by the agent in Step 1.

The agent’s desktop can see only the customer’s number entered by the agent. The incoming call at the customer’s end shows up with a caller ID belonging to their area (as selected by the agent in step 1).

The following diagram shows the dynamic outbound dial workflow.

 

 

Prerequisites

For this walkthrough, you should have the following prerequisites:

  • Phone Number whitelisting: Any out-dial phone number to be used from Amazon Connect needs to be whitelisted with the Amazon Connect services team. This process allows the number to be legitimately used from Amazon Connect for outbound call. The process involves creating an AWS support ticket with the reason ‘Country Whitelisting for outbound calls’. Please provide the use case in the description of the ticket.

NOTE: Whitelisting is carrier dependent. Any out-dial from Amazon Connect to a different region (state or country) depends on local rules and regulations. Depending on these, the numbers may still show up as ‘Unknown’ – number display is not guaranteed.

  • An active AWS account with the following permissions:
    • Create and modify Lambda functions.
    • Create and update DynamoDB tables.
  • An Amazon Connect instance configured for inbound and outbound calls. Claim the international and national phone numbers to be used for outbound dialing. For more information, see Getting Started with Amazon Connect.

The following IAM Lambda policies are required to prepare the environment:

  • Amazon Connect: Policy to place outbound call. Policy Name = AWSConnect-GrantOutboundPermission. JSON noted below:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "connect:StartOutboundVoiceContact",
            "Resource": ""arn:aws:connect::*:instance/<InsertAmazonConnectInstanceName>/contact/*""
        }
    ]
}

NOTE: Change ‘<InsertAmazonConnectInstanceName>’ to your amazon connect instance name.

  • DynamoDB: Refer this AWS article to create a policy that has access to read from a specific table. Update policy as shown below to enable read from the table ‘USAreaCodes’. The policy is shown below. Policy Name = DDBTblSpecificReadAccess
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ListAndDescribe",
            "Effect": "Allow",
            "Action": [
                "dynamodb:List*",
                "dynamodb:DescribeReservedCapacity*",
                "dynamodb:DescribeLimits",
                "dynamodb:DescribeTimeToLive"
            ],
            "Resource": "*"
        },
        {
            "Sid": "SpecificTable",
            "Effect": "Allow",
            "Action": [
                "dynamodb:BatchGet*",
                "dynamodb:DescribeStream",
                "dynamodb:DescribeTable",
                "dynamodb:Get*",
                "dynamodb:Query",
                "dynamodb:Scan",
            ],
            "Resource": "arn:aws:dynamodb:*:*:table/ USAreaCodes"
        }
    ]
}
  • Lambda: The Lambda functions require the basic pre-existing AWS Role to execute: AWSLambdaBasicExecutionRole. The policy is noted below:
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "logs:CreateLogGroup",
                    "logs:CreateLogStream",
                    "logs:PutLogEvents"
                ],
                "Resource": "*"
            }
        ]
    } 
    

Setup

  • The latest list of US and CA area codes can be obtained from the North American Number Planning Association – NANPA. The blog post requires that this list is batch loaded into DyamnoDB. Please refer this AWS article on batch uploading to DynamoDB.
  • Lambda function: (Name = DDBPhoneNumberSearch): Retrieves the area code from a phone number and returns an outbound dial number specific to that area code. For more information, see AWS Lambda Function Handler in Python.
import json
import boto3

from boto3 import resource
from boto3.dynamodb.conditions import Key
dynamodb_resource   = resource('dynamodb')
areaCodesTable = dynamodb_resource.Table('USAreaCodes')
RET_ERROR = 999

def lambda_handler(event, context):
    phoneNumber = event['Details']['ContactData']['CustomerEndpoint']['Address'] 
    areaCode = (phoneNumber[0:5])[-3:]
    response = ''
    try:
        response = retrieveOutboundDialNumber(areaCode)
    except Exception as e:
        return {
            'statusCode': RET_ERROR,
            'OutboundDialNumber':str(e)
        }
        
    if response != '' :
        if 0 < response['Count'] :
            return {
                'statusCode': response['ResponseMetadata']['HTTPStatusCode'],
                'OutboundDialNumber': response['Items'][0]['OutboundDialNumber']
            }
        else :
            return {
                'statusCode': RET_ERROR,
                'OutboundDialNumber':response['Count']
            }
        
def retrieveOutboundDialNumber(areaCode):
    try:
        response = areaCodesTable.query(
                            KeyConditionExpression=Key('AreaCode').eq(areaCode),
                            ScanIndexForward=False,
                            Limit=1
                            )
    except Exception as ex:
        raise ex
    else :
        return response

Unit Test input for this function:

{
  "Details": {
    "ContactData": {
      "CustomerEndpoint": {
        "Address": "+14088551212"
      }
    }
  }
}

IAM Policies required for this Lambda function:

AWSLambdaBasicExecutionRole

DDBTblSpecificReadAccess

  • Configure the Amazon Connect instance: The Amazon Connect instance must be configured before you create a contact flow. Amazon Connect requires you to whitelist your Lambda functions in the configuration section before being used by a contact flow.
  • Create the Amazon Connect contact flow: Amazon Connect offers you the ability to create various types of contact flows. For this post, I used Contact Flow Type = Outbound Whisper Flow. This flow is invoked whenever an agent assigned to the right queue attempts to place an outbound call. The graphical workflow is shown in the following diagram.

  • Lambda Function Configuration: The block calls the function DDBPhoneNumberSearch
  • The ‘Call phone number’ block has been setup to read the ‘External’ value returned ‘OutboundDialNumber’ and use that number to place the outbound call.
  • The queue within the routing profile that the agent logs in must be configured to use this Outbound Whisper Flow as follows:
    • For Name, enter BasicQueue.
    • For Description, enter “A simple, basic voice queue.”
    • For Hours of operation, choose Basic Hours.
    • For Outbound whisper flow (optional), choose DynamicOutboundDialer.

Execution

Assume that an agent in any location wants to reach out to a customer based in Atlanta, Georgia who has a phone number +17705551212. They want the outbound caller ID to show an Atlanta number:

  • Agent logs into CCP (Call Control Panel). Refer this article to invoke and log into the CCP using Amazon Connect.
  • Agent enters an outbound dial number in the CCP window and hits the ‘Dial’ button. The outbound dial request from the agent’s CCP instance to Amazon Connect invokes the Outbound Whisper Flow. That in turn calls the Lambda function DDBPhoneNumberSearch.
{
  "Details": {
    "ContactData": {
      "CustomerEndpoint": {
        "Address": "+17705551212"
      }
    }
  }
}
  • Return from this Lambda function is:
{
  "StatusCode": 200,
  "DialNumber": "+17706661212"
}

The Outbound Whisper Flow uses the number ‘+17706661212’ to place the outbound call. The customer sees this number when they receive the call on their phone.

 

Conclusion

It’s easy to create a Lambda handler that can dynamically pick an outbound number based on your business case and return that to Amazon Connect to place an outbound call. This functionality can most commonly be used by agents in a marketing department who are responsible to place outbound calls. The functionality increases the success rate at which these calls are accepted by customers as customer are more likely to pick up and answer calls originating from their country.  Note that this approach can be extended to cases where the outbound dial number needs to be for specific states or regions – in such cases, the DynamoDB lookup table will need to be modified / updated accordingly.