WhatsApp Business API | Integration with Rasa
Hi there!
In this tutorial, you will learn to enable WhatsApp communication on a simple Rasa assistant with the tyntec Conversations API. This integration allows your assistant to receive WhatsApp text messages and reply to them with ease.
You will need
-
- Your tyntec API key from your tyntec account
-
- Your WABA phone number that has been assigned to you by tyntec
-
- A mobile phone with WhatsApp installed that’s not associated with your WABA
-
- Rasa Open Source installed
-
- Your favorite text editor or IDE with Python and YAML highlighting
-
- An ngrok account and the binary installed
-
- Postman installed
Step One: Create an assistant
Let’s create artificial intelligence! This step is optional if you are starting with Rasa Open Source. Continue with step 2 if you already have your Assistant.
- Create a new project with an initial model by running the following command:
$ rasa init
Welcome to Rasa! 🤖
To get started quickly, an initial project will be created.
If you need some help, check out the documentation at https://rasa.com/docs/rasa.
Now let's start! 👇🏽
? Please enter a path where the project will be created [default: current directory] ./my-great-assistant
? Path './my-great-assistant' does not exist 🧐. Create path? Yes
Created project directory at '/home/john-doe/my-great-assistant'.
Finished creating project structure.
? Do you want to train an initial model? 💪🏽 Yes
Training an initial model...
The configuration for pipeline and policies was chosen automatically. It was written into the config file at './my-great-assistant/config.yml'.
Training NLU model...
[...]
NLU model training completed.
Training Core model...
[...]
Core model training completed.
Your Rasa model is trained and saved at '/home/john-doe/my-great-assistant/models/20210930-155824.tar.gz'.
? Do you want to speak to the trained assistant on the command line? 🤖 No
Ok 👍🏼. If you want to speak to the assistant, run 'rasa shell' at any time inside the project directory.
2. Change your current working directory:
$ cd my-great-assistant
You’ve created an assistant that automatically handles interactions.
Step Two: Add a WhatsApp connector
In this step, you connect the assistant to the tyntec Conversations API with a custom channel connector. The connector can process incoming WhatsApp messages, pass them to your assistant, and reply on WhatsApp.
1. Create a file addons/tyntec.py with the following content:
import json
import logging
import rasa.core.channels.channel
import requests
import sanic
import sanic.response
def _compose_tyntec_send_whatsapp_text_request(apikey, from_, to, text):
return requests.Request(
method="POST",
url="https://api.tyntec.com/conversations/v3/messages",
headers={
"Accept": "application/json",
"apikey": apikey},
json={
"from": from_,
"to": to,
"channel": "whatsapp",
"content": {
"contentType": "text",
"text": text}})
def _parse_tyntec_webhook_request(body):
try:
id_ = body["messageId"]
event = body["event"]
from_ = body["from"]
channel = body["channel"]
content_type = body["content"]["contentType"]
content_text = body["content"]["text"]
except KeyError:
raise ValueError("body not a tyntec WhatsApp text message event")
if event != "MoMessage" or channel != "whatsapp" or content_type != "text":
raise ValueError("body not a WhatsApp text message event")
return _TyntecWhatsAppTextMessage(id_, from_, content_text)
class _TyntecWhatsAppTextMessage:
def __init__(self, id_, from_, text):
self.id = id_
self.from_ = from_
self.text = text
class TyntecInputChannel(rasa.core.channels.channel.InputChannel):
def __init__(self, waba, tyntec_apikey, requests_session=None):
if requests_session is None:
requests_session = requests.Session()
self.requests_session = requests_session
self.tyntec_apikey = tyntec_apikey
self.waba = waba
@classmethod
def from_credentials(cls, credentials):
return cls(credentials["waba"], credentials["apikey"])
@classmethod
def name(cls):
return "tyntec"
def blueprint(self, on_new_message):
custom_webhook = sanic.Blueprint("tyntec")
@custom_webhook.route("/", methods=["GET"])
async def health(request):
return sanic.response.json({"status": "ok"})
@custom_webhook.route("/webhook", methods=["POST"])
async def receive(request):
try:
text_message = _parse_tyntec_webhook_request(request.json)
except ValueError:
request_json = json.dumps(request.json)
logging.warning(f"Unsupported event skipped: {request_json}")
return sanic.response.text(f"Unsupported event skipped: {request_json}")
await on_new_message(
rasa.core.channels.channel.UserMessage(
text_message.text,
TyntecOutputChannel(self.waba, self.tyntec_apikey, self.requests_session),
text_message.from_,
input_channel=self.name(),
message_id=text_message.id))
return sanic.response.text("OK")
return custom_webhook
class TyntecOutputChannel(rasa.core.channels.channel.OutputChannel):
def __init__(self, waba, tyntec_apikey, requests_session):
self.requests_session = requests_session
self.tyntec_apikey = tyntec_apikey
self.waba = waba
@classmethod
def name(cls):
return "tyntec"
async def send_text_message(self, recipient_id, text, **kwargs):
request = _compose_tyntec_send_whatsapp_text_request(self.tyntec_apikey, self.waba, recipient_id, text)
prepared_request = request.prepare()
response = self.requests_session.send(prepared_request)
response.raise_for_status()
Step Three: Configure and run the assistant
Now, you will configure and run the assistant.
1. Add the following associative array entry to the credentials.yml file and replace WABA with your WABA phone number and APIKEY with your tyntec API key:
addons.tyntec.TyntecInputChannel:
waba: "WABA" # replace WABA with your WABA phone number
apikey: "APIKEY" # replace APIKEY with your tyntec API key
2. Start the assistant:
$ rasa run
3. Create a publicly accessible URL using ngrok in another terminal:
$ path/to/ngrok http 5005
4. Copy the displayed public URL (such as https://843fc8776770.ngrok.io).
Note: This setup is suitable only for development. For production use, follow the official documentation “Deploy Your Rasa Assistant” to deploy your assistant. It includes methods such as Helm charts, deploying your Kubernetes cluster, or Docker Compose.
Step Four: Let the Conversations API know about your assistant
Let the tyntec Conversations API know where to deliver WhatsApp messages from your customers or users. You’re going to subscribe to the assistant’s webhook via an API call in Postman.
1. From the api-collection/conversations/v3 directory, import the Conversations V3.5.postman_collection.json into Postman.
2. Authorize Postman with your tyntec API key and your WABA phone number. Right-click the collection and select Edit. Then go to Variables and set the apikey variable to your tyntec API key. Also, set the whatsAppBusinessNumber variable to your WABA phone number.
3. Let’s set up a webhook! Open the WhatsApp folder. Inside, open the Configurations folder and select the Configure the callback for a specific number request and change the inboundMessageUrl in the body to the assistant’s /webhooks/tyntec/webhook endpoint URL (for example, https://843fc8776770.ngrok.io/webhooks/tyntec/webhook). This request will subscribe the URL to incoming message events.
4. Hit the Send button. You should receive a 2xx status in the response if everything is okay.
Cool! Now the Conversations API knows where to deliver WhatsApp messages from your customers.
Step Five: Test your assistant
Nothing more is needed to publish your assistant through WhatsApp. Now you can test it!
1. From your test device with WhatsApp installed, write a message to your WhatsApp Business Account Number and wait for the Rasa assistant’s response.
Cool! Your Rasa assistant can now talk with anyone on WhatsApp!
More?
Utilizing Rasa’s platform you can make your assistant smarter. Look at the official Handle Business Logic tutorial and level up your assistant. For example, you may want the assistant to collect specific information such as customer phone numbers.
By overriding the TyntecOutputChannel’s methods (for example, send_image_url or send_attachment), your assistant can reply with a snappy meme using an image message or with a funny cat video using a video message. Moreover, you send replies with buttons in cooperation with WhatsApp interactive messages. Look at the documentation of the TyntecOutputChannel’s base class OutputChannel for more information about all the methods that can be overridden.
If you want to protect the assistant’s /webhooks/tyntec/webhook endpoint against unauthorized messages, you can register the webhook with a custom header containing a bearer token. Then, you check the request headers in the blueprint’s receive function before parsing the request body and throw an error response if the request does not include the token.
Once you have built an assistant that can handle the most important happy path stories, you can use a Rasa X tool to improve your assistant. It can help you to listen to your users and use those insights to improve your AI.