WHATSAPP BOT

This bot provides an integration between the WhatsApp For Business and Teamwire messaging platforms, through the services provided by the 360Dialog MessagePipe platform.

In a typical usage scenario, a WhatsApp contact number is published on a company web site, for customers to initiate a conversation with e.g. a sales or support department. As soon as a WhatsApp user sends a message to the designated phone number, a chat is created in Teamwire with a predefined set of recipients. The recipient users in the Teamwire chat can then reply back by sending messages that are automatically relayed to the Whatsapp user.

The WhatsApp for Business platforms only allows the inbound creation of conversations, so it is not possible to send a message to a WhatsApp user if they did not intentionally start a conversation with us first.

As an additional limitation, the 360Dialog platform disallows sending messages to WhatsApp users after 24 hours since their last message. In other words, as soon as a WhatsApp user starts a conversation, a 24 hours "session" is created, during which it is possible to send free-form messages back to the contacting user. Every time the WhatsApp user sends a new message in that conversation, the session duration is prolonged by 24 hours again. After the session has elapsed, i.e. no new messages are received from WhatsApp in that conversation, it is only possible to contact the WhatsApp user with "template" messages, i.e. one between a set of predefined messages that are statically configured in the 360Dialog platform. For additional information on these limitations, please refer to the 360Dialog documentation.

WhatsApp Bot source code

Obtaining a 360Dialog account, API Key, and setting up a WhatsApp contact number

For using the WhatsApp bot integration you need a Facebook Business account, and a 360Dialog Partner account. Please contact support@360dialog.com for information about how to activate a partner account to access the 360Dialog platform.

Once the account is properly set up, you will register a user name and password for accessing the 360Dialog Client Hub dashboard, where you will need to create an API Key to be used for configuring the Teamwire WhatsApp bot.

Requirements

In order to run the bot you need the following requirements to be satisfied:

  • A working python installation
  • the Teamwire Python SDK installed in the system

Additionally you should install the bot dependencies with:

$ pip install -r requirements.txt

WhatsApp bot configuration file format

The bot is mainly configured through a JSON configuration file, with the following general format:

{
    "enabled_config": "0f093255-25fa-4588-ac7d-0862e7020adc",
    "configs": [
        {
            "key": "0f093255-25fa-4588-ac7d-0862e7020adc",
            "chat_title_prefix": "Whatsapp: ",
            "chat_avatar_path": "path/to/whatsapp-logo.png",
            "group_recipients": [
                {
                    "group_id": "group-1-id"
                },
                {
                    "title": "Group 2"
                }
            ],
            "user_recipients": [
                {
                    "first_name": "Firstname",
                    "last_name": "Lastname"
                },
                {
                    "user_id": "user-1-id"
                }
            ],
            "admins": [
                {
                    "first_name": "Firstname",
                    "last_name": "Lastname"
                }
            ]
        }
    ]
}

At the top level of the configuration dictionary we find two items:

  • configs: a list of available configurations
  • enabled_config: the key of the currently enabled configuration. This must match the key element of one of the configurations in the configs array. The enabled_config key can be omitted if the configs list only contains one item.

Each item of the configs array has the following properties:

  • key: a GUID, used to univocally identify this configuration
  • chat_title_prefix: the prefix of the title of each chat created by the bot. Such title will be in the form "{title_prefix} {user_name} ({phone})"
  • chat_avatar_path: the full path of a jpeg image file (600x600px) that will be used as avatar for the chats created by the bot
  • group_recipients: a list of circles in the form {"title": "<group title>"}, or {"group_id": "<group id>"}, which will be members of the created chats. NOTE: circles can be members of chats with bots, only if they are set as "public" circles in the Teamwire Admin dashboard
  • user_recipients: a list of users in the form {"first_name": "<first name>", "last_name": "<last name>"}, or {"user_id": "<user id>"}, which will be members of the created chats
  • admins: a list of users in the form {"first_name": "<first name>", "last_name": "<last name>"} that will be administrators of the created chats

WhatsApp bot environment variables

The bot credentials are passed to the bot through the following environment variables:

  • TW_API_APPID
  • TW_API_SECRET

These are obtained when creating the bot in the “App Integrations” panel of the Teamwire Admin Dashboard. Additionally, the WhatsApp bot requires the following environment variables:

  • TW_API_HOST: the teamwire backend URL (either cloud or on-premise)
  • WA_API_KEY: the 360Dialog API Key generated in the Client Hub dashboard

Other optional environment variables:

  • WA_USE_SANDBOX: (default False). If set to "True" the bot expects to use the 360Dialog sandbox API. See the next section for additional details
  • WA_NOTIFICATIONS_PORT: TCP port for the notifications web hook server - default: 8080
  • WA_NOTIFICATIONS_URL_PATH: public path of the notifications web hook - default: /whatsapp/notification
  • WA_BOT_CONFIG: path of the (JSON) configuration file to use - default: wa_config.json
  • WA_DB_FILE: path of the (automatically created) session-storage database file - default: whatsapp_bot.db

Getting WhatsApp notifications

The 360Dialog platform delivers messages and events through a notification mechanism based on web hooks (see the messaging API documentation for additional details). For such reason, the WhatsApp Bot implements an HTTP server that should be exposed publicly on the Internet, in order to receive notifications when the web hook is invoked.

Notifications web hook setup

The WhatsApp bot should be configured and deployed on an Internet accessible server. In particular, in order to receive notifications about new incoming WhatsApp messages, the bot implements a custom web-hook that needs to be properly configured on the 360Dialog backend. In an ideal deployment, the bot should run behind a reverse proxy (e.g. nginx), configured to pass incoming requests for the notifications web-hook URL to the internal web server exposed by the bot.

For this, a simple proxy-pass rule can be added to the nginx configuration:

location /whatsapp/notification {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_pass http://localhost:8081;
}

Supposing that the bot server is reachable at the example.com address, and that the exposed web hook URL is https://example.com/whatsapp/notification, this can be configured in the 360Dialog service by performing the following POST request:

curl --request POST \
--url https://waba.messagepipe.io/v1/configs/webhook \
--header "D360-Api-Key: <YOUR-360-API-KEY>" \
--header "Content-Type: application/json"   \
--data '{"url": “https://example.com/whatsapp/notification”}'

where is the API key generated in the 360Dialog dashboard. Additional information can be found in 360Dialog API documentation: https://docs.360dialog.com/whatsapp-api/whatsapp-api/webhook.

NOTE: in case you are using a 360Dialog sandbox environment (see next section), the above "curl" command should be directed to the

https://waba-sandbox.messagepipe.io/v1/configs/webhook

URL.

In case the path location, or the TCP port used internally would need to be different than the default ones, they can be changed by properly setting the WA_NOTIFICATIONS_URL_PATH and WA_NOTIFICATIONS_PORT environment variables when running the bot.

Using a 360Dialog sandbox environment

In alternative to the normal setup workflow, it’s possible to use a simplified environment for testing purposes, using the "sandbox" backend provided by 360Dialog. In this scenario, there is no need to register a WhatsApp for Business and 360Dialog accounts for using the service. A D360-API-KEY can be obtained by simply sending a WhatsApp message with the text “START” to the 360Dialog phone number +4930609859535 , which will automatically respond with a message like the following: “Your new api-key is: "abcdeFGH_sandbox". Now you can follow the instructions from our docs!”. Using the API key provided in the message it is possible to set up the notifications web hook, as described in previous sections, and to use it for setting the WA_API_KEY required to start a bot instance. When using the sandbox, only the WhatsApp user that initially sent the “START” message can exchange messages with the sandbox environment, and the number of messages that 360Dialog API can send back in response is limited to 10. The documentation at the url https://docs.360dialog.com/whatsapp-api/whatsapp-api/sandbox contains additional information.

Running the bot

In order to start the bot you simply have to run:

    $ python whatsapp-bot.py

Please ensure that the bot credentials environment variables are correctly set:

  • TW_API_APPID
  • TW_API_SECRET
  • TW_API_HOST
  • WA_API_KEY

Running the bot with Docker

If you are Teamwire Partner, you can request access to the Teamwire's Harbor Registry where you can find a standard image of the WhatsApp bot to be directly deployed in your own staging or production environment. Please contact support@teamwire.eu for additional information about how to get access to Teamwire Teamwire's Harbor Registry.

Provided that the above requirement is met, you can get the WhatsApp bot image with:

$ docker pull harbor.teamwire.eu/bots/whatsapp-bot:1.6.0

then you can launch it with:

docker run -d --restart always --network host --name whatsapp-bot    \
    -e TW_API_APPID="<YOUR APP ID>"  \
    -e TW_API_SECRET="<YOUR API SECRET>" \
    -e TW_API_HOST="https://backend.teamwire.eu" \
    -e WA_API_KEY="<YOUR 360Dialog API KEY>" \
    -e WA_BOT_CONFIG="/wa_storage/wa_config.json" \
    -e WA_DB_FILE="/wa_storage/whatsapp_bot.db" \
    -e WA_NOTIFICATIONS_PORT=8080   \
    -e WA_NOTIFICATIONS_URL_PATH="/whatsapp/notification" \
    -e PYTHONIOENCODING=utf-8 \
    -v /path/to/your/storage/dir:/wa_storage \
    harbor.teamwire.eu/bots/whatsapp-bot:1.6.0

The above docker run command creates a new container named whatsapp-bot and passes to it all the required environment variables. In particular, the bot's web server will listen on TCP port 8080, exposed at the URL path /whatsapp/notification. In order to make a custom configuration file available to the bot, a container volume is set, mounting the /path/to/your/storage/dir external directory to the internal /wa_storage directory. The WA_BOT_CONFIG environment variable ensures that the configuration file is loaded from the volume. Similarly, the sessions database will be stored in the same directory in the whatsapp_bot.dbfile, as specified by the WA_DB_FILE variable.

Creating a Docker image for the bot

NOTE: this is needed only in case you want to build your own Docker image for the bot, e.g. because you want to run your own customised version of it. In case you simply want to run the standard Docker image provided by Teamwire, please refer to the previous section.

To build a Docker image for the bot you need access to the Teamwire SDK docker image named bots/sdk-base which is available for Teamwire Partners on Teamwire's Harbor Registry.

Provided that the above requisite is met, the Docker image for the bot can be created with:

$ docker build --rm -t teamwire/whatsapp-bot -f Dockerfile .

This will create the teamwire/whatsapp-bot Docker image that can then be deployed in a Docker environment, like detailed in the previous section.

For example:

docker run -d --restart always --network host --name whatsapp-bot    \
    -e TW_API_APPID="<YOUR APP ID>"  \
    -e TW_API_SECRET="<YOUR API SECRET>" \
    -e TW_API_HOST="https://backend.teamwire.eu" \
    -e WA_API_KEY="<YOUR 360Dialog API KEY>" \
    -e WA_BOT_CONFIG="/wa_storage/wa_config.json" \
    -e WA_DB_FILE="/wa_storage/whatsapp_bot.db" \
    -e WA_NOTIFICATIONS_PORT=8081   \
    -e WA_NOTIFICATIONS_URL_PATH="/whatsapp/notification" \
    -e PYTHONIOENCODING=utf-8 \
    -v /path/to/your/storage/dir:/wa_storage \
    teamwire/whatsapp-bot

Bot usage description

Once the bot is properly configured and deployed it will listen forever for notifications of messages sent to the contact WhatsApp number.

As soon as a new conversation is created by a whatsapp user writing to the inbound contact number, the bot will check if an existing chat has already been created for a conversation with the sender WhatsApp number. If none is found, a new Teamwire chat is created with the recipients specified in the active bot configuration. The teamwire recipients will receive a message containing the original whatsapp message body, to which they can reply. Any message sent to the Teamwire chat will be relayed back to the WhatsApp user, except for messages starting with the "/" character, which are interpreted as commands.

/help command

In order to retrieve a list of possible commands, please send the "/help" message. The bot will reply with the following message:

Whatsapp Bot

Available commands:
/help: list supported commands
/info: reports information about the current whatsapp conversation
/templates: list the available template messages
/send <template index>: send the specified template message
Note: any non-command message is relayed to the whatsapp user

/info command

For each conversation, the bot will store the relevant information and status in a persistent database (see the WA_DB_FILE environment variable discussed in previous sections). In order to get up to date information about the current conversation you can use the "/info" command. The bot will reply with a message like the following:

Whatsapp Bot

Conversation info:
Started at: 22/04/2020, 14:18:02
By WhatsApp user: Tobias
Phone number: +496813***978
Last message received: 22/04/2020, 14:18:02
Last message sent: 22/04/2020, 14:29:39
Conversation active: Yes

Note: a WhatsApp conversation is active for 24 hours after the last message sent from the WhatsApp user has been received. During that
time all messages sent to this chat are normally relayed to the WhatsApp user. After the 24hrs timeout is expired, only template
messages >can be sent.

As described, the WhatsApp user can be contacted only within a 24 hours period after their last message. During such time, the conversation is considered as "active", and such state is reported in the result of the "/info" command.

Among the other relevant information reported we find the time when the conversation has been started, the time of the last received message and of the last sent message, as well as the display name of the WhatsApp user and phone number in redacted form.

/templates command

If the conversation session is timed out, i.e. more than 24 hours have elapsed since the last WhatsApp message was received, only predefined "template" messages can be sent to the WhastApp user. In order to get a list of available template messages that can be sent, we can use the "/templates" command. The bot will reply with a message like the following:

Available template messages:

1. Your message reached us while we were not available, may we contact you concerning your question again? If so, please reply to this message with YES.

The above is the default template message configured by 360Dialog.

/send command

In order to send a specific template message, we can use the "/send" command, followed by the index of the selected template from the list of available templates retrieved with the "/templates" command.

The bot will respond with an affirmative or negative confirmation about the result of the operation.