WhatsApp Integration with Amazon Connect (with voice notes)
Use WABA as chat channel for your contact center.
- AWS End User Messaging (EUM) for WhatsApp channel management
- Amazon Connect for chat functionality
- AWS Lambda for message processing and integration
- Amazon DynamoDB for conversation state management
- Amazon S3 for media file storage
- Amazon SNS Topic for event pub/sub
- User sends a WhatsApp message
- AWS End User Messaging Social (EUM-Social) receives the message send it to SNS Topic for inbound messages.
- AWS Lambda function:
- Creates or continues a chat in Amazon Connect
- Stores message metadata in DynamoDB (Not message content)
- Handles media files by uploading them to S3
- Optionally if voice note is received, it will be downloaded to s3 bucket and transcribed before sending to amazon connect chat.
- Amazon Connect agent receives and responds to the message
- Lambda function receives Connect response (via another SNS Topic) and sends it back to WhatsApp user via EUM API
- User receives the response in WhatsApp
- Have or create a Meta Business Account
- Access AWS End User Messaging Social console and and link business account through Facebook embedded portal.
- Ensure you have a phone number that can receive SMS/voice verification and add it to Whatsapp.
python3 -m venv .venv
source .venv/bin/activate # On Windows use: .venv\Scripts\activate.bat
pip install -r requirements.txt
WhatsappHandler
Lambda function and update the INSTANCE_ID
(your instance id) CONTACT_FLOW_ID
(the contact flow used for chat session) and CHAT_DURATION_MINUTES
(how long the chat will be active in connect) environment variables.WhatsappService
class to easily save, react, read, and reply whatsapp messages:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
for message in whatsapp.messages:
audio = message.get_audio(download=True) # Check if there is audio
transcription = None
if audio.get("location"): # it's been downloaded
print("TRANSCRIBE IT")
# transcribe using Amazon Transcribe
transcription = transcribe_service.transcribe(audio.get("location"))
message.add_transcription(transcription)
#An existing conversation with Amazon Connect Chat
contact = connections.get_contact(message.phone_number)
# Get message text content
text = message.get_text()
if transcription:
# Reply the transcription to the user
message.text_reply(f"🔊_{transcription}_")
text = transcription
...
send_whatsapp_message
method from End User Social Service. For a complete list of the different messages you can send and examples, please refer to this documentation. In this code you can implemente custom logic to handle reactions, images, videos, etc.- If a contact exists, it tries to send the message using the existing connection. If the connection is invalid, it removes the old contact and creates a new chat connection
- If no contact exists, it creates a new chat connection from scratch. In all cases it stores/updates the connection details in the connections database
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
if(contact):
try:
send_message_response = chat.send_message(text, contact['connectionToken'])
except:
print('Invalid Connection Token')
connections.remove_contactId(contact['contactId'])
print('Initiating connection')
contactId, participantToken, connectionToken = chat.start_chat_and_stream(
text, message.phone_number, "Whatsapp", customer_name, message.phone_number_id)
connections.update_contact(
message.phone_number, "Whatsapp", contactId, participantToken, connectionToken, customer_name,
message.phone_number_id)
else:
print("Creating new contact")
contactId, participantToken, connectionToken = chat.start_chat_and_stream(
text, message.phone_number, "Whatsapp", customer_name, message.phone_number_id)
connections.insert_contact(message.phone_number, "Whatsapp", contactId, participantToken, connectionToken, customer_name,
message.phone_number_id)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
customer = connections.get_customer(contactId)
if(customer):
phone = customer['customerId']
systemNumber = customer['systemNumber']
send_whatsapp_text(message_body,phone, systemNumber)
...
def send_whatsapp_text(text_message, to, phone_number_id, meta_api_version="v20.0" ):
message_object = {
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": f"+{to}",
"type": "text",
"text": {"preview_url": False, "body": text_message},
}
kwargs = dict(
originationPhoneNumberId=phone_number_id,
metaApiVersion=meta_api_version,
message=bytes(json.dumps(message_object), "utf-8"),
)
response = boto3.client("socialmessaging").send_whatsapp_message(**kwargs)
print("replied to message:", response)
...
- Pay per message sent/received 0.005 USD
- Conversation rate (24 thread) depends of conversartion categories.
- Amazon SNS (no charges for lambda delivery)
- Amazon Connect Chat: 0,004 USD per message
- Amazon DynamoDB storing chat metadata
- Amazon Transcribe for audio transcription
- Amazon S3 for media storage
cdk destroy
if using cdk cli. Alternately go to cloudformation console an hit Delete
Any opinions in this post are those of the individual author and may not reflect the opinions of AWS.