11# Introduction
22
33This repository implements an Infrastructure as Code (IaC), serverless stack that exposes a REST API for sending
4- SMS & WhatsApp messages to your customers while handling conversation windows with WhatsApp destinations
4+ SMS & WhatsApp messages to your customers while handling conversation windows with WhatsApp destinations
55(more on this below).
66
7- It uses AWS End User Messaging as its communications platform and logs message history and handles
7+ It uses AWS End User Messaging as its communications platform and logs message history and handles
88WhatsApp user consent automatically in Amazon DynamoDB.
99
10- [ TOC]
11-
1210# Requirements
1311
1412The code has been tested with Python 3.12 in macOS. You will also need:
@@ -20,18 +18,18 @@ The code has been tested with Python 3.12 in macOS. You will also need:
2018 - [ Configuration set] ( https://docs.aws.amazon.com/sms-voice/latest/userguide/configuration-sets.html )
2119 - [ Phone number or sender ID] ( https://docs.aws.amazon.com/sms-voice/latest/userguide/phone-number-types.html ) . This is
2220 referred to as the "originating entity" later in this document.
23- * WhatsApp-related requirements:
24- - A [ WhatsApp Business Account] ( https://docs.aws.amazon.com/social-messaging/latest/userguide/managing-waba.html )
21+ * WhatsApp-related requirements:
22+ - A [ WhatsApp Business Account] ( https://docs.aws.amazon.com/social-messaging/latest/userguide/managing-waba.html )
2523 [ configured in AWS End User Messaging Social] ( https://docs.aws.amazon.com/social-messaging/latest/userguide/managing-phone-numbers-add.html ) .
26- + If you only have configured a single WhatsApp phone number, the solution will use that for sending messages.
27- For other use cases and for efficiency purposes, you can specify the phone number to use when deploying the
24+ + If you only have configured a single WhatsApp phone number, the solution will use that for sending messages.
25+ For other use cases and for efficiency purposes, you can specify the phone number to use when deploying the
2826 solution.
29- + The Business Account in End User Messaging Social must be configured with a
27+ + The Business Account in End User Messaging Social must be configured with a
3028 [ message and event destination] ( https://docs.aws.amazon.com/social-messaging/latest/userguide/managing-event-destinations.html )
3129 pointing to an SNS topic that this solution will use for tracking SMS message delivery.
32- - A default WhatsApp template in English requesting that your users to connect with you. When you try to send a
33- WhatsApp message to a number that has not communicated with you in the last 24h, the solution will send this
34- template to the user and keep the message in a queue for 2h. If the customer replies to your template in this 2h
30+ - A default WhatsApp template in English requesting that your users to connect with you. When you try to send a
31+ WhatsApp message to a number that has not communicated with you in the last 24h, the solution will send this
32+ template to the user and keep the message in a queue for 2h. If the customer replies to your template in this 2h
3533 window your original message will be automatically sent to the user automatically.
3634
3735# Architecture
@@ -60,9 +58,9 @@ the principles described [below](#observability).
6058
6159## WhatsApp
6260
63- In WhatsApp you generally cannot send free-form messages to users unless they have contacted you in the previous 24
64- hours. In order to contact new users, you must either have them send you a message or send them
65- [ a Meta-approved template] ( https://developers.facebook.com/docs/whatsapp/message-templates/guidelines/ ) asking the
61+ In WhatsApp you generally cannot send free-form messages to users unless they have contacted you in the previous 24
62+ hours. In order to contact new users, you must either have them send you a message or send them
63+ [ a Meta-approved template] ( https://developers.facebook.com/docs/whatsapp/message-templates/guidelines/ ) asking the
6664destination user to write back to you. When they do, you are allowed to send free-text messages to your users for the
6765next 24 hours.
6866
@@ -72,7 +70,7 @@ The communication flow for talking to your clients in WhatsApp is as follows:
7270 explicitly ask the user to not answer anything if they do not want to be contacted.
73712 . If the user answers with any text you can start sending free-form messages for the next 24 hours.
74723 . After 24 hours the communication window closes and you have to send a new template to the customer in order to be
75- able to send free-form messages.
73+ able to send free-form messages.
7674
7775This solution tracks user communications with your number by automatically sending a template as needed and only trying
7876to send free-form messages if the user has responded to the template. If the user does not respond 2 hours after the
@@ -92,15 +90,15 @@ flowchart TD
9290 T -->|No|ST[Send template]
9391 ST -->W
9492 W -->Q
95-
93+
9694 style E fill:#009,color:#ddd
9795 style T fill:#009,color:#ddd
9896```
9997
10098This handling is transparent to you, and you are only responsible for sending the initial request to send a free-form
10199message.
102100
103- Once you make the initial request to the API to send the message, you can track its status as described
101+ Once you make the initial request to the API to send the message, you can track its status as described
104102[ below] ( #observability ) .
105103
106104# Observability
@@ -114,10 +112,10 @@ An entry in the message tracking table will typically contain the following fiel
114112
115113* ` type ` : Message type (either ` sms ` or ` whatsapp ` )
116114* ` eum_msg_id ` : AWS End User Messaging message ID. This is a random unique id.
117- * ` wa_msg_id ` : Meta-provided WhatsApp Message ID. Only available for WhatsApp messages and only once
115+ * ` wa_msg_id ` : Meta-provided WhatsApp Message ID. Only available for WhatsApp messages and only once
118116 Meta server have processed the message send request. Contains ` __UNKOWN__ ` for SMS messages or WhatsApp messages
119117 that have not yet been processed by Meta.
120- * ` delivery_history ` : Map with the history of the ISO-formatted instants when the message transitioned states.
118+ * ` delivery_history ` : Map with the history of the ISO-formatted instants when the message transitioned states.
121119* ` expiration_date ` : The UTC timestamp when the memssage will expire.
122120* ` latest_status ` : The most recent delivery status for the message.
123121* ` latest_update ` : The UTC timestamp when the message delivery information was last updated.
@@ -132,7 +130,7 @@ The status a message transverses through its lifecyle are:
132130* ` delivered ` : Message has been delivered to the user's terminal. Does not guarantee that the user has read it. Also,
133131 SMS carriers might not provide us with this information so correctly delivered SMS messages might not be marked as
134132 ` delivered ` in the table.
135- * ` read ` : [ WhatsApp specific] The message has been shown to the user in the WhatsApp application.
133+ * ` read ` : [ WhatsApp specific] The message has been shown to the user in the WhatsApp application.
136134
137135# Deployment sample
138136
@@ -167,18 +165,18 @@ curl -X POST -H "x-api-key: $(aws apigateway get-api-key --api-key ${RestAPIAPIK
167165
168166More work is required to turn this code into a production sample. Some ideas for future improvement:
169167
170- * WhatsApp delivery error handling in particular should be improved. While the solution should handle 24h
171- WhatsApp communication windows automatically and re-sends the default template if needed, it does not
172- handle the case where delivery to WhatsApp phone numbers fails for whatever reason.
173- The logic for handling these failures can be found in the [ ` wa_status_handler ` ] ( lambda/wa_status_handler/main.py )
168+ * WhatsApp delivery error handling in particular should be improved. While the solution should handle 24h
169+ WhatsApp communication windows automatically and re-sends the default template if needed, it does not
170+ handle the case where delivery to WhatsApp phone numbers fails for whatever reason.
171+ The logic for handling these failures can be found in the [ ` wa_status_handler ` ] ( lambda/wa_status_handler/main.py )
174172 lambda code.
175- * Also, the WhatsApp sending logic only sends English templates. WhatsApp templates can be configured per-language, so
173+ * Also, the WhatsApp sending logic only sends English templates. WhatsApp templates can be configured per-language, so
176174 you will most likely want to make the template sending logic configurable per-language.
177175 The handling code is located in the [ ` send_whatsapp ` ] ( lambda/send_whatsapp/main.py ) lambda.
178- * In the WhatsApp flow, if the user answers to the template message more than 2h after the template has been sent (and
179- therefore the initiating free-form message has already been automatically discarded) no extra communication is sent,
180- which can be confusing for users. Extra work should be done to improve the UX for these cases (maybe by sending a
176+ * In the WhatsApp flow, if the user answers to the template message more than 2h after the template has been sent (and
177+ therefore the initiating free-form message has already been automatically discarded) no extra communication is sent,
178+ which can be confusing for users. Extra work should be done to improve the UX for these cases (maybe by sending a
181179 specific message explaining that the original message has expired?).
182- * The solution only supports sending basic message types. WhatsApp supports a
180+ * The solution only supports sending basic message types. WhatsApp supports a
183181 [ wide variety of rich messages] ( https://developers.facebook.com/docs/whatsapp/cloud-api/guides/send-messages ) . The
184182 solution could be extended to support these different message types.
0 commit comments