View Categories

Integrating WhatsApp Flows with Dialogflow

2 min read

Dialogflow (Google Cloud) can act as the intelligence layer behind your WhatsApp Flows — processing submitted data, deciding the next action, and sending a tailored follow-up message. This article walks through two integration modes and provides working code examples.

Integration architecture overview #

Customer submits Flow
        ↓
WhatsApp Cloud API
        ↓
Baat webhook receiver
        ↓
  [ two paths ]

Path A — Post-submit (async):
  Baat stores data → Journey Builder triggers → calls Dialogflow webhook → sends reply

Path B — data_exchange (sync, during Flow):
  Flow calls your endpoint directly → your server calls Dialogflow → returns dynamic screen data

Path A — Post-submit async integration #

This is the simpler and more common path. The Flow completes, Baat receives the submission via webhook, and Journey Builder triggers a follow-up step that calls your Dialogflow agent.

1. Set up a Dialogflow webhook endpoint #

Create an HTTPS endpoint that accepts a POST request from Baat’s Journey Builder. Here is a minimal Node.js (Express) example:

const express = require('express');
const { SessionsClient } = require('@google-cloud/dialogflow');

const app = express();
app.use(express.json());

const client = new SessionsClient();
const projectId = 'your-dialogflow-project-id';

app.post('/dialogflow-webhook', async (req, res) => {
  const { contact_phone, flow_response } = req.body;
  // flow_response contains the submitted Flow fields as key-value pairs

  const sessionPath = client.projectAgentSessionPath(
    projectId,
    contact_phone.replace('+', '')
  );

  const request = {
    session: sessionPath,
    queryInput: {
      text: {
        text: JSON.stringify(flow_response),
        languageCode: 'en-IN',
      },
    },
  };

  const [response] = await client.detectIntent(request);
  const fulfillmentText = response.queryResult.fulfillmentText;

  // Return the reply Baat should send back to the customer
  res.json({ reply: fulfillmentText });
});

app.listen(3000);

2. Configure the Journey Builder step #

  1. In Baat, open your Journey and add a Webhook step after the Flow trigger
  2. Set the URL to your endpoint (e.g. https://your-server.com/dialogflow-webhook)
  3. Map Flow response fields to the payload: contact_phone{{contact.phone}}, flow_response{{flow.response}}
  4. Add a Send Message step after the webhook using {{webhook.reply}} as the message body

Path B — data_exchange sync integration #

Use this when you need to return dynamic data to the Flow while the customer is still in it — for example, fetching available appointment slots based on the selected date.

Flow JSON with data_exchange #

{
  "type": "Footer",
  "label": "Check slots",
  "on-click-action": {
    "name": "data_exchange",
    "payload": {
      "selected_date": "${form.appointment_date}",
      "service": "${form.service_type}"
    }
  }
}

Endpoint that handles the data_exchange call #

Meta calls your endpoint directly (not via Baat) with the payload the customer submitted. Your server must respond within 10 seconds with updated screen data.

app.post('/flow-exchange', async (req, res) => {
  const { screen, data, flow_token, version } = req.body;

  if (screen === 'SCREEN_1') {
    const { selected_date, service } = data;

    // Fetch available slots from your booking system
    const slots = await getAvailableSlots(selected_date, service);

    res.json({
      screen: 'SCREEN_2',
      data: {
        available_slots: slots.map(s => ({
          id: s.id,
          title: s.label   // e.g. "10:00 AM", "2:00 PM"
        }))
      }
    });
  }
});
Security: Meta signs data_exchange requests using your Flow’s private_key and the payload is AES-encrypted. You must decrypt the payload and verify the signature before processing. See Meta’s Flows documentation for the decryption helper code.

Dialogflow intent for Flow data #

Create a Dialogflow intent that handles the JSON text you send as the query. Use a fulfillment webhook on the intent to process the structured data and return a personalised response.

// Fulfillment webhook response format (Dialogflow v2)
{
  "fulfillmentMessages": [
    {
      "text": {
        "text": [
          "Thanks Priya! Your appointment for Spa Treatment on 15 June at 10:00 AM is confirmed. We'll send you a reminder the day before."
        ]
      }
    }
  ],
  "outputContexts": [
    {
      "name": "projects/your-project/agent/sessions/SESSION_ID/contexts/booking-confirmed",
      "lifespanCount": 2,
      "parameters": {
        "service": "spa",
        "date": "2024-06-15",
        "slot": "10:00"
      }
    }
  ]
}

End-to-end flow example #

  1. Customer receives template message: “Book your appointment — tap below”
  2. Customer taps the Flow button → sees booking form → selects Spa, 15 June
  3. Customer taps “Check slots” → data_exchange fires → your server returns available times
  4. Customer selects 10:00 AM and submits → Flow closes
  5. Baat receives the webhook with response_json containing all submitted fields
  6. Journey Builder fires → calls your Dialogflow webhook endpoint with the data
  7. Dialogflow returns a confirmation message
  8. Baat sends the message to the customer: “Your Spa appointment on 15 June at 10:00 AM is confirmed ✅”
Next step: See WhatsApp Flows — Use Cases for ready-to-use Flow configurations for appointment booking, lead qualification, surveys, and more.