VTAP allows you to build connectors to whatsapp service providers. There are different types of whatsapp APIs by various whatsapp partners. To let CRM connect to these and send/receive messages VTAP now supports Whatsapp connector which gives a framework to build extensions and provide all these capabilities.
Adding Whatsapp Connector
XML configuration
On adding the connector, a default XML template will be loaded which needs to be updated with the service details which we want to enable sending/receiving whatsapp messages.
Let’s go through each XML node from the top level.
Connector - This is the root node for all the configuration and for attribute will tell the type of connector.
Config - We need to take input from administrators to connect to external services like apikey, username, passwords etc. These configuration fields are added here under config > fields node with type attribute defining text type of fields.
These details will be used either in request as a header or part of a parameter or request body. To access these in other parts of xml we can use them with $config.$fields.appid.
The fields given here will appear in the Whatsapp > Settings > Add configuration page.
<config>
<fields>
<field name=”appid” type=”text” />
<field name=”apikey” type=”text” />
</fields>
</config>
Provider - To connect to any services you need to set an endpoint and other authentication details. These can be set under the provider node and we can input values from the administrator added in the config node here.
<provider>
<url> https://provider_url </url>
<auth>
<basic username="$config.$fields.username" password="$config.$fields.password"/>
</auth>
</provider>
Url - This is where you will put in your endpoint of whatsapp service.
Auth - If the service provider expects the secret details to be sent as basic authorization or bearer token then it can be done using the Auth node.
Basic - This is used to perform basic authorization.
Bearer - Use this if the service provider expects the key to be passed as bearer token.
Apikey - Use this if a token is to be passed in Authorization header.
message_send - After setting endpoints and configuration details we need to send a request to send a whatsapp message. For this we have sub components described below
message_send.request
request.template - use this to send template messages. This contains below sub components
<template>
<url>/messaging</url>
<headers>
<header name=”content-type” value=”application/json”></header>
<header name=”apikey” value=”$config.$fields.apikey”></header>
</headers>
<parameters raw-post-data="true">
<parameter name="to" value="@to" />
<parameter name="body" value="@message" />
<parameter name="notifyurl" value="@callback" />
</parameters>
</template>
request.text - use this when you want to send text message(within 24 hour session). These messages are send once you customer has responded back to the template messages or have initiated the conversation with the businesses.
text.url, text.headers and text.parameters follow the same conventions as template components.
<text>
<url>/messaging</url>
<parameters raw-post-data="true">
<parameter name="appid" value="$config.$fields.appid" />
<parameter name="deliverychannel" value="whatsapp" />
<parameter name="notifyurl" value="@callback"></parameter>
</parameters>
</text>
request.media - use this when you want to add an attachment with the message. Rest of the sub components follow the same conventions like template components. We should use this when all attachment types(pdf, image, video etc) are to be sent using the same api.
request.document - use this when api expects to send pdf attachments.
request.image - use this when api expects to send image attachments.
request.video - use this when api expects to send video attachments.
request.template_headerfooter - use this node when you have a header and footer with the text template message.
request.template_media - if the template message has an attachment, then use this xml node to define the endpoints and parameters.
request.template_cta - If the template message has Call-to-action buttons, then use this xml node. These message will have website and phone number buttons in them, including file.
request.template_cta_text - If the Call-to-action template message does not have attachment then use this.
request.template_qr - If the template message have quick reply buttons, then use this xml node. Use this when there is attachment along with the quick reply buttons.
request.template_qr_text - Use this when quick reply buttons does not have attachments with them.
Note : All the above xml nodes are used to define sending whatsapp messages and are defined inside message_send xml node.
message_send.response - We need to use the response of the message sent to update details like setting the status, unique id of message for later lookup on delivery status etc. Following nodes are useful to set the
response.message_to : set this if the response has the receiver's number of messages.
<response format="json">
<error use="error" />
<messages use="results" />
<message_id use="messageId" />
<message_status use="messageStatus" />
<message_to use="messageTo" />
</response>
message_send.callback - To get delivery callbacks of the message like delivered, read etc, we need to configure the status and message_id in the callback node.
<callback format="json">
<message_id use="messageid" />
<message_status use="messageStatus" />
</callback>
message_send.statuses - Use this to map the status value of the provider with Vtiger. Here “Submitted” value from the service provider is mapped to the Send status of Vtiger. Likewise the other statuses.
<statuses>
<!-- CONFIGURE : What is the success/failure status -->
<status Sent="Submitted" />
<status Queued="Queued" />
<status Delivered="delivered" />
<status Undelivered="failed" />
<status Sent="sent" />
<status Received="received" />
<status Read="Read" />
</statuses>
message_receive - This node lets you configure the incoming messages from the customer to the CRM.
message_receive.response - We need to capture information from the Incoming messages to assign it to associate to proper contact in CRM. Also incoming messages can have attachments which need to be created and linked. Following nodes needs to be mapped from response:
response.file_url - if a public file url is sent then use file_url with file_mime and file_name to map to type and name of the file.
<message_receive>
<response>
<message use="message" />
<from_number use="waid" />
<message_id use="tid" />
<attachments use="attachments" />
<file_content use=”file.content” />
<file_url use="url" />
<file_mime use="mime" />
</response>
</message_receive>
VTAP gives several dynamic data variable which can be used in the xml, see below list:
Connecting to Clickatell whatsapp account, and here is the link to their api documentation.
<?xml version='1.0'?>
<connector for="Whatsapp">
<config>
<fields>
<!-- CONFIGURE : Data fields that need to be captured from Whatsapp settings -->
<field name="apikey" label="API Key" type="text" required="true"/>
</fields>
</config>
<provider>
<!-- CONFIGURE : Provider URL -->
<url>https://platform.clickatell.com/v1</url>
</provider>
<message_send>
<request method="post">
<!-- CONFIGURE : Whatsapp send request end point -->
<url> /message </url>
<headers>
<header name="content-type" value="application/json" />
<header name="authorization" value="$config.$fields.apikey" />
</headers>
<text>
<url>/message</url>
<parameters raw-post-data="true">
<!-- CONFIGURE : name of From parameter and value -->
<parameter name="messages">
<values>
<parameter name="channel" value="whatsapp"></parameter>
<parameter name="to" value="@to"></parameter>
<parameter name="content" value="@message"></parameter>
</values>
</parameter>
</parameters>
</text>
<template>
<url> /message </url>
<parameters raw-post-data="true">
<!-- CONFIGURE : name of From parameter and value -->
<parameter name="messages">
<values>
<parameter name="channel" value="whatsapp"></parameter>
<parameter name="to" value="@to"></parameter>
<parameter name="template">
<parameter name="templateName" value="@template_name"></parameter>
<parameter name="body">
<parameter name="parameters" value="@template_params"></parameter>
</parameter>
</parameter>
</values>
</parameter>
</parameters>
</template>
<template_headerfooter>
<url> /message </url>
<parameters raw-post-data="true">
<!-- CONFIGURE : name of From parameter and value -->
<parameter name="messages">
<values>
<parameter name="channel" value="whatsapp"></parameter>
<parameter name="to" value="@to"></parameter>
<parameter name="template">
<parameter name="templateName" value="@template_name"></parameter>
<parameter name="body">
<parameter name="parameters" value="@template_params"></parameter>
</parameter>
</parameter>
</values>
</parameter>
</parameters>
</template_headerfooter>
<template_media>
<url> /message </url>
<parameters raw-post-data="true">
<!-- CONFIGURE : name of From parameter and value -->
<parameter name="messages">
<values>
<parameter name="channel" value="whatsapp"></parameter>
<parameter name="to" value="@to"></parameter>
<parameter name="template">
<parameter name="templateName" value="@template_name"></parameter>
<parameter name="header">
<parameter name="type" value="media"></parameter>
<parameter name="media">
<parameter name="fileId" value="@file_url"></parameter>
</parameter>
</parameter>
</parameter>
</values>
</parameter>
</parameters>
</template_media>
<template_cta>
<url> /message </url>
<parameters raw-post-data="true">
<!-- CONFIGURE : name of From parameter and value -->
<parameter name="messages">
<values>
<parameter name="channel" value="whatsapp"></parameter>
<parameter name="to" value="@to"></parameter>
<parameter name="template">
<parameter name="templateName" value="@template_name"></parameter>
<parameter name="header">
<parameter name="type" value="media"></parameter>
<parameter name="media">
<parameter name="fileId" value="$file_url"></parameter>
</parameter>
</parameter>
<parameter name="body">
<parameter name="parameters" value="@template_params"></parameter>
</parameter>
<parameter name="buttons">
<parameter name="websiteUrl">
<values>
<parameter name="listPosition" value="1"></parameter>
<parameter name="parameters">
<parameter name="1" value="@website_button_url"></parameter>
</parameter>
</values>
</parameter>
</parameter>
</parameter>
</values>
</parameter>
</parameters>
</template_cta>
<template_cta_text>
<url> /message </url>
<parameters raw-post-data="true">
<!-- CONFIGURE : name of From parameter and value -->
<parameter name="messages">
<values>
<parameter name="channel" value="whatsapp"></parameter>
<parameter name="to" value="@to"></parameter>
<parameter name="template">
<parameter name="templateName" value="@template_name"></parameter>
<parameter name="body">
<parameter name="parameters" value="@template_params"></parameter>
</parameter>
<parameter name="buttons">
<parameter name="websiteUrl">
<values>
<parameter name="listPosition" value="1"></parameter>
<parameter name="parameters">
<parameter name="1" value="@website_button_url"></parameter>
</parameter>
<parameter name="listPosition" value="2"></parameter>
<parameter name="parameters">
<parameter name="1" value="@phone_number"></parameter>
</parameter>
</values>
</parameter>
</parameter>
</parameter>
</values>
</parameter>
</parameters>
</template_cta_text>
<template_qr>
<url> /message </url>
<parameters raw-post-data="true">
<!-- CONFIGURE : name of From parameter and value -->
<parameter name="messages">
<values>
<parameter name="channel" value="whatsapp"></parameter>
<parameter name="to" value="@to"></parameter>
<parameter name="template">
<parameter name="templateName" value="@template_name"></parameter>
<parameter name="header">
<parameter name="type" value="media"></parameter>
<parameter name="media">
<parameter name="fileId" value="@file_url"></parameter>
</parameter>
</parameter>
<parameter name="body">
<parameter name="parameters" value="@template_params"></parameter>
</parameter>
<parameter name="items">
<values>
<parameter name="title" value="@button_text_1"></parameter>
<parameter name="postbackData" value="@button_text_1"></parameter>
</values>
<values>
<parameter name="title" value="@button_text_2"></parameter>
<parameter name="postbackData" value="@button_text_2"></parameter>
</values>
<values>
<parameter name="title" value="@button_text_3"></parameter>
<parameter name="postbackData" value="@button_text_3"></parameter>
</values>
</parameter>
</parameter>
</values>
</parameter>
</parameters>
</template_qr>
<template_qr_text>
<url> /message </url>
<parameters raw-post-data="true">
<!-- CONFIGURE : name of From parameter and value -->
<parameter name="messages">
<values>
<parameter name="channel" value="whatsapp"></parameter>
<parameter name="to" value="@to"></parameter>
<parameter name="template">
<parameter name="templateName" value="@template_name"></parameter>
<parameter name="body">
<parameter name="parameters" value="@template_params"></parameter>
</parameter>
<parameter name="items">
<values>
<parameter name="title" value="@button_text_1"></parameter>
<parameter name="postbackData" value="@button_text_1"></parameter>
</values>
<values>
<parameter name="title" value="@button_text_2"></parameter>
<parameter name="postbackData" value="@button_text_2"></parameter>
</values>
<values>
<parameter name="title" value="@button_text_3"></parameter>
<parameter name="postbackData" value="@button_text_3"></parameter>
</values>
</parameter>
</parameter>
</values>
</parameter>
</parameters>
</template_qr_text>
<media>
<url>/message</url>
<parameters raw-post-data="true">
<parameter name="messages">
<values>
<parameter name="channel" value="whatsapp"></parameter>
<parameter name="to" value="@to"></parameter>
<parameter name="content" value="@file_content"></parameter>
<parameter name="media">
<parameter name="contentType" value="@file_mime_type"></parameter>
<parameter name="caption" value="@file_name"></parameter>
</parameter>
</values>
</parameter>
</parameters>
</media>
</request>
<!-- CONFIGURE : type of message response json or xml -->
<response format="json">
<!-- CONFIGURE : response identifiers -->
<error use="messages.0.error.description" /> <!-- What is the error message identifier if request fails from service -->
<message_id use="messages.0.apiMessageId" />
<message_status use="messages.0.accepted" />
<message_to use="messages.0.to" />
</response>
<!-- INFO : Callback will be https://instance_url/modules/Whatsapp/callbacks/Custom.php -->
<callback format="json">
<!-- CONFIGURE : What is the message/status identifier in callback response -->
<message use="event" />
<message_id use="event.messageStatusUpdate.0.messageId" />
<message_status use="event.messageStatusUpdate.0.status" />
</callback>
<statuses>
<!-- CONFIGURE : What is the success/failure status -->
<status Sent="SENT_TO_SUPPLIER" />
<status Queued="1" />
<status Delivered="DEVICE_ACK" />
<status Undelivered="failed" />
<status Received="received" />
<status Read="READ" />
</statuses>
</message_send>
<message_receive>
<response>
<message use="event.moMedia.0.caption || event.moText.0.content" />
<to_number use="event.moMedia.0.to || event.moText.0.to || event.moLocation.0.to" />
<message_id use="event.moMedia.0.messageId || event.moText.0.messageId || event.moLocation.0.messageId" />
<from_number use="event.moMedia.0.from || event.moText.0.from || event.moLocation.0.from" />
<from_name use="event.moMedia.0.whatsapp.profileName || event.moText.0.whatsapp.profileName || event.moLocation.0,whatsapp.profileName" />
<file_mime use="event.moMedia.0.contentType" />
<file_name use="event.moMedia.0.caption" />
<file_content use="event.moMedia.0.content" />
</response>
</message_receive>
</connector>