AWS Contact Center

Recovering abandoned calls with Amazon Connect

At some point, you have likely had to hang up after waiting on the phone for an agent to help you. You lost your spot in the queue, without the option to leave a voicemail or receive a callback. This experience is exceptionally frustrating for users, and also damaging to a business from both a customer satisfaction and revenue perspective.

However, what if you could capture those abandoned calls? What if you could analyze them to determine if you wanted to recover those callers, then call those customers back to make sure that they got the help that they needed? What if you could call them when an agent was available, instead of having to wait in the queue?

Amazon Connect makes this solution possible.

This post walks you through how to recover customers that have abandoned their position in the queue.

Solution overview

This solution has the following architecture:


The solution has the following steps:

  • Stream contact trace records (CTRs) using Amazon Kinesis.
  • Configure queue parameters with an Amazon DynamoDB table.
  • Process events in the stream with an AWS Lambda function.
  • Engage with customers that abandoned their call by deploying an Amazon Connect contact flow.
  • Deploy the solution.
  • Test and validate the solution.

This solution requires the following:

  • An existing Amazon Connect instance.
  • Configure Amazon Connect to stream Contact Trace Records (CTRs) out via Amazon Kinesis.
    • For this blog, we are using Amazon Kinesis Data Streams specifically, and not Amazon Kinesis Firehose
  • Access to the AWS Management Console, with permissions to create new IAM policies and roles, DynamoDB tables, and Lambda functions.

Additionally, you need your Amazon Connect instance Amazon Resource Name (ARN) and the code example package, which contains code and contact flow samples. As you work through the process, there are a few item names to reference in multiple places. It is helpful to have your preferred text app open to record these during this configuration.

To find your Amazon Connect ARN, complete the following steps.

  1. In the Amazon Connect console, select the instance name to configure.
  2. Copy the instance ARN.
  3. Paste this into your text app.

To download the code example package, complete the following steps.

  1. Download the code example package .zip file.
  2. Save the .zip file to your local computer.
  3. Extract the file contents to a readily available location on your computer.

When you have your instance ARN and code example package, you’re ready to begin the configuration.

Configure CTR streaming

The first step is to configure your Amazon Connect instance to stream CTRs, or by validating the configuration if already done.

The best way to capture abandoned calls in Amazon Connect is to analyze the CTRs. A CTR contains everything you need, including time in the queue, agent connection attempts, and contact attributes. To analyze CTRs, you must stream them using Amazon Kinesis Data Streams. This configuration uses Kinesis Data Streams as opposed to Amazon Kinesis Data Firehose. Kinesis Data Firehose has a buffer that can delay the processing of records and you want to recapture these customers as fast as possible.

To configure CTR streaming, complete the following steps.

  1. From the Amazon Connect console, select the instance name to configure.
  2. Choose Data streaming.
    1. If data streaming is already enabled and configured for CTRs, verify that Kinesis Stream is selected and copy the stream name to your text app.
    2. If data streaming is not enabled or configured for CTRs, select Enable data streaming.
  3. For Contact Trace Records, choose Kinesis Stream.
  4. Choose Create a new Kinesis Stream. This opens a new tab or window.
  5. From the Kinesis Data Streams console, choose Create Kinesis Stream.
  6. For ease of reference, name the new stream YOUR_INSTANCE_NAME_CTR. For example, acrblogtest09132019_ctr and copy the stream name to your text app.
  7. For Number of shards, enter 1.
  8. Leave all other settings as the default and choose Create Kinesis Stream.
  9. Close the Kinesis tab or window and return to the console. Refresh the browser to go back to the console main page.
  10. Select the instance name to configure, choose Data streaming, and then select Enable data streaming.
  11. For Contact Trace Records, select Kinesis Stream and select the data stream that you just created.
  12. Choose Save.

Configure the customer callback experience

The next step is to configure the callback experience for customers that abandoned their call.

When calling them back, give them the option to receive a callback or to decline further interaction. To do this, import a pre-configured contact flow.

  1. Log in to Amazon Connect Administrator.
  2. On the left menu, choose Routing, Contact flows.
  3. Choose Create contact flow.
  4. Under Save, choose Import Flow (beta).
  5. Navigate to the code example package that you downloaded and extracted earlier.
  6. In the connect folder, select ACR_Callback_Example.
  7. Choose Import.
  8. After the import completes, choose Publish.
  9. After the flow is published and the editor refreshed, expand the Show additional information pane and copy the flow ARN value to your text app.

The customer experience is ready to go!

Create the queue configuration database

Now configure a place to store your queue configuration settings.

While there are many cases in which recovering abandoned calls is desirable, there may be cases in which it is not. There may also be different criteria for abandoned calls in different queues, or a desire to provide a different customer experience. To enable queue level customization, you need a place to store some settings. This post uses DynamoDB.

To configure the Queue Settings database, complete the following steps.

  1. From the DynamoDB console, choose Create table.
  2. For Table name, enter the name of your choice.
  3. Copy the name to your text app.
  4. For Primary key, enter queue_name.
  5. Leave all other settings to default and choose Create.
  6. Choose Items, Create item.
  7. Choose Tree, Text.
  8. From the code example package, in the \dynamo folder, open the file sample_dynamo_db_record.json and copy the file contents.
  9. On the Create item page, replace the default item JSON with the following code example:
    • For abandoned_threshold, enter the number of seconds that the caller must be in the queue before hanging up to qualify as an abandoned call.
    • For callback flow ID, copy and paste the last string of characters in the contact flow ARN that you imported earlier, everything after the last “/”. For example, daad10e8-50e9-40d1-8f6b-da38295b9289.
    • For queue_name, enter “BasicQueue” to configure the options for the default queue created in all Amazon Connect instances.
      { “abandoned_threshold”: 30, “callback_flow_id”: “daad10e8-50e9-40d1-8f6bda38295b9289”, “queue_name”: “BasicQueue” }
  10. Choose Save.

Repeat these steps for all queues to configure for abandoned call recovery. For queues from which you do not want to recover abandoned calls, do not configure the option. The code you use later skips any records that do not have a configuration.

You now have your queue configuration database created.

Create an IAM policy and role

The next step is to configure access to the required resources to make this configuration work.

This configuration uses code deployed using AWS Lambda, which allows code to run in a serverless environment. However, you must give that code access to all of the resources that it needs, such as the Kinesis data stream and the Amazon Connect instance. Generate a policy and role that the Lambda function can assume when executing.

For most of the rights that Lambda needs, you can use some AWS managed policies. However, to give Lambda access to the Amazon Connect API that launches the outbound call to the customer, you need a new policy.

To create the new IAM policy, complete the following steps.

  1. In the IAM console, choose Policies, Create policy, JSON.
  2. In the IAM folder within the code example package, open connect_outbound.json and copy the contents.
  3. Replace the default policy JSON with the JSON that you copied.
    Replace YOUR_INSTANCE_ARN in the resource key with the Amazon Connect instance ARN that you copied earlier, as in the following code example.{
    "Version": "2012-10-17",
    "Statement": [
    "Sid": "VisualEditor0",
    "Effect": "Allow",
    "Action": "connect:StartOutboundVoiceContact",
    "Resource": "arn:aws:connect:YOUR_REGION:YOUR_ACCOUNT:instance/YOUR_INSTANCE_ID/contact/*"
    The resource ARN must end with “/contact/*”. If you accidentally remove this, your outbound API calls fail. This policy grants permissions to start outbound calls from that instance.
  4. Choose Review policy, and provide a name and optional description.
  5. Choose Create policy.

You are now ready to create the IAM role that uses this policy.

  1. In the IAM console, choose Roles, Create role.
  2. Under Select type of trusted entity, choose AWS service.
  3. For Choose the service that will use this role, choose Lambda.
  4. Choose Next: Permissions.
  5. Find and select the following policies:
    • The policy that you just created—Provides the user of this role with the rights to start outbound calls from your Amazon Connect instance.
    • AmazonDynamoDBReadOnlyAccess—Grants read-read only access to DynamoDB.
    • AWSLambdaKinesisExecutionRole—Provides Lambda read access to the Kinesis data stream and records.
    • AWSLambdaBasicExecutionRole—Provides Lambda the rights to create Amazon CloudWatch log groups, streams, and events.
  6. Choose Next: Tags, add any desired tags, and choose Next: Review.
  7. For Role name, enter a new name, such as ACR_Role.
  8. Choose Create role.

Create a new Lambda function

The final step in the configuration is to create the Lambda function that makes everything work.

The core of this configuration is Python code that executes in Lambda. This code processes the CTRs as the data stream emits them. It checks if the record is potentially an abandoned call by seeing if the call was in a queue and never connected to an agent.

  • If the call meets that criteria, the code checks the DynamoDB table to see if the queue in the CTR has a configuration.
  • If so, it checks to see if this call was in the queue beyond the threshold configured in the table.
  • If the call meets all these conditions, the code submits the outbound API request, using the contact flow that you imported to provide the customer experience.

To create a new Lambda function, complete the following steps.

  1. In the Lambda console, choose Create a new function, Author from scratch.
  2. For Function name, enter a name.
  3. For Runtime, select Python 3.7.
  4. Under Choose or create an execution role, choose Use an existing role and select the IAM role that you created earlier.
  5. Choose Create function.
  6. After the function creation completes, expand the Designer pane, and choose Add trigger.
  7. On the Add trigger page, under Trigger configuration, choose Kinesis.
  8. Select the CTR stream that you created earlier, keep all other settings at their defaults, and choose Add.
  9. After the screen updates, choose the Lambda function box in the Designer page, then collapse the Designer pane.
  10. In the function code, replace the contents of the Lambda function with the contents of the file in the \lambda folder of the code example package.
  11. Under Environment variables, enter a new variable with the key name acr_config_table and set the value to the name of the DynamoDB table that you created earlier (acrblog_table).
  12. Choose Save.

Test the solution

You can now validate the function by placing test calls into the instance, verifying the experience, and validating the results in CloudWatch.

  1. Log an agent into your instance. Make sure that the agent has BasicQueue or another queue that you have configured for abandoned call recovery in their routing profile.
  2. Place a call into the instance and answer it. This confirms that the setup does not process that call as abandoned.
  3. Place a second call and leave it in the queue beyond the threshold that you defined, then hang up. The setup should process this call as abandoned.
  4. Make sure that the agent is available.
  5. Call your instance from an external phone, playing the role of customer, and accept the call as the agent.
  6. End the call and put your agent into an offline state. It is important to exit the After Call Work state, if configured, to make sure that the CTR generates.
  7. Call again. This time the agent does not answer the call.
  8. Let the call stay in the queue until after the threshold time, then hang up.
  9. In less than 1 minute, you should receive a callback on the external (customer) phone. Answer the call. When asked if you would like to speak with an agent, press 1. After setting the callback, hang up.
  10. Put your agent into the available state. The callback request should come to the agent.
  11. Accept the callback. You should receive the callback as the customer.

To validate what happened in CloudWatch Logs, complete the following steps.

  1. In the Lambda console, select the Lambda function that you created for this post.
  2. After the function loads, choose Monitoring, View logs in CloudWatch.
  3. In the most recent log streams, you should see two responses:
    • The call that was not abandoned:
      {'ctrs_processed': 0, 'ctrs_skipped': 1}
    • The call that was abandoned:
      'destination_phone_number': '+1XXXXXXXXXX',
      'contact_flow_id': 'YOUR_CONTACT_FLOW_ID',
      'instance_id': 'YOUR_INSTANCE_ID',
      'source_phone_number': '+1XXXXXXXXXX',
      'attributes': {
      'greetingPlayed': 'true',
      'from_queue': 'arn:aws:connect:us-east-1:YOUR_ACCOUNT:instance/YOUR_INSTANCE/queue/YOUR_QUEUE_ID'


This solution analyzed CTRs from Amazon Connect to determine when callers have abandoned the call while waiting. This allows you to re-engage that customer to solve their problem and improve their experience.