Webhook-Dienst

Wenn Sie das Fulfillment in einem Produktionssystem verwenden möchten, müssen Sie einen Webhook-Dienst implementieren und bereitstellen. Für die Auftragsausführung muss Ihr Webhook-Dienst JSON-Anfragen akzeptieren und JSON-Antworten zurückgeben, wie in diesem Leitfaden beschrieben. Der detaillierte Verarbeitungsablauf für die Auftragsausführung und Webhooks wird im Dokument zur Übersicht über die Auftragsausführung beschrieben.

Webhook-Dienstanforderungen

Ihr Webhook-Dienst muss die folgenden Anforderungen erfüllen:

  • HTTPS-Anfragen verarbeiten HTTP wird nicht unterstützt. Wenn Sie Ihren Webhook-Dienst in Google Cloud mit einer Compute- oder serverlosen Computing-Lösung hosten, finden Sie in der Produktdokumentation Informationen zur Bereitstellung mit HTTPS. Weitere Hosting-Optionen finden Sie unter SSL-Zertifikat für Ihre Domain abrufen.
  • Die URL des Webhook-Dienstes muss öffentlich zugänglich sein.
  • Verarbeitet POST-Anfragen mit einem JSON-WebhookRequest-Text.
  • Antworten Sie auf WebhookRequest-Anfragen mit einem JSON-WebhookResponse-Text.

Authentifizierung

X Element
Nutzername und Passwort für die Anmeldung Für Webhook-Einstellungen können Sie optionale Werte für den Nutzernamen und das Passwort für die Anmeldung angeben. Wenn angegeben, fügt Dialogflow Webhook-Anfragen einen Autorisierungs-HTTP-Header hinzu. Dieser Header hat das folgende Format: "authorization: Basic <base 64 encoding of the string username:password>".
Authentifizierungsheader In den Webhook-Einstellungen können Sie optionale HTTP-Header-Schlüssel/Wert-Paare angeben. Falls angegeben, fügt Dialogflow diese HTTP-Header zu Webhook-Anfragen hinzu. Es ist üblich, ein einzelnes Paar mit dem Schlüssel authorization anzugeben.
Integrierte Authentifizierung für Cloud Run Functions Sie können die integrierte Authentifizierung verwenden, wenn Sie Cloud Run-Funktionen verwenden. Wenn Sie diese Art der Authentifizierung verwenden möchten, geben Sie keinen Nutzernamen, kein Passwort und keine Autorisierungsheader an. Wenn Sie eines dieser Felder angeben, wird es nicht für die integrierte Authentifizierung verwendet.
Identitätstokens für Dienste Sie können Dienstidentitätstokens für die Authentifizierung verwenden. Wenn Sie keinen Anmeldenamen, kein Anmeldepasswort oder keinen Header mit dem Schlüssel authorization angeben, geht Dialogflow automatisch davon aus, dass Dienstidentitätstokens verwendet werden sollen, und fügt Webhook-Anfragen einen Autorisierungs-HTTP-Header hinzu. Dieser Header hat das folgende Format: "authorization: Bearer <identity token>".
Gegenseitige TLS-Authentifizierung Weitere Informationen finden Sie in der Dokumentation zur gegenseitigen TLS-Authentifizierung.

Webhook-Anfrage

Wenn ein für die Auftragsausführung konfigurierter Intent übereinstimmt, sendet Dialogflow eine HTTPS-POST-Webhook-Anfrage an Ihren Webhook-Dienst. Der Text dieser Anfrage ist ein JSON-Objekt mit Informationen zur übereinstimmenden Absicht.

Zusätzlich zur Anfrage des Endnutzers senden viele Integrationen auch Informationen zum Endnutzer. Beispiel: eine ID, die den Nutzer eindeutig identifiziert. Auf diese Informationen kann über das Feld originalDetectIntentRequest in der Webhook-Anfrage zugegriffen werden, das die von der Integrationsplattform gesendeten Informationen enthält.

Weitere Informationen finden Sie in der Referenzdokumentation zu WebhookRequest.

Hier ist eine Beispielanfrage:

{
  "responseId": "response-id",
  "session": "projects/project-id/agent/sessions/session-id",
  "queryResult": {
    "queryText": "End-user expression",
    "parameters": {
      "param-name": "param-value"
    },
    "allRequiredParamsPresent": true,
    "fulfillmentText": "Response configured for matched intent",
    "fulfillmentMessages": [
      {
        "text": {
          "text": [
            "Response configured for matched intent"
          ]
        }
      }
    ],
    "outputContexts": [
      {
        "name": "projects/project-id/agent/sessions/session-id/contexts/context-name",
        "lifespanCount": 5,
        "parameters": {
          "param-name": "param-value"
        }
      }
    ],
    "intent": {
      "name": "projects/project-id/agent/intents/intent-id",
      "displayName": "matched-intent-name"
    },
    "intentDetectionConfidence": 1,
    "diagnosticInfo": {},
    "languageCode": "en"
  },
  "originalDetectIntentRequest": {}
}

Webhook-Antwort

Nachdem Ihr Webhook eine Anfrage erhalten hat, muss er eine Antwort senden. Der Text dieser Antwort ist ein JSON-Objekt, das die folgenden Informationen enthält:

Für die Antwort gelten die folgenden Einschränkungen:

  • Antworten Sie bei Google Assistant-Anwendungen innerhalb von 10 Sekunden oder bei anderen Anwendungen innerhalb von 5 Sekunden. Andernfalls kommt es zu einer Zeitüberschreitung der Anfrage.
  • Die Antwortgröße darf maximal 64 KiB betragen.

Weitere Informationen finden Sie in der Referenzdokumentation zu WebhookResponse.

Textantwort

Hier ist ein Beispiel für eine Textantwort:

{
  "fulfillmentMessages": [
    {
      "text": {
        "text": [
          "Text response from webhook"
        ]
      }
    }
  ]
}

Kartenantwort

Hier ist ein Beispiel für eine Kartenantwort:

{
  "fulfillmentMessages": [
    {
      "card": {
        "title": "card title",
        "subtitle": "card text",
        "imageUri": "https://example.com/images/example.png",
        "buttons": [
          {
            "text": "button text",
            "postback": "https://example.com/path/for/end-user/to/follow"
          }
        ]
      }
    }
  ]
}

Google Assistant-Antwort

Hier ist ein Beispiel für eine Google Assistant-Antwort:

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "richResponse": {
        "items": [
          {
            "simpleResponse": {
              "textToSpeech": "this is a Google Assistant response"
            }
          }
        ]
      }
    }
  }
}

Kontext

Im folgenden Beispiel wird der Ausgabekontext festgelegt:

{
  "fulfillmentMessages": [
    {
      "text": {
        "text": [
          "Text response from webhook"
        ]
      }
    }
  ],
  "outputContexts": [
    {
      "name": "projects/project-id/agent/sessions/session-id/contexts/context-name",
      "lifespanCount": 5,
      "parameters": {
        "param-name": "param-value"
      }
    }
  ]
}

Ereignis

Im folgenden Beispiel wird ein benutzerdefiniertes Ereignis aufgerufen:

{
  "followupEventInput": {
    "name": "event-name",
    "languageCode": "en-US",
    "parameters": {
      "param-name": "param-value"
    }
  }
}

Sitzungsentität

Im folgenden Beispiel wird eine Sitzungsentität festgelegt:

{
  "fulfillmentMessages": [
    {
      "text": {
        "text": [
          "Choose apple or orange"
        ]
      }
    }
  ],
  "sessionEntityTypes":[
    {
      "name":"projects/project-id/agent/sessions/session-id/entityTypes/fruit",
      "entities":[
        {
          "value":"APPLE_KEY",
          "synonyms":[
            "apple",
            "green apple",
            "crabapple"
          ]
        },
        {
          "value":"ORANGE_KEY",
          "synonyms":[
            "orange"
          ]
        }
      ],
      "entityOverrideMode":"ENTITY_OVERRIDE_MODE_OVERRIDE"
    }
  ]
}

Benutzerdefinierte Nutzlast

Im folgenden Beispiel wird eine benutzerdefinierte Nutzlast bereitgestellt:

{
  "fulfillmentMessages": [
    {
      "payload": {
        "facebook": { // for Facebook Messenger integration
          "attachment": {
            "type": "",
            "payload": {}
          }
        },
        "slack": { // for Slack integration
          "text": "",
          "attachments": []
        },
        "richContent": [ // for Dialogflow Messenger integration
          [
            {
              "type": "image",
              "rawUrl": "https://example.com/images/logo.png",
              "accessibilityText": "Example logo"
            }
          ]
        ],
        // custom integration payload here
      }
    }
  ]
}

Auftragsausführung aktivieren und verwalten

So aktivieren und verwalten Sie die Auftragsausführung für Ihren Agent über die Konsole:

  1. Rufen Sie die Dialogflow ES-Konsole auf.
  2. Wählen Sie einen Agent aus.
  3. Wählen Sie im Seitenleistenmenü Auftragsausführung aus.
  4. Stellen Sie für das Feld Webhook die Option Aktiviert ein.
  5. Geben Sie im Formular die Details für Ihren Webhook-Dienst an. Wenn für Ihren Webhook keine Authentifizierung erforderlich ist, lassen Sie die Authentifizierungsfelder leer.
  6. Klicken Sie auf Speichern.

Screenshot: Aktivieren der Auftragsausführung

Informationen zum Aktivieren und Verwalten des Fulfillment für Ihren Agenten mit der API finden Sie in der Agent-Referenz. Mit den Methoden getFulfillment und updateFulfillment können Sie die Einstellungen für die Auftragsausführung verwalten.

So aktivieren Sie mit der Konsole die Auftragsausführung für einen Intent:

  1. Wählen Sie im Menü der linken Seitenleiste Intents aus.
  2. Wählen Sie einen Intent aus.
  3. Gehen Sie zum Abschnitt Auftragsausführung.
  4. Aktivieren Sie die Option Webhook-Aufruf für diesen Intent aktivieren.
  5. Klicken Sie auf Speichern.

Informationen zum Aktivieren des Fulfillment für einen Intent mit der API finden Sie in der Referenz zu Intents. Setzen Sie das Feld webhookState auf WEBHOOK_STATE_ENABLED.

Webhook-Fehler

Wenn bei Ihrem Webhook-Dienst ein Fehler auftritt, sollte er einen der folgenden HTTP-Statuscodes zurückgeben:

  • 400: Ungültige Anfrage
  • 401: Fehlende Autorisierung
  • 403: Verboten
  • 404: Nicht gefunden
  • 500: Interner Serverfehler
  • 503: Dienst nicht verfügbar

In den folgenden Fehlersituationen antwortet Dialogflow dem Endnutzer mit der integrierten Antwort, die für den übereinstimmenden Intent konfiguriert ist:

  • Das Zeitlimit für die Antwort wurde überschritten.
  • Ein Fehlerstatuscode wurde empfangen.
  • Die Antwort ist ungültig.
  • Der Webhook-Dienst ist nicht verfügbar.

Wenn ein API-Aufruf zur Intent-Erkennung die Intent-Übereinstimmung auslöst, enthält das Feld status in der Antwort zur Intent-Erkennung außerdem die Webhook-Fehlerinformationen. Beispiel:

"status": {
    "code": 206,
    "message": "Webhook call failed. <details of the error...>"
}

Automatische Wiederholungsversuche

Dialogflow ES enthält interne Mechanismen, die bei bestimmten Webhook-Fehlern automatisch einen Wiederholungsversuch ausführen, um die Robustheit zu verbessern. Nur nicht-terminale Fehler wie Zeitüberschreitungs- oder Verbindungsfehler werden wiederholt.

So verringern Sie die Wahrscheinlichkeit doppelter Aufrufe:

  • Längere Zeitlimits für Webhooks festlegen.
  • Unterstützen Sie Idempotenz in Ihrer Webhook-Logik oder deduplizieren Sie Anfragen.

Cloud Run Functions verwenden

Sie können Cloud Run-Funktionen auf verschiedene Arten für die Auftragsausführung verwenden. Der Inline-Editor von Dialogflow ist in Cloud Run Functions eingebunden. Wenn Sie den Inline-Editor zum Erstellen und Bearbeiten Ihres Webhook-Codes verwenden, stellt Dialogflow eine sichere Verbindung zu Ihrer Cloud Functions-Funktion her.

Sie können auch eine Cloud Functions-Funktion verwenden, die nicht mit dem Inline-Editor erstellt wurde. Wenn sich Cloud Function im selben Projekt wie Ihr Agent befindet, kann Ihr Agent den Webhook ohne spezielle Konfiguration aufrufen.

In den folgenden beiden Situationen müssen Sie diese Integration jedoch manuell einrichten:

  1. Das Dienstkonto Dialogflow-Dienst-Agent mit der folgenden Adresse muss für Ihr Agent-Projekt vorhanden sein:
    service-agent-project-number@gcp-sa-dialogflow.iam.gserviceaccount.com
    Dieses spezielle Dienstkonto und der zugehörige Schlüssel werden normalerweise automatisch erstellt, wenn Sie den ersten Agent für ein Projekt erstellen. Wenn Ihr Agent vor dem 10. Mai 2021 erstellt wurde, müssen Sie die Erstellung dieses speziellen Dienstkontos möglicherweise mit Folgendem auslösen:
    1. Erstellen Sie einen neuen Agent für das Projekt.
    2. Führen Sie den folgenden Befehl aus:
      gcloud beta services identity create --service=dialogflow.googleapis.com --project=agent-project-id
  2. Wenn sich Ihre Webhook-Funktion in einem anderen Projekt als der Agent befindet, müssen Sie dem Dienstkonto Dialogflow-Dienst-Agent im Projekt Ihrer Funktion die IAM-Rolle Cloud Functions-Aufrufer zuweisen.

Identitätstokens für Dienste

Wenn Dialogflow einen Webhook aufruft, wird mit der Anfrage ein Google Identity-Token bereitgestellt. Jeder Webhook kann das Token optional mit Google-Clientbibliotheken oder Open-Source-Bibliotheken wie github.com/googleapis/google-auth-library-nodejs validieren. Sie können beispielsweise die email des ID-Tokens so prüfen:

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

Beispiele

Die folgenden Beispiele zeigen, wie Sie eine WebhookRequest empfangen und eine WebhookResponse senden. In diesen Beispielen werden Intents verwendet, die in der Kurzanleitung erstellt wurden.

Go

Richten Sie zur Authentifizierung bei Dialogflow CX Standardanmeldedaten für Anwendungen ein. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
)

type intent struct {
	DisplayName string `json:"displayName"`
}

type queryResult struct {
	Intent intent `json:"intent"`
}

type text struct {
	Text []string `json:"text"`
}

type message struct {
	Text text `json:"text"`
}

// webhookRequest is used to unmarshal a WebhookRequest JSON object. Note that
// not all members need to be defined--just those that you need to process.
// As an alternative, you could use the types provided by
// the Dialogflow protocol buffers:
// https://godoc.org/google.golang.org/genproto/googleapis/cloud/dialogflow/v2#WebhookRequest
type webhookRequest struct {
	Session     string      `json:"session"`
	ResponseID  string      `json:"responseId"`
	QueryResult queryResult `json:"queryResult"`
}

// webhookResponse is used to marshal a WebhookResponse JSON object. Note that
// not all members need to be defined--just those that you need to process.
// As an alternative, you could use the types provided by
// the Dialogflow protocol buffers:
// https://godoc.org/google.golang.org/genproto/googleapis/cloud/dialogflow/v2#WebhookResponse
type webhookResponse struct {
	FulfillmentMessages []message `json:"fulfillmentMessages"`
}

// welcome creates a response for the welcome intent.
func welcome(request webhookRequest) (webhookResponse, error) {
	response := webhookResponse{
		FulfillmentMessages: []message{
			{
				Text: text{
					Text: []string{"Welcome from Dialogflow Go Webhook"},
				},
			},
		},
	}
	return response, nil
}

// getAgentName creates a response for the get-agent-name intent.
func getAgentName(request webhookRequest) (webhookResponse, error) {
	response := webhookResponse{
		FulfillmentMessages: []message{
			{
				Text: text{
					Text: []string{"My name is Dialogflow Go Webhook"},
				},
			},
		},
	}
	return response, nil
}

// handleError handles internal errors.
func handleError(w http.ResponseWriter, err error) {
	w.WriteHeader(http.StatusInternalServerError)
	fmt.Fprintf(w, "ERROR: %v", err)
}

// HandleWebhookRequest handles WebhookRequest and sends the WebhookResponse.
func HandleWebhookRequest(w http.ResponseWriter, r *http.Request) {
	var request webhookRequest
	var response webhookResponse
	var err error

	// Read input JSON
	if err = json.NewDecoder(r.Body).Decode(&request); err != nil {
		handleError(w, err)
		return
	}
	log.Printf("Request: %+v", request)

	// Call intent handler
	switch intent := request.QueryResult.Intent.DisplayName; intent {
	case "Default Welcome Intent":
		response, err = welcome(request)
	case "get-agent-name":
		response, err = getAgentName(request)
	default:
		err = fmt.Errorf("Unknown intent: %s", intent)
	}
	if err != nil {
		handleError(w, err)
		return
	}
	log.Printf("Response: %+v", response)

	// Send response
	if err = json.NewEncoder(w).Encode(&response); err != nil {
		handleError(w, err)
		return
	}
}

Java

Richten Sie zur Authentifizierung bei Dialogflow CX Standardanmeldedaten für Anwendungen ein. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.


// 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 Example implements HttpFunction {

  public void service(HttpRequest request, HttpResponse response) throws Exception {
    JsonParser parser = new JsonParser();
    Gson gson = new GsonBuilder().create();

    JsonObject job = gson.fromJson(request.getReader(), JsonObject.class);
    String str =
        job.getAsJsonObject("queryResult")
            .getAsJsonObject("intent")
            .getAsJsonPrimitive("displayName")
            .toString();
    JsonObject o = null;
    String a = '"' + "Default Welcome Intent" + '"';
    String b = '"' + "get-agent-name" + '"';
    String responseText = "";

    if (str.equals(a)) {
      responseText = '"' + "Hello from a Java GCF Webhook" + '"';
    } else if (str.equals(b)) {
      responseText = '"' + "My name is Flowhook" + '"';
    } else {
      responseText = '"' + "Sorry I didn't get that" + '"';
    }

    o =
        parser
            .parse(
                "{\"fulfillmentMessages\": [ { \"text\": { \"text\": [ "
                    + responseText
                    + " ] } } ] }")
            .getAsJsonObject();

    BufferedWriter writer = response.getWriter();
    writer.write(o.toString());
  }
}

Node.js

Richten Sie zur Authentifizierung bei Dialogflow CX Standardanmeldedaten für Anwendungen ein. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.

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

// TODO: Add handleWebhook to 'Entry point' in the Google Cloud Function
functions.http('handleWebhook', (request, response) => {
  const tag = request.body.queryResult.intent.displayName;

  let jsonResponse = {};
  if (tag === 'Default Welcome Intent') {
    //fulfillment response to be sent to the agent if the request tag is equal to "welcome tag"
    jsonResponse = {
      fulfillment_messages: [
        {
          text: {
            //fulfillment text response to be sent to the agent
            text: ['Hello from a GCF Webhook'],
          },
        },
      ],
    };
  } else if (tag === 'get-name') {
    //fulfillment response to be sent to the agent if the request tag is equal to "welcome tag"
    jsonResponse = {
      fulfillment_messages: [
        {
          text: {
            //fulfillment text response to be sent to the agent
            text: ['My name is Flowhook'],
          },
        },
      ],
    };
  } else {
    jsonResponse = {
      //fulfillment text response to be sent to the agent if there are no defined responses for the specified tag
      fulfillment_messages: [
        {
          text: {
            ////fulfillment text response to be sent to the agent
            text: [
              `There are no fulfillment responses defined for "${tag}"" tag`,
            ],
          },
        },
      ],
    };
  }
  response.send(jsonResponse);
});

Python

Richten Sie zur Authentifizierung bei Dialogflow CX Standardanmeldedaten für Anwendungen ein. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.

# TODO: change the default Entry Point text to handleWebhook
import functions_framework


@functions_framework.http
def handleWebhook(request):
    req = request.get_json()

    responseText = ""
    intent = req["queryResult"]["intent"]["displayName"]

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

    # You can also use the google.cloud.dialogflowcx_v3.types.WebhookRequest protos instead of manually writing the json object
    res = {"fulfillmentMessages": [{"text": {"text": [responseText]}}]}

    return res