SMS Return Message Routing
In part 1 of this blog we looked at three options that enable an Agent to make originate an SMS message:
- Option 1 – User a TASK Template
- Option 2 – Create an HTML Form
- Option 3 – Create an Email to SMS solution
As it relates to being able to route a return message back to the Agent that created the message, there are some real problems with Option 1 and Option 2.
Option 1 Task Template launches Contact Flow
The TASK solution gets the Origination SMS job done and works just fine. The Contact Flow the TASK points to contains an invoke Lambda that sends the messageContent and phoneNumber on to Pinpoint SMS. There is no real way however, to capture the Agent that initialized the Task. We tried writing the phoneNumber and TaskID along with a timestamp to a dynamoDB table, then invoking another lambda to look up the phoneNumber it in an inbound contact flow, but it was just ugly. How many lambda’s does it take to route a message? You need someway to ID the Agent so you can “set working queue” by agent and get the incoming return message routed accordingly. Given that custom fields (as of this blog) can not be passed as a contact attribute, there was not way to add the Agent ID to the Task Template.
Another major challenge is that the CHAT API used by SMS (and chat for that matter) does not support Contact Attributes. Let us assume you want to ask the customer to enter the order number so you can look up the status. They might provide that number, but there is no way to extract that data and assign it to a Contact Attribute for further processing later in the contact flow.
We learned that you can extract the incoming EVENT when it hits the Contact Flow attached to the Pinpoint SMS number in your instance. In fact we regularly do that just to make sure that documentation that describes the EVENT is correct. In this example we want to grab the incoming phone number so we can look it up in the scratch pad dynamoDB table created for this purpose.
Invoke this simple python Lambda as the first block in your contact flow and you will get the details you need to extract the senders phone number.
Note in details that this SMS came in as a CHAT channel, though he Segment Attribute is channel:SMS. We can get the customer endpoint and use that to set a Contact Attribute, but not much else of use here! The ContactId and the InitialContactId are the same.
Enter Option 2 (Static s# website to launch HTML form)
The benefit of popping an HTML form is that you can prompt the Agent to enter something to identify themselves. This would enable you to write the phoneNumber, AgentId and timestamp to a dynamoDB table for later processing. On the inbound handler we could grab the phoneNumber, look it up in the database and grab whatever it was that you were using for an AgentID. This might be the AgentLogIn or User Name or even an “extensionNumber”. There would be yet another dynamoDB table that mapped AgentId to the Agents Name or ARN, either of which can be used to “Set Working Queue by Agent”.
Enter option 3 Email to SMS
In this option we want to use email to launch the SMS handler using the configuration provided in Part 1. The thinking here was to use SNS rather to trigger a Lambda rather than Invoking Lambda from inside a contact flow triggered by the Chat API. Do not connect the SMS phone number direct;y to the Instance. We created two SMS handlers: one inbound Lambda to handle either an SMS that did not ordinate by an Agent. it could also handle a return message originated by an Agent.
Email Outbound
Using the email client we were able to launch an outbound lambda that would be able to parse the message and write the From (i.e. Agent ID), Subject (i.e. target recipient phone number)and a times stamp to a dynamoDB table. No need to log the message content, we would pass all the variables off to the Pinpoint SMS number.
SMS Inbound
The inbound SMS triggered the lambda which would use the phone number to index the dynamoDB table and bring back the AgentId. It might be necessary to use the AgentId to look up the Agent Name or ARN, but the result was much cleaner and seemed to work just fine! With the AgentId we were If there was no matching number in the database then the message was treated as a new incoming SMS and routed to the default workgroup set in the contact flow.
TTL
We needed a ‘garbage collector’ that could go into Dynamodb and clean out any entries that had a time stamp that exceeded whatever we set as the Time To Live (TTL) value.