AWS Contact Center

Dynamically setting outbound numbers for contact centers with HAQM 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 HAQM 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 HAQM 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 HAQM Connect.
  3. This flow invokes a Lambda function. HAQM 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 HAQM Connect.
  5. The HAQM 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 HAQM Connect needs to be whitelisted with the HAQM Connect services team. This process allows the number to be legitimately used from HAQM 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 HAQM 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 HAQM 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 HAQM Connect.

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

  • HAQM 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/<InsertHAQMConnectInstanceName>/contact/*""
        }
    ]
}

NOTE: Change ‘<InsertHAQMConnectInstanceName>’ 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 HAQM Connect instance: The HAQM Connect instance must be configured before you create a contact flow. HAQM Connect requires you to whitelist your Lambda functions in the configuration section before being used by a contact flow.
  • Create the HAQM Connect contact flow: HAQM 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 HAQM 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 HAQM 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 HAQM 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.