2021-09-24

How to initiate task from IVR in Amazon Connect

UPDATE from 2021/11/20:

Amazon Connect now allows creating tasks from Contact Flow using a new contact block.

It means that you do not need to use Lambda functions to do that.

The New Create task block is quite intuitive. Now you can also specify if you want to create a task right away or schedule task creation in the future. 

More documentation is available here:

https://docs.aws.amazon.com/connect/latest/adminguide/create-task-block.html

Lambda function that is mentioned below could be still useful if you want to trigger task creation, not from IVR. But for example from another Amazon AWS service.


*********************

Not long time ago Amazon introduced a new type of contacts available in Amazon Connect -  tasks.

In my article, I will show you an example of how to initiate a task from IVR.

How it could be useful?

For example, a client calls your IVR and requests a certain type of service that cannot be fully automated. In that case, you might profit from the ability to automatically create a task that will be then sent to an agent for processing.

Here is a sample scenario:

1) Client calls an IVR of  home internet provider company

2) IVR asks the client to enter the account number for identification

3) After that you ask the client what he wants to do with his current contract

  • option 1- upgrade
  • option 2 - renewal
  • option 3 - cancellation
4) For example client selects renewal 

5) Now we will initiate a task that will be sent to a queue that is responsible for contract renewals.

6) When an agent receives the task he would be able to see: account number, request type, and phone number of the person. 

Here is how it can be done in Amazon Connect:



Step 1.

The first step is to create a simple contact flow that will be used to send tasks to the required queue.


 What it does:
* Set working queue - to define Queue that will be used to receive tasks
* Transfer to queue - to send a task to the queue

Once you created the contact flow click on "Show additional flow information". You will see a long string of Contact Flow ARN. You need to copy the last 36 characters of it starting after contact-flow/. This is your ContactFlowId. You will need it in the next step.


Step 2.

I created Lambda function using Python 3.9 which is called initiateTask.

What it does:

1) Collects the following attributes from the call
* account number
* request type
* caller number
* InstanceARN - it is required to be able to get InstanceID, it is required to initiate task using Amazon Connect API

2) Using Amazon Connect API I initiate a task.

Important: you need to specify Contact Flow Id that will be used to send tasks to the queue.
This is Contact Flow that was created in the previous step.

3) You can also specify the URL that will be displayed in your task description.
It could be link to your CRM system or any other website.

Here is the full text of my Lambda function:

import json
import boto3


def lambda_handler(event, context):
    
    accountNumber=event['Details']['ContactData']['Attributes']['accountNumber']
    requestType=event['Details']['ContactData']['Attributes']['requestType']
    CLID=event['Details']['ContactData']['CustomerEndpoint']['Address']
    InstanceARN=event['Details']['ContactData']['InstanceARN']
    InstanceId = InstanceARN[-36:]

    client = boto3.client('connect')
    
    Name=requestType.upper()
    URL="https://www.your-internet-on-demand.com/?accountNumber="+accountNumber
    Description="Request type ="+requestType+". AccountNumber="+ accountNumber+". Caller number="+CLID
    
    
    response = client.start_task_contact(
        InstanceId=InstanceId,
        ContactFlowId='5b67729d-21e7-4d3c-8a28-c96f881aa1a1',
        Name=Name,
        References={
            'URL': {
                'Value': URL,
                'Type': 'URL'
            }
        },
        Description=Description
    )
    
    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('OK')
    }


Step 3.

Now I will create another Contact flow that initiates the task.





This is how it works

1) Client calls the contact center

2) In the IVR I play the following message 
"Hello. Welcome to Internet on Demand. 
Please enter your 5-digit account number."

3) Client enters an account number

4) I save this information as User Defined attribute accountNumber


5) Now I play another message to the client

"How can we help you?
To request an upgrade press 1. 
To request a renewal without upgrade press 2. 
To cancel account press 3"

6) Depending on what the client selects I save the choice in User-defined attribute requestType

Example: when the client selects option 1 - upgrade


7) After that I invoke my Lambda function

8) At the end I play the following message
"Thank you. Your request was sent for processing. You can expect results in 24 hours."



Step 4.

Here is what the agent will see when the task arrives




2021-09-22

How to send Email from IVR in Amazon Connect

 In my previous article, I gave an example of how to send SMS from IVR in Amazon Connect.

This time I will demonstrate how to send an email.

Why someone might need this feature? For example, you can send instructions to contact center clients when they select a certain option in IVR menu.

The process is similar to sending SMS:

1) Client calls IVR and selects an option to receive information by Email

2) After that you have to identify the client in your database. In my example, I identify client simply by caller number, but in your case, you can ask client to enter  client id.

3) Also database has to identify the email address associated with the client.

4) Once the client is identified and we know the email address we can send an email using Amazon Simple Email Service (SES). Alternatively, you can send an email using Amazon Pinpoint. In my example I use SES.

Here is the full process:

Step 1.

Create DynamoDB table Clients that contains information for each client, including phone number and email address.

Phone number must be in E.164 format.


Step 2.

In order to be able to send emails using Amazon SES you need to add an Email Address to it that you will use as Mail From.

In my next step MailFrom variable contains an email address that I already added to Amazon SES.

Step 3.

I created Lambda function using Python 3.9 which is called sendSMS. 

What it does:

1) gets contact attribute with caller number

2) does query in Clients table and returns Email address of the person

3) If the client is identified and we have his email address we can now send an email message using Amazon SES

Here is the full text of Lambda function:

import json
import boto3
from botocore.exceptions import ClientError
from boto3.dynamodb.conditions import Key

def lambda_handler(event, context):
    
    
    dynamodb = boto3.resource('dynamodb')
    table = dynamodb.Table('Clients')
    
    CLID=event['Details']['ContactData']['CustomerEndpoint']['Address']
   
    
    response = table.query(
        KeyConditionExpression=Key('phoneNumber').eq(CLID)
        )
    resp=response['Items']
    
    for item in resp:
            Email=item['Email']
    

    MailFrom = "support@yourcompany.com"
    MailTo = Email
    MailSubject = "New application instructions"
    
    # Non-HTML Body
    MailBody = ("New application instructions\r\n"
                 "Access following link to get installation instructions http://tinyurl.com/AmazonConnectSMS"             
                )
                
    # HTML Body
    MailBodyHTML = """<html>
    <head></head>
    <body>
      <h1>New application instrunctions</h1>
      <p>Access following link to get installation instructions
        <a href='http://tinyurl.com/AmazonConnectSMS'>New application</a>
        </p>
    </body>
    </html>
    """            
    
 
    client = boto3.client('ses',region_name="us-east-1")

    # Sending email
    try:
        #Provide the contents of the email.
        response = client.send_email(
            Destination={
                'ToAddresses': [
                    MailTo,
                ],
            },
            Message={
                'Body': {
                    'Html': {
                        'Charset': "UTF-8",
                        'Data': MailBodyHTML,
                    },
                    'Text': {
                        'Charset': "UTF-8",
                        'Data': MailBody,
                    },
                },
                'Subject': {
                    'Charset': "UTF-8",
                    'Data': MailSubject,
                },
            },
            Source=MailFrom,
        )
 
    except ClientError as e:
        print(e.response['Error']['Message'])
    else:
        print("Email sent! Message ID:"),
        print(response['MessageId'])
        return {
            'statusCode': 200,
            'body': json.dumps('OK')
        }


Step 4.

Here is my sample call flow that sends email.

In the IVR I ask clients:

"Hello. Thank you for calling IT Helpdesk.
Please press 1 to receive an email with instructions on how to setup a new application."

if the client pressed 1 I invoke my Lambda function sendEmail.






2021-09-18

How to send SMS from IVR in Amazon Connect

One great thing about AWS is how easy it is to integrate different services. Here is one of the examples.

Let's say you want to build the following solution:

  • Clients are calling your contact center and when they press a certain option in the IVR you want to send them an SMS message. What this message contains depends on your requirements. In my case, I send an SMS with a link to instructions on how to install a new mobile application.
  • Before sending the message you want to verify if this is a valid client and not just a random person.

You can do that by integrating Amazon Connect with Amazon Simple Notification Service (SNS).

Here is how to do that:

Step 1.

I created DynamoDB table called Clients.

It contains phone numbers for each client and some other information about each client.

Phone numbers must be in E.164 format.


Step 2.

I created Lambda function sendSMS. I use Python 3.9

How it works:

1. I get the contact attribute Customer number to get the phone number of the caller.

2. I run a query and check if this phone number is in Clients tables.

3. If it is found - it means it is a valid client

4. After that I connect to SNS and use action publish to send SMS.


In my example message is hardcoded in my Lambda function but depending on your particular requirements you can make it dynamic.


Here is my Lambda function:

import json
import boto3
from botocore.exceptions import ClientError
from boto3.dynamodb.conditions import Key

def lambda_handler(event, context):
    
    dynamodb = boto3.resource('dynamodb')
    table = dynamodb.Table('Clients')
    
    message="Link on how to setup our new mobile application http://tinyurl.com/AmazonConnectSMS"
    
    CLID=event['Details']['ContactData']['CustomerEndpoint']['Address']

    response = table.query(
            KeyConditionExpression=Key('phoneNumber').eq(CLID)
        )
    resp=response['Items']
    
    for item in resp:
            phoneNumber=item['phoneNumber']

            if phoneNumber==CLID:            
                 # Create an SNS client
                client = boto3.client("sns",region_name="us-east-1")
            
        
                # Send SMS message
                client.publish(
                    PhoneNumber=CLID,
                    Message=message
                )
    
                return {
                    'statusCode': 200,
                    'body': json.dumps('OK')
                }


Step 3.

Now I just need to add my lambda function to Amazon Connect IVR flow.

I created a simple call flow. 

It plays the following message:

"Hello. Welcome to IT Helpdesk. If you are calling from a mobile device about instructions on how to setup a new application please press 1 and we will send you instructions by SMS."

If the client presses 1 I invoke Lambda function sendSMS. Quite simple.







2021-09-15

Estimated Wait Time in Amazon Connect

One of the popular features of the contact center is the ability to play different comfort messages while a call is waiting in the queue.

Out of the box Amazon Connect allows you to play the following information:
  • Number of contacts waiting in the queue
  • How much time oldest contact waiting in the queue
  • Various information about how many agents are available, busy, etc...

What if you want to play Estimated Wait Time (also called Average wait time or Expected wait time in different contact center solutions)? 

It is possible to add this functionality by utilizing Amazon Connect API and Lambda function.


Step 1. 

I created AWS Lambda function getEWT. I used Python 3.9.

What it does?
1) It takes the following attributes from the call
  • statInterval - allows to define time interval that we will use to calculate Estimated Wait Time. It could be last 15 minutes or longer depending on your requirements. If statInterval attribute is missing my function will use 15 minutes as the default value.
  • channel - this parameter identifies the type of contact (Calls, Chat, Tasks) - if your Queue allows receiving different types of contacts normally you would want to have separate Estimated Wait Time for different types of contacts.
  • queueARN - this is identificator of the queue. We need to get the last 36 characters of it to get queueID- we need this parameter to be able to get real-time stats for the queue.
  • InstanceARN - ARN of your Amazon Connect instance. We need it to get InstanceId of your Amazon Connect instance which is required to use Amazon Connect API function

2) after that I connect to Amazon Connect API and use function get_metric_data to get statistical info for the queue during the required interval.

3) I get a metric called QUEUE_ANSWER_TIME - the average time that contacts wait in the queue before being answered by an agent. I use this metric as equivalent for Estimated Wait Time.


You can find the source code of this function on my Github:


Step 2.

Now you can use this Lambda function in your Customer queue flows (flow that is used when a call is waiting in queue).

1) At first you need to assign the required statistical interval to user-defined attribute statInterval using "Set contact attributes" block. 

In my example, I use 15 minutes intervals.





2) After that you can invoke getEWT function

3) It will return the external attribute EWT that contains the estimated wait time value in seconds.

Based on the returned value you can play different messages to clients or make decisions of what to do with the call.





Here is a sample call flow that I use:





Step 3.

You can also use this function in inbound contact flows or modules.

How to do it:

1) Use Set contact attributes block to define statInterval
2) Use Set working queue block to define Queue
3) Now you can use Invoke AWS Lambda function to call getEWT function
4) Use Check contact attribute to check external attribute EWT