Service de webhook

Pour utiliser le fulfillment dans un système de production, vous devez mettre en œuvre et déployer un service de webhook. Pour gérer le fulfillment, votre service de webhook doit accepter les requêtes JSON et renvoyer des réponses JSON comme indiqué dans ce guide. Le flux de traitement détaillé pour le fulfillment et les webhooks est décrit dans le document de présentation du fulfillment.

Conditions requises pour le service de webhook

Votre service de webhook doit remplir les conditions suivantes :

  • Il doit gérer les requêtes HTTPS. Le protocole HTTP n'est pas compatible. Si vous hébergez votre service de webhook sur Google Cloud Platform à l'aide d'une solution de calcul ou de calcul sans serveur, consultez la documentation produit pour la diffusion avec HTTPS. Pour connaître les autres options d'hébergement, consultez la page Obtenir un certificat SSL pour votre domaine.
  • Son URL pour les requêtes doit être accessible publiquement.
  • Il doit gérer les requêtes POST avec un corps JSON WebhookRequest.
  • Il doit répondre aux requêtes WebhookRequest avec un corps JSON WebhookResponse.

Authentification

Il est important de sécuriser votre service de webhook, de sorte que vous seul ou votre agent Dialogflow soyez autorisé à effectuer des requêtes. Dialogflow est compatible avec les mécanismes d'authentification suivants :

  • L'authentification de base avec identifiant et mot de passe. Elle est configurée lors de l'activation du fulfillment.
  • L'authentification avec des en-têtes d'authentification. Elle est configurée lors de l'activation du fulfillment.
  • L'authentification TLS mutuelle.

Requête de webhook

Lorsqu'un intent configuré pour le fulfillment est mis en correspondance, Dialogflow envoie une requête de webhook POST HTTPS à votre service de webhook. Le corps de cette requête est un objet JSON contenant des informations sur l'intent mis en correspondance.

Pour plus d'informations, consultez la documentation de référence du message WebhookRequest.

Voici un exemple de requête :

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

Réponse de webhook

Une fois que votre webhook reçoit une requête de webhook, il doit envoyer une réponse de webhook. Le corps de cette réponse est un objet JSON contenant les informations suivantes :

Les limites suivantes s'appliquent à votre réponse :

  • La réponse doit survenir dans les 10 secondes pour l'Assistant Google ou dans les 5 secondes pour toutes les autres applications, sinon la requête expire.
  • La taille de la réponse doit être inférieure ou égale à 64 Kio.

Pour plus d'informations, consultez la documentation de référence du message WebhookResponse.

Réponse textuelle

Exemple de réponse textuelle :

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

Réponse sous forme de fiche

Exemple de réponse sous forme de fiche :

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

Réponse de l'Assistant Google

Exemple de réponse de l'Assistant Google :

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

Contexte

Exemple qui définit le contexte de sortie :

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

Événement

Exemple qui appelle un événement personnalisé :

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

Entité de session

Exemple qui définit une entité de session :

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

Activer et gérer le fulfillment

Pour activer et gérer le fulfillment pour votre agent à l'aide de la console, procédez comme suit :

  1. Accédez à la console Dialogflow ES.
  2. Sélectionnez un agent.
  3. Dans le menu de la barre latérale de gauche, sélectionnez Fulfillment.
  4. Définissez le champ Webhook sur Enabled (Activé).
  5. Fournissez les détails de votre service de webhook dans le formulaire. Si votre webhook ne nécessite pas d'authentification, laissez les champs d'authentification vides.
  6. Cliquez sur Enregistrer au bas de la page.

Capture d'écran de l'activation du fulfillment.

Pour activer et gérer le fulfillment pour votre agent à l'aide de l'API, consultez la documentation de référence de l'agent. Les méthodes getFulfillment et updateFulfillment peuvent servir à gérer les paramètres de fulfillment.

Pour activer le fulfillment pour un intent avec la console, procédez comme suit :

  1. Cliquez sur Intents dans le menu de la barre latérale gauche.
  2. Sélectionnez un intent.
  3. Faites défiler la page jusqu'à la section Fulfillment.
  4. Activez l'option Activer l'appel webhook pour cet intent.
  5. Cliquez sur Enregistrer.

Pour activer le fulfillment d'un intent avec l'API, consultez la documentation de référence des intents. Définissez le champ webhookState sur WEBHOOK_STATE_ENABLED.

Erreurs de webhook

Si votre service de webhook rencontre une erreur, il doit renvoyer l'un des codes d'état HTTP suivants :

  • 400 Requête incorrecte
  • 401 Opération non autorisée
  • 403 Interdit
  • 404 Introuvable
  • 500 Panne du serveur
  • 503 Service indisponible

Dans les cas d'erreur suivants, Dialogflow répond à l'utilisateur final avec la réponse intégrée configurée pour l'intent actuellement mis en correspondance :

  • Expiration du délai de réponse
  • Code d'état d'erreur reçu
  • Réponse non valide
  • Service de webhook non disponible

En outre, si la mise en correspondance d'intent a été déclenchée par un appel d'API de détection d'intent, le champ status de la réponse de détection d'intent contient des informations sur l'erreur du webhook. Exemple :

"status": {
    "code": 206,
    "errorType": "webhook call failed with %error Code% error"
}

Exemples

L'exemple suivant montre comment recevoir une requête WebhookRequest et envoyer une réponse WebhookResponse. Cet exemple référence les intents créés dans le guide de démarrage rapide.

Go

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
	}
}