Webhooks

Webhooks are services that host your business logic. During a session, webhooks allow you to use the data extracted by Dialogflow's natural language processing to generate dynamic responses, validate collected data, or trigger actions on the backend.

CX webhooks are similar to ES webhooks, except that request and response fields have been changed to support CX features.

Webhook service requirements

The following requirements must be met by your webhook service:

Authentication

It's important to secure your webhook service, so that only you or your Dialogflow agent are authorized to make requests. This is configured when creating a webhook resource. Dialogflow CX supports the following mechanisms for authentication:

Term Definition
Login username and password For webhook settings, you can specify optional login username and password values. If supplied, Dialogflow adds an authorization HTTP header to webhook requests. This header is of the form: "authorization: Basic <base 64 encoding of the string username:password>".
Authentication headers For webhook settings, you can specify optional HTTP header key-value pairs. If supplied, Dialogflow adds these HTTP headers to webhook requests. It is common to provide a single pair with a key of authorization. The header values support session parameter references and system function parsing like in static response messages.
Cloud Functions built-in authentication You can use the built-in authentication when using Cloud Functions. In order to use this type of authentication, do not supply login username, login password, or authorization headers. If you do supply any of these fields, these fields will be used for authentication rather than the built-in authentication.
Service identity tokens You can use service identity tokens for authentication. If you do not supply login username, login password, or a header with a key of authorization, Dialogflow automatically assumes that service identity tokens should be used and adds an authorization HTTP header to webhook requests. This header is of the form: "authorization: Bearer <identity token>".
Mutual TLS authentication See the Mutual TLS authentication documentation.

HTTPS certificate verification

Dialogflow by default uses Google's default trust store to verify HTTPS certificates. If you intend to use certificates not recognized by Google's default trust store for your HTTPS server, such as self-signed certificates or custom root certificates, please refer to Custom CA certificates.

Webhook request

When a fulfillment with a webhook is called, Dialogflow sends an HTTPS POST webhook request to your webhook service. The body of this request is a WebhookRequest JSON object with information about the matched intent.

Some integrations populate the WebhookRequest.payload field with additional information. For example, the Dialogflow CX phone gateway integration provides the end-user caller ID.

See the WebhookRequest(V3) or WebhookRequest(V3Beta1) reference documentation for details.

Webhook response

Once your webhook service receives a webhook request, it needs to send a webhook response. The following limitations apply to your response:

  • The response must occur within a timeout that you configure when creating the webhook resource, otherwise the request will time out.
  • The response must be less than or equal to 64 KiB in size.

See the WebhookResponse(V3) or WebhookResponse(V3Beta1) reference documentation for details.

Webhook resource settings

The following describes webhook resource settings:

Term Definition
Display name The name shown in the console for the webhook.
Webhook timeout When Dialogflow sends a webhook request to your webhook service, it may timeout while waiting for a response. This setting controls that timeout in seconds. If a timeout occurs, Dialogflow invokes a webhook.error.timeout event.
Type Set to Service directory if you are using service directory for private network access, otherwise set to Generic web service.
Webhook URL Provide the URL address for your webhook service.
Environment-specific webhook You can provide environment-specific webhooks.
Authentication See the authentication section.
Custom CA certificate This is used to upload custom CA certificates.

Environment-specific webhooks

If you are using environments to isolate production systems from development systems (recommended), you can configure your webhooks to be environment-specific. For each webhook resource you define, you can provide unique URL and authentication settings for each environment that you have defined for the agent.

This allows you to safely develop and test your webhook code updates before deploying them to production.

Create or edit webhook resources

Once you have a webhook service running, you need to create a webhook resource in your agent that has connectivity and authentication information. After creation, you can also edit webhook resource settings at any time.

To create or edit a webhook resource:

Console

  1. Open the Dialogflow CX Console.
  2. Choose your GCP project.
  3. Select your agent.
  4. Select the Manage tab.
  5. Click Webhooks.
  6. Click Create or click a webhook resource in the list to edit.
  7. Enter webhook resource settings.
  8. Click Save.

API

To create a webhook resource, see the create method for the Webhook type. To edit a webhook resource (except for environment-specific settings), see the patch or update method for the Webhook type.

Select a protocol and version for the Webhook reference:

Protocol V3 V3beta1
REST Webhook resource Webhook resource
RPC Webhook interface Webhook interface
C++ WebhooksClient Not available
C# WebhooksClient Not available
Go WebhooksClient Not available
Java WebhooksClient WebhooksClient
Node.js WebhooksClient WebhooksClient
PHP Not available Not available
Python WebhooksClient WebhooksClient
Ruby Not available Not available

To edit the environment-specific settings for a webhook, see the patch or update method for the Environment type.

Select a protocol and version for the Environment reference:

Protocol V3 V3beta1
REST Environment resource Environment resource
RPC Environment interface Environment interface
C++ EnvironmentsClient Not available
C# EnvironmentsClient Not available
Go EnvironmentsClient Not available
Java EnvironmentsClient EnvironmentsClient
Node.js EnvironmentsClient EnvironmentsClient
PHP Not available Not available
Python EnvironmentsClient EnvironmentsClient
Ruby Not available Not available

Webhook errors

If your webhook service encounters an error while handling a webhook request, your webhook code should return one of the following HTTP status codes:

  • 400 Bad Request
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not found
  • 500 Server fault
  • 503 Service Unavailable

In any of the following error situations, Dialogflow invokes a webhook error or timeout built-in event and continues processing as usual:

  • Response timeout exceeded.
  • Error status code received.
  • Response is invalid.
  • Webhook service is unavailable.

In addition, if the webhook service call was triggered by a detect intent API call, the queryResult.webhookStatuses field in the detect intent response contains the webhook status information.

Using Cloud Functions

Dialogflow integrates with Cloud Functions, so you can easily create a secure, serverless webhook. If you create a function that resides in the same project as your agent, your agent can securely call your webhook without needing any special configuration.

However, there are two situations in which you must manually setup this integration:

  1. The Dialogflow Service Agent service account with the following address must exist for your agent project:
    service-agent-project-number@gcp-sa-dialogflow.iam.gserviceaccount.com
    This special service account and the associated key is normally created automatically when you create the first agent for a project. If your agent was created before November 01, 2020, you may trigger creation of this special service account:
    1. Create a new agent for the project.
    2. Execute the following command:
      gcloud beta services identity create --service=dialogflow.googleapis.com --project=agent-project-id
  2. If your webhook function resides in a different project than the agent, you must provide the Cloud Functions Invoker IAM role to the Dialogflow Service Agent service account in your function's project.

Using Service Directory for private network access

Dialogflow integrates with Service Directory private network access, so it can connect to webhook targets inside your VPC network. This keeps the traffic within the Google Cloud network and enforces IAM and VPC Service Controls.

To set up a webhook targeting a private network:

  1. Follow Service Directory private network configuration to configure your VPC network and Service Directory endpoint.

  2. The Dialogflow Service Agent service account with the following address must exist for your agent project:

    service-agent-project-number@gcp-sa-dialogflow.iam.gserviceaccount.com
    Grant the Dialogflow Service Agent service account the following IAM roles:

    • servicedirectory.viewer of the Service Directory project
    • servicedirectory.pscAuthorizedService of the network project
  3. Provide Service Directory Service along with the URL and optional authentication information when creating the webhook.

    Console

    Service Directory Webhook screenshot.

    API

    See the serviceDirectory field for the Webhook type.

    Select a protocol and version for the Webhook reference:

    Protocol V3 V3beta1
    REST Webhook resource Webhook resource
    RPC Webhook interface Webhook interface
    C++ WebhooksClient Not available
    C# WebhooksClient Not available
    Go WebhooksClient Not available
    Java WebhooksClient WebhooksClient
    Node.js WebhooksClient WebhooksClient
    PHP Not available Not available
    Python WebhooksClient WebhooksClient
    Ruby Not available Not available

Service identity tokens

When Dialogflow calls a webhook, it provides a Google identity token with the request. Any webhook can optionally validate the token using Google client libraries or open source libraries like github.com/googleapis/google-auth-library-nodejs. For example, you can verify the email of the ID token as:

service-agent-project-number@gcp-sa-dialogflow.iam.gserviceaccount.com

Samples

The following samples show how to receive a WebhookRequest and send a WebhookResponse.

Go

See the Webhooks quick start.

Java


// TODO: Change class name to Example
// TODO: add GSON dependency to Pom file
// (https://mvnrepository.com/artifact/com.google.code.gson/gson/2.8.5)
// TODO: Uncomment the line bellow before running cloud function
// package com.example;

import com.google.cloud.functions.HttpFunction;
import com.google.cloud.functions.HttpRequest;
import com.google.cloud.functions.HttpResponse;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.BufferedWriter;

public class BasicWebhook implements HttpFunction {
  @Override
  public void service(HttpRequest request, HttpResponse response) throws Exception {
    JsonParser parser = new JsonParser();
    Gson gson = new GsonBuilder().create();
    JsonObject parsedRequest = gson.fromJson(request.getReader(), JsonObject.class);

    // For more information on the structure of this object https://cloud.google.com/dialogflow/cx/docs/reference/rest/v3/Fulfillment
    String requestTag = parsedRequest.getAsJsonObject("fulfillmentInfo")
        .getAsJsonPrimitive("tag").toString();
    JsonObject responseObject = null;
    String defaultIntent = "\"Default Welcome Intent\"";
    String secondIntent = "\"get-agent-name\"";
    String responseText = "";

    // Compares the Intent Tag to provide the correct response 
    if (requestTag.equals(defaultIntent)) {
      responseText = "\"Hello from a Java GCF Webhook\"";
    } else if (requestTag.equals(secondIntent)) {
      responseText = "\"My name is Flowhook\"";
    } else {
      responseText = "\"Sorry I didn't get that\"";
    }

    // Constructing the response jsonObject 
    responseObject =
        parser
            .parse(
                "{ \"fulfillment_response\": { \"messages\": [ { \"text\": { \"text\": ["
                    + responseText
                    + "] } } ] } }")
            .getAsJsonObject();
    BufferedWriter writer = response.getWriter();

    //Sends the responseObject
    writer.write(responseObject.toString());
  }
}

Node.js


exports.handleWebhook = (request, response) => {
  const tag = request.body.fulfillmentInfo.tag;
  let text = '';

  if (tag === 'Default Welcome Intent') {
    text = 'Hello from a GCF Webhook';
  } else if (tag === 'get-name') {
    text = 'My name is Flowhook';
  } else {
    text = `There are no fulfillment responses defined for "${tag}"" tag`;
  }

  const jsonResponse = {
    fulfillment_response: {
      messages: [
        {
          text: {
            //fulfillment text response to be sent to the agent
            text: [text],
          },
        },
      ],
    },
  };

  response.send(jsonResponse);
};

Python


# TODO(developer): change entry point to handle_webhook in cloud function


def handle_webhook(request):

    req = request.get_json()

    tag = req["fulfillmentInfo"]["tag"]

    if tag == "Default Welcome Intent":
        text = "Hello from a GCF Webhook"
    elif tag == "get-name":
        text = "My name is Flowhook"
    else:
        text = f"There are no fulfillment responses defined for {tag} tag"

    # You can also use the google.cloud.dialogflowcx_v3.types.WebhookRequest protos instead of manually writing the json object
    # Please see https://googleapis.dev/python/dialogflow/latest/dialogflow_v2/types.html?highlight=webhookresponse#google.cloud.dialogflow_v2.types.WebhookResponse for an overview
    res = {
        "fulfillment_response": {
            "messages": [
                {
                    "text": {
                        "text": [
                            text
                        ]
                    }
                }
            ]
        }
    }

    # Returns json
    return res