Integrating WhatsApp Inbound Location Data into Twilio Studio Flow Using Conversations API

38 Views Asked by At

I'm working on retrieving inbound location data from WhatsApp messages in my Twilio Studio Flow, but I've encountered some issues as this functionality is not directly supported by the Conversations API without additional setup.

What I've Tried

I've managed to route WhatsApp sender messages through the Default Messaging Service for Conversations to a Twilio serverless function (/wa/webhook). This function parses the inbound location data, and uploads it as a geojson with the application/geo+json MIME-type using the media API, and adds the parsed message with the media sid to the conversation. For example:

{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [
      19.18691444397,
      -34.418468475342
    ]
  },
  "properties": {
    "address": "1 Taute Street, Hermanus, Western Cape 7200",
    "label": "Mountain View Manor Guesthouse"
  }
}

However, I'm facing an issue with the Studio webhook on the conversation. Depending on how I configure the participant and conversation, I encounter one of two scenarios when a single message is sent to the Twilio number:

  1. I get a set of {unparsed:inbound, parsed:inbound, outbound1, outbound2} messages in the conversation transcript. This scenario results from the unparsed and parsed messages interacting with the Studio Flow. (*Except for the initial message, which is not replayed in the illustration that follows, upon webhook creation)
  2. I get a set of {parsed:inbound, outbound} messages in the transcript, which is what I desire. However, in this case, the outbound message from the Studio Flow does not get sent back to the original sender via WhatsApp.

These outcomes vary based on how I configure the user as a participant, but neither achieves my goal. Here's a visualization of the issue:

Scenario visual

For example, using the address and addressProxy method as recommended by the documentation:

const participant = await client.conversations.v1
  .conversations(conversation.sid)
  .participants.create({
    xTwilioWebhookEnabled: 'true',
    'messagingBinding.address': event.From,
    'messagingBinding.proxyAddress': event.To,
    attributes: JSON.stringify({ ProfileName: event.ProfileName }),
  })

This configuration leads to the first scenario mentioned above, and illustrated below.

WhatsApp Chat 1

Conversation Transcript 1

Alternatively, using the identity configuration:

const participant = await client.conversations.v1
  .conversations(conversation.sid)
  .participants.create({
    xTwilioWebhookEnabled: 'true',
    identity: event.From,
    attributes: JSON.stringify({ ProfileName: event.ProfileName }),
  })

This leads to the second scenario initially mentioned, and again, illustrated below.

enter image description here

enter image description here

This setup results in the second scenario. My webhook configuration is as follows:

const webhook = await conversation.webhooks().create({
  target: 'studio',
  'configuration.filters': ['onMessageAdded'],
  'configuration.flowSid': context.FLOW_SID, 
})

I'm aiming for a setup where the parsed inbound messages correctly interact with the Studio Flow and outbound messages are sent back to the original sender. Any insights or suggestions on how to achieve this would be greatly appreciated.

P.S. Ideally I would prefer not to use the Incoming Message trigger as opposed to the Incoming Conversation, however I feel as though I may need to go in that direction and manually capture the replies on each outbound widget.

1

There are 1 best solutions below

0
Geoffrey Garrett On

I found a workaround which I'm happy with. I went with the first way of configuring participants and added a pre-event webhook for onMessageAdd to a serverless function containing:

export const handler: ServerlessFunctionSignature<
  TwilioContext,
  Event
> = async (context, event, callback) => {
  if (event.Source === 'WHATSAPP') {
    console.log('Filtering in pre-event')
    return callback('Filtering in pre-event', 400)
  } else {
    console.log('Not filtering in pre-event')
    return callback(null)
  }
}

The studio flow subsequently only reacts to my parsed/processed messaging sent from the API containing my inbound location data from WhatsApp, and only the parsed version is added to the conversation transcript.