Implémenter des webhooks

Ce guide fournit différents exemples d'implémentation webhooks ainsi que des recommandations de dépannage pour les webhooks.

Définir un paramètre de session

Les exemples suivants montrent comment définir un paramètre de session.

Go

Pour vous authentifier auprès de Dialogflow, configurez les identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

Consultez le guide de démarrage rapide des webhooks.

Java

Pour vous authentifier auprès de Dialogflow, configurez les identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.


// TODO: Change class name to Example
// TODO: Uncomment the line below 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 java.io.BufferedWriter;

public class WebhookConfigureSessionParameters implements HttpFunction {
  @Override
  public void service(HttpRequest request, HttpResponse response) throws Exception {
    JsonObject orderParameter = new JsonObject();
    orderParameter.addProperty("order_number", "12345");

    JsonObject parameterObject = new JsonObject();
    parameterObject.add("parameters", orderParameter);

    // Creates webhook response object
    JsonObject webhookResponse = new JsonObject();
    webhookResponse.add("session_info", parameterObject);

    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    String jsonResponseObject = gson.toJson(webhookResponse);

    /** { "session_info": { "parameters": { "order_number": "12345" } } } */
    BufferedWriter writer = response.getWriter();
    // Sends the webhookResponseObject
    writer.write(jsonResponseObject.toString());
  }
}

Node.js

Pour vous authentifier auprès de Dialogflow, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

const functions = require('@google-cloud/functions-framework');

functions.http('configureSessionParams', (request, response) => {
  // Session parameter configured by the webhook
  const orderNumber = 123;

  const jsonResponse = {
    sessionInfo: {
      parameters: {
        orderNumber: orderNumber,
      },
    },
  };

  response.send(jsonResponse);
});

Python

Pour vous authentifier auprès de Dialogflow, configurez les identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

import functions_framework

# TODO (developer): change entry point to configure_session_params in Cloud Function


@functions_framework.http
def configure_session_params(request):
    """Webhook to validate or configure new session parameters."""

    order_number = 123

    json_response = {
        "sessionInfo": {
            "parameters": {
                "orderNumber": order_number,
            },
        },
    }

    return json_response

Renvoyer une réponse de traitement

Les exemples suivants montrent comment renvoyer une réponse de traitement.

Go

Pour vous authentifier auprès de Dialogflow, configurez les identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

Consultez le Guide de démarrage rapide des webhooks

Java

Pour vous authentifier auprès de Dialogflow, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.


// 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 {
    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 =
        JsonParser
            .parseString(
                "{ \"fulfillment_response\": { \"messages\": [ { \"text\": { \"text\": ["
                    + responseText
                    + "] } } ] } }")
            .getAsJsonObject();
    BufferedWriter writer = response.getWriter();

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

Node.js

Pour vous authentifier auprès de Dialogflow, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

const functions = require('@google-cloud/functions-framework');

functions.http('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

Pour vous authentifier auprès de Dialogflow, configurez les identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

import functions_framework

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


@functions_framework.http
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

Définissez les paramètres du formulaire si nécessaire

Les exemples suivants montrent comment signaler un paramètre si nécessaire.

Java

Pour vous authentifier auprès de Dialogflow, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.


// TODO: Change class name to Example
// TODO: Uncomment the line below 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.JsonArray;
import com.google.gson.JsonObject;
import java.io.BufferedWriter;

public class ConfigureWebhookToSetFormParametersAsOptionalOrRequired implements HttpFunction {
  @Override
  public void service(HttpRequest request, HttpResponse response) throws Exception {
    JsonObject parameterObject = new JsonObject();
    parameterObject.addProperty("display_name", "order_number");
    parameterObject.addProperty("required", "true");
    parameterObject.addProperty("state", "VALID");

    JsonArray parameterInfoList = new JsonArray();
    parameterInfoList.add(parameterObject);

    JsonObject parameterInfoObject = new JsonObject();
    parameterInfoObject.add("parameter_info", parameterInfoList);

    JsonObject formInfo = new JsonObject();
    formInfo.add("form_info", parameterInfoObject);

    // Constructs the webhook response object
    JsonObject webhookResponse = new JsonObject();
    webhookResponse.add("page_info", formInfo);

    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    String jsonResponseObject = gson.toJson(webhookResponse);

    /* {
     *   "page_info": {
     *     "form_info": {
     *       "parameter_info": [
     *         {
     *           "display_name": "order_number",
     *           "required": "true",
     *           "state": "VALID"
     *         }
     *       ]
     *     }
     *   }
     * }
     */

    BufferedWriter writer = response.getWriter();

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

Node.js

Pour vous authentifier auprès de Dialogflow, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

const functions = require('@google-cloud/functions-framework');

functions.http('configureOptionalFormParam', (request, response) => {
  // The value of the parameter that the webhook will set as optional or required.
  // Note that the webhook cannot add or remove any form parameter

  const jsonResponse = {
    pageInfo: {
      formInfo: {
        parameterInfo: [
          {
            displayName: 'order-number',
            // if required: false, the agent will not reprompt for this parameter, even if the state is 'INVALID'
            required: true,
            state: 'VALID',
          },
        ],
      },
    },
  };

  // Info about form parameter that is sent in the webhook response:
  console.log(
    'Parameter Info: \n',
    jsonResponse.pageInfo.formInfo.parameterInfo[0]
  );

  response.send(jsonResponse);
});

Valider un paramètre de formulaire

Les exemples suivants montrent comment valider un paramètre de formulaire.

Java

Pour vous authentifier auprès de Dialogflow, configurez les identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.


// TODO: Change class name to Example
// TODO: Uncomment the line below 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.JsonArray;
import com.google.gson.JsonObject;
import java.io.BufferedWriter;

public class WebhookValidateFormParameter implements HttpFunction {
  @Override
  public void service(HttpRequest request, HttpResponse response) throws Exception {
    JsonObject sessionInfo = new JsonObject();
    JsonObject sessionParameter = new JsonObject();

    sessionParameter.addProperty("order_number", "null");
    sessionInfo.add("parameters", sessionParameter);

    JsonObject parameterObject = new JsonObject();
    parameterObject.addProperty("display_name", "order_number");
    parameterObject.addProperty("required", "true");
    parameterObject.addProperty("state", "INVALID");
    parameterObject.addProperty("value", "123");

    JsonArray parameterInfoList = new JsonArray();
    parameterInfoList.add(parameterObject);

    JsonObject parameterInfoObject = new JsonObject();
    parameterInfoObject.add("parameter_info", parameterInfoList);

    JsonObject pageInfo = new JsonObject();
    pageInfo.add("form_info", parameterInfoObject);

    // Constructs the webhook response object
    JsonObject webhookResponse = new JsonObject();
    webhookResponse.add("page_info", pageInfo);
    webhookResponse.add("session_info", sessionInfo);

    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    String jsonResponseObject = gson.toJson(webhookResponse);

    /**
     * { "page_info": { "form_info": { "parameter_info": [ { "display_name": "order_number",
     * "required": "true", "state": "INVALID", "value": "123" } ] } }, "session_info": {
     * "parameters": { "order_number": "null" } } }
     */
    BufferedWriter writer = response.getWriter();

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

Node.js

Pour vous authentifier auprès de Dialogflow, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

const functions = require('@google-cloud/functions-framework');

functions.http('validateParameter', (request, response) => {
  // Webhook will validate or invalidate parameter based on logic configured by the user.
  // Access parameter values through the webhook request via `request.body.pageInfo.formInfo.parameterInfo[]`
  const jsonResponse = {
    page_info: {
      form_info: {
        parameter_info: [
          {
            displayName: 'orderNumber',
            required: true,
            state: 'INVALID',
            value: 123,
          },
        ],
      },
    },
    sessionInfo: {
      parameters: {
        // Set session parameter to null if the form parameter is 'INVALID' and your agent needs to reprompt the user
        orderNumber: null,
      },
    },
  };

  response.send(jsonResponse);
});

Python

Pour vous authentifier auprès de Dialogflow, configurez les identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

import functions_framework


@functions_framework.http
def validate_parameter(request):
    """Webhook will validate or invalidate parameter based on logic configured by the user."""
    return {
        "page_info": {
            "form_info": {
                "parameter_info": [
                    {
                        "displayName": "orderNumber",
                        "required": True,
                        "state": "INVALID",
                        "value": 123,
                    },
                ],
            },
        },
        "sessionInfo": {
            "parameters": {
                # Set session parameter to None if the form parameter is 'INVALID' and your agent needs to reprompt the user
                "orderNumber": None,
            },
        },
    }

ID de session de journalisation

L'exemple suivant montre comment consigner le session ID à partir d'une requête webhook.

Python

Pour vous authentifier auprès de Dialogflow, configurez les identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.


import re

import functions_framework


@functions_framework.http
def log_session_id_for_troubleshooting(request):
    """Webhook will log session id corresponding to request."""

    req = request.get_json()
    # You can read more about SessionInfo at https://cloud.google.com/dialogflow/cx/docs/reference/rest/v3/SessionInfo
    # Use a regex pattern to get the session ID
    session_id_regex = r".+\/sessions\/(.+)"
    session = req["sessionInfo"]["session"]
    regex_match = re.search(session_id_regex, session)
    session_id = regex_match.group(1)

    # Instead of printing, use the logging tools available to you
    print(f"Debug Node: session ID = {session_id}")

    # Return a generic response
    res = {
        "fulfillment_response": {
            "messages": [{"text": {"text": [f"Request Session ID: {session_id}"]}}]
        }
    }

    # Returns json
    return res

Dépannage

Lorsque vous dépannez un webhook, il peut être utile de consigner l'ID de session de votre webhook. Le champ sessionInfo.session de WebhookRequest contient l'ID de session. L'ID de session doit être unique pour chaque conversation, et peut vous aider à comparer les journaux de l'agent aux journaux des webhooks. pour les requêtes utilisant le même ID de session. La section ID de session du journal ci-dessus montre comment consigner l'ID de session à partir d'un webhook.

De plus, si vous hébergez votre webhook Cloud Functions ou une solution sans serveur Google Cloud similaire, vous pouvez utiliser le champ trace de entrées de journal comme filtre de journal. Une seule exécution d'une fonction génère plusieurs entrées de journal avec la même valeur de trace.

L'exemple ci-dessous utilise à la fois l'ID de session et la valeur de trace pour associer un journal d'erreur d'agent Conversational Agents (Dialogflow CX) particulier aux entrées de journal du webhook Cloud Functions correspondantes. Cet exemple utilise Filtres Cloud Logging pour un agent qui a activé Cloud Logging :

1. Filtrer les journaux des agents conversationnels (Dialogflow CX) pour les journaux d'erreurs d'un agent spécifique

Utilisez le filtre Cloud Logging suivant pour filtrer les journaux de vos agents conversationnels (Dialogflow CX) en fonction des journaux d'erreurs d'un agent particulier :

labels.location_id="global"
labels.agent_id="AGENT_ID"
severity=ERROR

Une entrée d'erreur de journal de webhook ressemble à ceci :

{
  "insertId": "-zi368ye1ie3r",
  "jsonPayload": {
    "message": "Webhook error: State: URL_UNREACHABLE, Reason: UNREACHABLE_5xx, HTTP status code: 500",
    "code": 14
  },
  "resource": {
    "type": "global",
    "labels": {
      "project_id": "PROJECT_ID"
    }
  },
  "timestamp": "2022-10-05T19:44:53.098938Z",
  "severity": "ERROR",
  "labels": {
    "session_id": "ec8781-f28-7e6-791-d7e992e8f",
    "location_id": "global",
    "agent_id": "807346f0-f501-42b5-9642-af59d5e98165"
  },
  "logName": "projects/PROJECT_ID/logs/dialogflow-runtime.googleapis.com%2Frequests",
  "receiveTimestamp": "2022-10-05T19:44:53.222552658Z"
}

Notez le champ labels.session_id, qui contient l'ID de session. Vous utiliserez l'ID de session à l'étape suivante.

2. Filtrer les journaux de la fonction Cloud par ID de session

Utilisez le filtre Cloud Logging suivant pour filtrer les journaux de votre fonction Cloud par ID de session:

resource.type = "cloud_function"
resource.labels.function_name = "CLOUD_FUNCTION_NAME"
resource.labels.region = "CLOUD_FUNCTION_REGION"
textPayload="Debug Node: session ID = SESSION_ID"

Les journaux générés correspondent aux journaux de webhook créés au cours de la session fournie. Exemple :

{
  "textPayload": "Debug Node: session ID = ec8781-f28-7e6-791-d7e992e8f",
  "insertId": "632bdb2b000b7c6c77d0cc62",
  "resource": {
    "type": "cloud_function",
    "labels": {
      "project_id": "PROJECT_ID",
      "function_name": "webhook",
      "region": "us-central1"
    }
  },
  "timestamp": "2022-10-05T19:44:53.098938Z",
  "severity": "INFO",
  "labels": {
    "execution_id": "ozt5bnz50eeo",
    "instance_id": "00c61b117c1f116421aa5503bc80f9aa636b9ef117bb2722f3d54414085e62be6e55af0aa0250a63534262b31a3d3a14af8c940203f1915db8b25b"
  },
  "logName": "projects/PROJECT_ID/logs/cloudfunctions.googleapis.com%2Fcloud-functions",
  "trace": "projects/PROJECT_ID/traces/e41eefc1fac48665b442bfa400cc2f5e",
  "receiveTimestamp": "2022-10-05T19:44:53.222552658Z"
}

Notez le champ trace, qui sera utilisé à l'étape suivante.

3. Filtrer les journaux Cloud Functions pour une trace spécifique

Utilisez le filtre Cloud Logging suivant pour filtrer les journaux de la fonction Cloud pour une trace particulière:

resource.type = "cloud_function"
resource.labels.function_name = "CLOUD_FUNCTION_NAME"
resource.labels.region = "CLOUD_FUNCTION_REGION"
trace="projects/PROJECT_ID/traces/TRACE_ID"

TRACE_ID est le dernier segment de la trace. Par exemple, TRACE_ID pour projects/PROJECT_ID/traces/e41eefc1fac48665b442bfa400cc2f5e est e41eefc1fac48665b442bfa400cc2f5e.

Les journaux générés correspondent à tous les journaux webhook générés lors de l'exécution de la requête webhook associée à l'ID de session de l'étape 1 et à la trace de l'étape 2.