Flex Conversations requires Flex UI 2.0. If you are on Flex UI 1.x, please refer to Chat and Messaging pages.
Connect your WhatsApp sender number to Flex Conversations by following one of the two approaches outlined below. For numbers already registered with WhatsApp, use the Create a WhatsApp address via Flex Console instructions. For numbers using the WhatsApp sandbox, use the Configuring WhatsApp Sandbox instructions.
In order to create a Conversations Address for WhatsApp, you need to have a WhatsApp sender registered on your Twilio account. This is unfortunately not a quick process and includes registration and vetting on the WhatsApp side. For testing using the WhatsApp Sandbox, see the next step. You can create a WhatsApp Conversations Address via the Flex Console or via the API.
To get started, navigate to Messaging > Senders > WhatsApp senders in the Twilio Console. The rest assumes you already have a registered WhatsApp number on your account.
You can create WhatsApp Addresses via Flex Console > Manage > Messaging:
You can optionally enter a friendly name.
You can edit or delete WhatsApp Addresses at any point using the Flex Console.
The Conversations API's Address Configuration Resource allows you to create and manage WhatsApp addresses for your Twilio account. On address creation, you can specify autocreation of a Conversation upon receipt of an inbound message. The following example shows you the programmatic version of our Console example with a retry count. To learn more about the different resource properties, see Address Configuration Resource.
1// Download the helper library from https://www.twilio.com/docs/node/install2const twilio = require("twilio"); // Or, for ESM: import twilio from "twilio";34// Find your Account SID and Auth Token at twilio.com/console5// and set the environment variables. See http://twil.io/secure6const accountSid = process.env.TWILIO_ACCOUNT_SID;7const authToken = process.env.TWILIO_AUTH_TOKEN;8const client = twilio(accountSid, authToken);910async function createConfigurationAddress() {11const addressConfiguration =12await client.conversations.v1.addressConfigurations.create({13address: "whatsapp:+13115552368",14"autoCreation.enabled": true,15"autoCreation.studioFlowSid": "FWXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",16"autoCreation.studioRetryCount": 3,17"autoCreation.type": "studio",18type: "whatsapp",19});2021console.log(addressConfiguration.sid);22}2324createConfigurationAddress();
1{2"account_sid": "ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",3"sid": "IGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",4"address": "whatsapp:+13115552368",5"type": "whatsapp",6"friendly_name": "My Test Configuration",7"address_country": "CA",8"auto_creation": {9"enabled": true,10"type": "webhook",11"conversation_service_sid": "ISaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",12"webhook_url": "https://example.com",13"webhook_method": "POST",14"webhook_filters": [15"onParticipantAdded",16"onMessageAdded"17]18},19"date_created": "2016-03-24T21:05:50Z",20"date_updated": "2016-03-24T21:05:50Z",21"url": "https://conversations.twilio.com/v1/Configuration/Addresses/IGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"22}
For deleting a WhatsApp address via the API, see Delete Address Configuration.
These instructions are for setting up WhatsApp Sandbox to work with Flex Conversations. If you have a registered WhatsApp number, refer to the instructions above rather than this section. Registered WhatsApp numbers are set up similarly to SMS.
Since we don't have auto-create support for WhatsApp Sandbox, we will need to intercept incoming messages to create Conversations. Create another function with the following code. This uses the same Studio Flow as the SMS instructions and has been tested on Node v12, v14, and v16 runtime:
Declare twilio as a dependency. This automatically imports related npm modules into your Function.
Set STUDIO_FLOW_SID
as an environment variable using the unique ID (prefixed by FW) of your newly created Studio Flow.
whatsapp.protected.js
1/* Handles WhatsApp messages by2* 1. Creating a conversation3* 2. Adding the participant that sent that message4* 3. Adding the message to the conversation5* If any of these fail, the conversation is deleted6*/7exports.handler = async function(context, event, callback) {8const isConfigured = context.STUDIO_FLOW_SID;9const response = new Twilio.Response();10response.appendHeader('Access-Control-Allow-Origin', '*');11response.appendHeader('Access-Control-Allow-Methods', 'GET,POST,OPTIONS');12response.appendHeader('Content-Type', 'application/json');13response.appendHeader('Access-Control-Allow-Headers', 'Content-Type');1415console.log(`Received Event: ${JSON.stringify(event)}`);1617if ( !isConfigured) {18response.setBody({19status: 500,20message: "Studio Flow SID is not configured"21});22callback(null, response);23return;24}2526const client = context.getTwilioClient();2728let conversation;29const webhookConfiguration = {30'target': 'studio',31'configuration.flowSid': context.STUDIO_FLOW_SID,32'configuration.replayAfter': 0,33'configuration.filters': ['onMessageAdded']34};3536try {37conversation = await client.conversations.v1.conversations.create({'xTwilioWebhookEnabled':true,});38console.log(`Created Conversation with sid ${conversation.sid}`);39try {40console.log(`Adding studio webhook to conversation ${conversation.sid}`);41await client.conversations.v1.conversations(conversation.sid)42.webhooks43.create(webhookConfiguration);44} catch(error) {45console.log(`Got error when configuring webhook ${error}`);46response.setStatusCode(500);47return callback(error, response);48}49} catch( error) {50console.log(`Couldnt create conversation ${error}`)51return callback(error)52}5354try {55const participant = await client.conversations.v1.conversations(conversation.sid)56.participants57.create({58'messagingBinding.address': `${event.From}`,59'messagingBinding.proxyAddress': `${event.To}`60});61console.log(`Added Participant successfully to conversation`)62} catch(error) {63console.log(`Failed to add Participant to conversation, ${error}`)64console.log(`In case the error is something about "A binding for this participant and proxy address already exists", check if you havent used the Sandbox in any other instance you have. As WhatsApp Sandbox uses the same number across all accounts, could be that the binding of [Your Phone] + [Sandbox WA number] is already created in the other instance.`)65try {66await client.conversations.v1.conversations(conversation.sid).remove();67console.log("Deleted conversation successfully")68} catch (error) {69console.log(`Failed to remove conversation, ${error}`)70}71return callback(null,"");72}7374// Now add the message to the conversation75try {76const body = event.Body !== '' ? event.Body : 'Empty body, maybe an attachment. Sorry this function doesnt support adding media to the conversation. This should work post private beta';77console.log(`Setting body to ${body}`)78const message = await client.conversations.v1.conversations(conversation.sid)79.messages80.create({81'author': `${event.From}`,82'body': `${body}`,83'xTwilioWebhookEnabled':true,84});85console.log(`Added message successfully to conversation`)86} catch(error) {87console.log(`Failed to add message to conversation, ${error}`)88try {89await client.conversations.v1.conversations(conversation.sid).remove();90} catch (error) {91console.log(`Failed to remove conversation, ${error}`)92}93return callback(null, `${error}`);94}9596return callback(null, "");97};
If you haven't registered your WhatsApp number in the sandbox, do that now by following the instructions in the WhatsApp Participants section. For example, in the case below, you would send "join cloud-forgot" to the number +1 415 523 8886 from your WhatsApp.
If everything has been configured correctly, this should render as an incoming WhatsApp task in your Flex application. Follow steps 1 and 2 of "Send your first SMS" to accept the incoming task and test WhatsApp in Flex.