Layanan webhook

Untuk menggunakan fulfillment dalam sistem produksi, Anda harus mengimplementasikan dan men-deploy layanan webhook. Untuk menangani fulfillment, layanan webhook Anda harus menerima permintaan JSON dan menampilkan respons JSON seperti yang ditentukan dalam panduan ini. Alur pemrosesan mendetail untuk fulfillment dan webhook dijelaskan dalam dokumen ringkasan fulfillment.

Persyaratan layanan webhook

Persyaratan berikut harus dipenuhi oleh layanan webhook Anda:

  • Aplikasi harus menangani permintaan HTTPS. HTTP tidak didukung. Jika Anda menghosting layanan webhook di Google Cloud Platform menggunakan solusi Komputasi atau Komputasi Serverless, lihat dokumentasi produk untuk melakukan penayangan dengan HTTPS. Untuk opsi hosting lainnya, lihat Mendapatkan sertifikat SSL untuk domain Anda.
  • URL-nya untuk permintaan harus dapat diakses secara publik.
  • Aplikasi harus menangani permintaan POST dengan isi WebhookRequest JSON.
  • Aplikasi harus merespons permintaan WebhookRequest dengan isi WebhookResponse JSON.

Authentication

Mengamankan layanan webhook Anda adalah hal yang penting, sehingga hanya Anda atau agen Dialogflow Anda yang diizinkan untuk membuat permintaan. Dialogflow mendukung mekanisme berikut untuk autentikasi:

Masa Berlaku Definisi
Nama pengguna dan sandi login Untuk setelan webhook, Anda dapat menentukan nilai sandi dan nama pengguna login opsional. Jika disediakan, Dialogflow akan menambahkan header HTTP otorisasi ke permintaan webhook. Header ini memiliki bentuk: "authorization: Basic <base 64 encoding of the string username:password>".
Header autentikasi Untuk setelan webhook, Anda dapat menentukan key-value pair header HTTP opsional. Jika disediakan, Dialogflow akan menambahkan header HTTP ini ke permintaan webhook. Anda dapat memberikan satu pasangan dengan kunci authorization.
Autentikasi bawaan Cloud Functions Anda dapat menggunakan autentikasi bawaan saat menggunakan Cloud Functions. Untuk menggunakan jenis autentikasi ini, jangan berikan nama pengguna login, sandi login, atau header otorisasi. Jika Anda menyediakan salah satu kolom tersebut, kolom tersebut akan digunakan untuk autentikasi, bukan autentikasi bawaan.
Token identitas layanan Anda dapat menggunakan token identitas layanan untuk autentikasi. Jika Anda tidak memberikan nama pengguna untuk login, sandi login, atau header dengan kunci authorization, Dialogflow secara otomatis akan mengasumsikan bahwa token identitas layanan harus digunakan dan menambahkan header HTTP otorisasi ke permintaan webhook. Header ini memiliki bentuk: "authorization: Bearer <identity token>".
Autentikasi TLS bersama Lihat dokumentasi Autentikasi TLS bersama.

Permintaan webhook

Saat intent yang dikonfigurasi untuk fulfillment cocok, Dialogflow akan mengirimkan permintaan webhook POST HTTPS ke layanan webhook. Isi permintaan ini adalah objek JSON dengan informasi tentang intent yang cocok.

Selain kueri pengguna akhir, banyak integrasi juga mengirim sejumlah informasi tentang pengguna akhir. Misalnya, ID untuk mengidentifikasi pengguna secara unik. Informasi ini dapat diakses melalui kolom originalDetectIntentRequest di permintaan webhook, yang akan berisi informasi yang dikirim dari platform integrasi.

Lihat dokumentasi referensi WebhookRequest untuk mengetahui detailnya.

Berikut adalah contoh permintaan:

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

Respons webhook

Setelah menerima permintaan webhook, webhook Anda perlu mengirimkan respons webhook. Isi respons ini adalah objek JSON dengan informasi berikut:

Batasan berikut berlaku pada respons Anda:

  • Respons harus terjadi dalam 10 detik untuk aplikasi Asisten Google atau 5 detik untuk semua aplikasi lain. Jika tidak, waktu tunggu permintaan akan habis.
  • Ukuran respons harus kurang dari atau sama dengan 64 KiB.

Lihat dokumentasi referensi WebhookResponse untuk mengetahui detailnya.

Pesan balasan

Contoh untuk respons teks:

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

Respons kartu

Contoh untuk respons kartu:

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

Respons Asisten Google

Contoh untuk respons Asisten Google:

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

Konteks

Contoh yang menetapkan konteks output:

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

Acara

Contoh yang memanggil peristiwa kustom:

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

Entity sesi

Contoh yang menetapkan entity sesi:

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

Payload kustom

Contoh yang menyediakan payload kustom:

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

Mengaktifkan dan mengelola fulfillment

Untuk mengaktifkan dan mengelola fulfillment agen Anda dengan konsol:

  1. Buka Konsol Dialogflow ES.
  2. Pilih agen.
  3. Pilih Fulfillment di menu sidebar kiri.
  4. Alihkan kolom Webhook ke Enabled.
  5. Berikan detail untuk layanan webhook Anda dalam formulir. Jika webhook Anda tidak memerlukan autentikasi, kosongkan kolom autentikasi.
  6. Klik Save di bagian bawah halaman.

Screenshot pengaktifan fulfillment.

Untuk mengaktifkan dan mengelola fulfillment agen Anda dengan API, lihat referensi agen. Metode getFulfillment dan updateFulfillment dapat digunakan untuk mengelola setelan fulfillment.

Untuk mengaktifkan fulfillment intent dengan konsol:

  1. Pilih Intent di menu sidebar kiri.
  2. Pilih intent.
  3. Scroll ke bawah ke bagian Fulfillment.
  4. Geser tombol Aktifkan panggilan webhook untuk intent ini ke aktif.
  5. Klik Save.

Guna mengaktifkan fulfillment untuk intent dengan API, lihat referensi intent. Tetapkan kolom webhookState ke WEBHOOK_STATE_ENABLED.

Error webhook

Jika terjadi error, layanan webhook Anda akan menampilkan salah satu kode status HTTP berikut:

  • 400 Bad Request
  • 401 Unauthorized
  • 403 Terlarang
  • 404 Tidak ditemukan
  • 500 Kesalahan server
  • 503 Service Unavailable

Dalam salah satu situasi error berikut ini, Dialogflow akan merespons pengguna akhir dengan respons bawaan yang dikonfigurasi untuk intent yang saat ini cocok:

  • Waktu tunggu respons terlampaui.
  • Kode status error diterima.
  • Respons tidak valid.
  • Layanan webhook tidak tersedia.

Selain itu, jika pencocokan intent dipicu oleh panggilan API intent deteksi, kolom status dalam respons intent deteksi akan berisi informasi error webhook. Contoh:

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

Menggunakan Cloud Functions

Ada beberapa cara untuk menggunakan Cloud Functions untuk fulfillment. Editor inline Dialogflow terintegrasi dengan Cloud Functions. Ketika Anda menggunakan editor inline untuk membuat dan mengedit kode webhook, Dialogflow akan membuat koneksi yang aman ke Cloud Function Anda.

Anda juga memiliki opsi untuk menggunakan Cloud Function yang tidak dibuat oleh editor inline (mungkin karena Anda ingin menggunakan bahasa selain Node.js). Jika Cloud Function berada dalam project yang sama dengan agen Anda, agen dapat memanggil webhook tanpa memerlukan konfigurasi khusus.

Namun, ada dua situasi yang mengharuskan Anda menyiapkan integrasi ini secara manual:

  1. Akun layanan Dialogflow Service Agent dengan alamat berikut harus ada untuk project agen Anda:
    service-agent-project-number@gcp-sa-dialogflow.iam.gserviceaccount.com
    Akun layanan khusus ini dan kunci terkait biasanya dibuat secara otomatis saat Anda membuat agen pertama untuk sebuah project. Jika agen dibuat sebelum 10 Mei 2021, Anda mungkin perlu memicu pembuatan akun layanan khusus ini dengan hal berikut:
    1. Buat agen baru untuk project.
    2. Jalankan perintah berikut:
      gcloud beta services identity create --service=dialogflow.googleapis.com --project=agent-project-id
  2. Jika fungsi webhook Anda berada di project yang berbeda dengan agen, Anda harus memberikan peran IAM Cloud Functions Invoker ke akun layanan Dialogflow Service Agent di project fungsi Anda.

Token identitas layanan

Saat Dialogflow memanggil webhook, webhook, dialog akan menyediakan token identitas Google dengan permintaan. Secara opsional, webhook apa pun dapat memvalidasi token menggunakan library klien Google atau library open source seperti github.com/googleapis/google-auth-library-nodejs. Misalnya, Anda dapat memverifikasi email token ID sebagai:

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

Sampel

Contoh berikut menunjukkan cara menerima WebhookRequest dan mengirim WebhookResponse. Contoh intent referensi ini yang dibuat di quickstart.

Go

Untuk mengautentikasi ke Dialogflow, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

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

Untuk mengautentikasi ke Dialogflow, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.


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

Untuk mengautentikasi ke Dialogflow, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

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

Untuk mengautentikasi ke Dialogflow, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

# 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