Webhook-Dienst

Wenn Sie die Auftragsausführung 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 für Webhooks wird im Übersichtsdokument für die Auftragsausführung beschrieben.

Webhook-Dienstanforderungen

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

Authentifizierung

Es ist wichtig, den Webhook-Dienst so zu sichern, dass nur Sie oder Ihr Dialogflow-Agent berechtigt sind, Anfragen zu stellen. Dialogflow unterstützt die folgenden Authentifizierungsmechanismen:

Begriff Definition
Nutzername und Passwort für die Anmeldung Für die Webhook-Einstellungen können Sie optionale Anmeldenamen und Passwörter angeben. Wenn Sie einen Wert angeben, fügt Dialogflow Webhook-Anfragen einen Autorisierungs-HTTP-Header hinzu. Dieser Header hat das Format "authorization: Basic <base 64 encoding of the string username:password>".
Authentifizierungs-Header Für Webhook-Einstellungen können Sie optionale HTTP-Header-Schlüssel/Wert-Paare angeben. Wenn Sie diese angeben, fügt Dialogflow sie den Webhook-Anfragen hinzu. Es ist üblich, ein einzelnes Paar mit dem Schlüssel authorization anzugeben.
Integrierte Authentifizierung in Cloud Functions Sie können die integrierte Authentifizierung bei der Verwendung von Cloud Functions verwenden. Wenn du diese Art der Authentifizierung verwenden möchtest, gib keinen Anmeldenamen, kein Anmeldepasswort und keine Autorisierungsheader an. Wenn Sie eines dieser Felder angeben, wird es anstelle der integrierten 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 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 zugeordnet wird, sendet Dialogflow eine HTTPS-POST-Webhook-Anforderung an Ihren Webhook-Dienst. Der Text dieser Anfrage ist ein JSON-Objekt mit Informationen zum zugeordneten Intent.

Neben der Endnutzerabfrage senden viele Integrationen auch einige Informationen über den Endnutzer. Dies kann beispielsweise eine ID sein, mit der der Nutzer eindeutig identifiziert werden kann. Auf diese Informationen kann in der Webhook-Anfrage über das Feld originalDetectIntentRequest zugegriffen werden. Dieses Feld enthält die von der Integrationsplattform gesendeten Informationen.

Weitere Informationen finden Sie in der Referenzdokumentation zu WebhookRequest.

Ein Beispiel für eine Anfrage:

{
  "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

Sobald Ihr Webhook eine Webhook-Anfrage erhält, muss er eine Webhook-Antwort senden. Der Text dieser Antwort ist ein JSON-Objekt mit den folgenden Informationen:

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

  • Die Antwort muss bei Google Assistant-Anwendungen innerhalb von 10 Sekunden und bei allen anderen Anwendungen innerhalb von 5 Sekunden erfolgen. Andernfalls tritt bei der Anfrage eine Zeitüberschreitung ein.
  • Die Antwort darf maximal 64 KiB groß sein.

Weitere Informationen finden Sie in der Referenzdokumentation zu WebhookResponse.

Textantwort

Beispiel für eine Textantwort:

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

Kartenantwort

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

Beispiel für eine Google Assistant-Antwort:

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

Kontext

Beispiel, das den Ausgabekontext festlegt:

{
  "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"
      }
    }
  ]
}

Event

Beispiel, das ein benutzerdefiniertes Ereignis aufruft:

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

Sitzungsentität

Beispiel, das eine Sitzungsentität festlegt:

{
  "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

Beispiel für eine benutzerdefinierte Nutzlast:

{
  "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 Menü der linken Seitenleiste 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 den Webhook keine Authentifizierung erforderlich ist, lassen Sie die Authentifizierungsfelder leer.
  6. Klicken Sie unten auf der Seite auf Speichern.

Screenshot: Aktivieren der Auftragsausführung

Informationen zum Aktivieren und Verwalten der Auftragsausführung für Ihren Agent mit der API finden Sie in der Agent-Referenz. Mit den Methoden getFulfillment und updateFulfillment können Sie die Auftragsausführungs-Einstellungen 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. Scrollen Sie nach unten, zum Abschnitt Auftragsausführung.
  4. Webhook-Aufruf für diesen Intent aktivieren einschalten.
  5. Klicken Sie auf Speichern.

Informationen zum Aktivieren der Auftragsausführung 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 Ihr Webhook-Dienst einen Fehler feststellt, sollte er einen der folgenden HTTP-Statuscodes zurückgeben:

  • 400 Fehlerhafte Anfrage
  • 401 Nicht autorisiert
  • 403 Unzulässig
  • 404 Nicht gefunden
  • 500 Serverfehler
  • 503 Dienst nicht verfügbar

Bei den folgenden Fehlern antwortet Dialogflow dem Endnutzer mit der eingebundenen Antwort, die für den aktuell zugeordneten Intent konfiguriert ist:

  • Antwortzeitlimit überschritten.
  • Fehlerstatuscode empfangen.
  • Die Antwort ist ungültig.
  • Der Webhook-Dienst ist nicht verfügbar.

Wenn der Intent-Abgleich durch einen API-Aufruf zur Intent-Erkennung ausgelöst wurde, enthält außerdem das Feld status in der Antwort für die Intent-Erkennung 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 neuen Versuch starten, um die Robustheit zu verbessern. Es werden nur nicht-terminale Fehler noch einmal versucht (z. B. Zeitüberschreitungen oder Verbindungsfehler).

So verringern Sie die Wahrscheinlichkeit von doppelten Anrufen:

  • Legen Sie längere Zeitlimits für Webhooks fest.
  • Unterstütze die Idempotency in der Webhook-Logik oder dedupliziere die Daten.

Cloud Functions verwenden

Es gibt verschiedene Möglichkeiten, Cloud Functions für die Auftragsausführung zu verwenden. Der Inline-Editor von Dialogflow kann in Cloud Functions eingebunden werden. Wenn Sie den Inline-Editor zum Erstellen und Bearbeiten des Webhook-Codes verwenden, stellt Dialogflow eine sichere Verbindung zu Ihrer Cloud Functions-Funktion her.

Sie haben auch die Möglichkeit, eine Cloud Functions-Funktion zu verwenden, die nicht vom Inline-Editor erstellt wurde (möglicherweise, weil Sie eine andere Sprache als Node.js verwenden möchten). Befindet sich die Cloud Functions-Funktion im selben Projekt wie der Agent, kann der Agent den Webhook ohne spezielle Konfiguration aufrufen.

Es gibt jedoch zwei Situationen, in denen Sie diese Integration manuell einrichten müssen:

  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 beim Erstellen des ersten Agents für ein Projekt normalerweise automatisch erstellt. Wenn Ihr Agent vor dem 10. Mai 2021 erstellt wurde, müssen Sie möglicherweise dieses spezielle Dienstkonto folgendermaßen erstellen:
    1. Erstellen Sie einen neuen Agent für das Projekt.
    2. Führen Sie diesen Befehl aus:
      gcloud beta services identity create --service=dialogflow.googleapis.com --project=agent-project-id
  2. Wenn sich die Webhook-Funktion in einem anderen Projekt als der Agent befindet, müssen Sie den Cloud Functions-Invoker IAM-Rolle an die Dialogflow-Dienst-Agent Dienstkonto im Projekt Ihrer Funktion.

Identitätstokens für Dienste

Wenn Dialogflow einen Webhook aufruft, wird ein Google-Identitätstoken mit der Anfrage 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

In den folgenden Beispielen wird gezeigt, wie Sie einen WebhookRequest empfangen und einen WebhookResponse senden. Diese Beispiele verweisen auf Intents, die in der Kurzanleitung erstellt wurden.

Go

Richten Sie zur Authentifizierung bei Dialogflow die 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 die 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 die 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 die 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