如要在正式版系統中使用執行要求,請實作並部署 Webhook 服務。如要處理完成要求,Webhook 服務必須接受 JSON 要求,並傳回本指南中指定的 JSON 回應。如要瞭解履單和 Webhook 的詳細處理流程,請參閱履單總覽文件。
Webhook 服務規定
Webhook 服務必須符合下列規定:
- 必須處理 HTTPS 要求。系統不支援 HTTP。 如果您使用 Compute 或無伺服器運算解決方案,在 Google Cloud Platform 上代管 Webhook 服務,請參閱產品說明文件,瞭解如何透過 HTTPS 提供服務。如需其他代管選項,請參閱「取得網域的安全資料傳輸層 (SSL) 憑證」。
- 要求網址必須可公開存取。
- 必須處理含有 JSON
WebhookRequest
內文的 POST 要求。 - 必須使用 JSON
WebhookRequest
WebhookResponse
內文回應要求。
驗證
請務必保護 Webhook 服務安全,確保只有您或 Dialogflow 代理程式有權提出要求。Dialogflow 支援下列驗證機制:
字詞 | 定義 |
---|---|
登入使用者名稱和密碼 | 在 Webhook 設定中,您可以指定選用的登入使用者名稱和密碼值。如果提供這項資訊,Dialogflow 會在 Webhook 要求中加入授權 HTTP 標頭。這個標頭的格式為 "authorization: Basic <base 64 encoding of the string username:password>" 。 |
驗證標頭 | 在 Webhook 設定中,您可以指定選用的 HTTP 標頭鍵/值組合。如果提供這些標頭,Dialogflow 會將其新增至 Webhook 要求。通常會提供單一鍵值對,且鍵為 authorization 。 |
Cloud Functions 內建驗證機制 | 使用 Cloud Functions 時,您可以採用內建驗證機制。如要使用這類驗證,請勿提供登入使用者名稱、登入密碼或授權標頭。如果您提供任何這類欄位,系統會使用這些欄位進行驗證,而非內建驗證。 |
服務身分權杖 | 您可以使用服務身分權杖進行驗證。如果您未提供登入使用者名稱、登入密碼或含有 authorization 鍵的標頭,Dialogflow 會自動假設應使用服務身分權杖,並在 Webhook 要求中加入授權 HTTP 標頭。這個標頭的格式為 "authorization: Bearer <identity token>" 。 |
雙向傳輸層安全標準 (TLS) 驗證 | 請參閱「雙向傳輸層安全標準 (TLS) 驗證」說明文件。 |
Webhook 要求
如果系統比對的是已設定執行要求的意圖,Dialogflow 則會將 HTTPS POST Webhook 要求傳送至 Webhook 服務。這項要求的主體是 JSON 物件,內含相符意圖的相關資訊。
除了使用者查詢內容,許多整合服務也會傳送一些使用者資訊。例如,可專門用來識別使用者的 ID。這項資訊可透過 Webhook 要求中的 originalDetectIntentRequest
欄位存取,其中會包含從整合平台傳送的資訊。
詳情請參閱 WebhookRequest
參考說明文件。
以下是範例要求:
{ "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 回應
Webhook 收到 Webhook 要求後,必須傳送 Webhook 回應。這項回應的主體是 JSON 物件,內含下列資訊:
回覆內容有以下限制:
- 如果是 Google 助理應用程式,回應必須在 10 秒內發生;至於其他所有應用程式,則應於 5 秒內進行回應,否則要求將會逾時。
- 回應大小必須小於或等於 64 KiB。
詳情請參閱 WebhookResponse
參考說明文件。
簡訊回覆
文字回覆範例:
{ "fulfillmentMessages": [ { "text": { "text": [ "Text response from webhook" ] } } ] }
卡片回應
資訊卡回覆範例:
{ "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 助理回覆
Google 助理回覆範例:
{ "payload": { "google": { "expectUserResponse": true, "richResponse": { "items": [ { "simpleResponse": { "textToSpeech": "this is a Google Assistant response" } } ] } } } }
背景資訊
設定輸出背景資訊的範例:
{ "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" } } ] }
事件
以下範例會叫用自訂事件:
{ "followupEventInput": { "name": "event-name", "languageCode": "en-US", "parameters": { "param-name": "param-value" } } }
工作階段實體
設定工作階段實體的範例:
{ "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" } ] }
自訂酬載
提供自訂酬載的範例:
{ "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 } } ] }
啟用及管理執行要求
如要使用主控台啟用及管理代理程式的執行要求,請按照下列步驟操作:
- 前往 Dialogflow ES 主控台。
- 選取代理程式。
- 選取左側欄選單中的「執行要求」。
- 將「Webhook」欄位切換為「Enabled」。
- 在表單中提供 Webhook 服務的詳細資料。 如果 Webhook 不需要驗證,請將驗證欄位保留空白。
- 按一下頁面底部的 [Save] (儲存)。
如要透過 API 啟用及管理代理程式的完成功能,請參閱代理程式參考資料。您可以使用 getFulfillment
和 updateFulfillment
方法管理出貨設定。
如要透過控制台為意圖啟用執行要求,請按照下列步驟操作:
- 選取左側欄選單中的 [Intents] (意圖)。
- 選取一個意圖。
- 向下捲動至「Fulfillment」(執行要求) 部分。
- 將「Enable webhook call for this intent」(為這個意圖啟用 Webhook 呼叫) 切換為開啟。
- 按一下 [儲存]。
如要透過 API 啟用意圖的執行要求,請參閱意圖參考資料。將 webhookState
欄位設為 WEBHOOK_STATE_ENABLED
。
Webhook 錯誤
如果 Webhook 服務發生錯誤,應傳回下列其中一個 HTTP 狀態碼:
400
不正確的要求401
未經授權403
禁止404
找不到500
伺服器錯誤503
服務無法使用
在下列任何錯誤情況下,Dialogflow 會使用目前比對到的意圖所設定的內建回應,回覆使用者:
- 回應逾時。
- 收到錯誤狀態碼。
- 回覆無效。
- Webhook 服務無法使用。
此外,如果意圖比對是由偵測意圖 API 呼叫觸發,則偵測意圖回應中的 status
欄位會包含 Webhook 錯誤資訊。例如:
"status": {
"code": 206,
"message": "Webhook call failed. <details of the error...>"
}
自動重試
Dialogflow ES 內建機制,可在發生特定 Webhook 錯誤時自動重試,以提升穩定性。系統只會重試非終端錯誤 (例如逾時或連線錯誤)。
如要降低重複呼叫的可能性:
- 設定較長的 Webhook 逾時門檻。
- 在 Webhook 邏輯中支援等冪性或重複資料刪除。
使用 Cloud Functions
您可以使用幾種方法,透過 Cloud Functions 執行完成動作。Dialogflow 內嵌編輯器與 Cloud Functions 整合。使用內嵌編輯器建立及編輯 Webhook 程式碼時,Dialogflow 會與 Cloud Function 建立安全連線。
您也可以使用不是透過內嵌編輯器建立的 Cloud Function (可能是因為您想使用 Node.js 以外的語言)。如果 Cloud Function 與代理程式位於同一個專案,代理程式即可呼叫 Webhook,不需要任何特殊設定。
不過,在下列兩種情況下,您必須手動設定這項整合:
- 代理程式專案必須有下列地址的 Dialogflow 服務代理程式
服務帳戶:
建立專案的第一個代理程式時,系統通常會自動建立這個特殊服務帳戶和相關聯的金鑰。 如果您的代理程式是在 2021 年 5 月 10 日前建立,您可能需要使用下列項目觸發建立這個特殊服務帳戶:service-agent-project-number@gcp-sa-dialogflow.iam.gserviceaccount.com
- 為專案建立新代理程式。
- 執行下列指令:
gcloud beta services identity create --service=dialogflow.googleapis.com --project=agent-project-id
- 如果 Webhook 函式與代理程式位於不同專案,您必須在函式專案中,為 Dialogflow 服務代理程式服務帳戶提供 Cloud Functions 叫用者 IAM 角色。
服務身分權杖
Dialogflow 呼叫 Webhook 時,會隨要求提供 Google 身分識別權杖。任何 Webhook 都可以選擇使用 Google 用戶端程式庫或開放原始碼程式庫 (例如 github.com/googleapis/google-auth-library-nodejs) 驗證權杖。舉例來說,您可以驗證 ID 權杖的 email
,如下所示:
service-agent-project-number@gcp-sa-dialogflow.iam.gserviceaccount.com
範例
下列範例說明如何接收 WebhookRequest
和傳送 WebhookResponse
。這些範例會參照在快速入門導覽課程中建立的意圖。
Go
如要向 Dialogflow 進行驗證,請設定應用程式預設憑證。 詳情請參閱「為本機開發環境設定驗證」。
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
如要向 Dialogflow 進行驗證,請設定應用程式預設憑證。 詳情請參閱「為本機開發環境設定驗證」。
Node.js
如要向 Dialogflow 進行驗證,請設定應用程式預設憑證。 詳情請參閱「為本機開發環境設定驗證」。
Python
如要向 Dialogflow 進行驗證,請設定應用程式預設憑證。 詳情請參閱「為本機開發環境設定驗證」。