Posted at

Dialogflow のチュートリアルが間違ってた話

More than 1 year has passed since last update.


はじめに

Dialogflow とは Google が提供している自然言語による対話をビルドするツールです。前々から試したいと思っていたので、今回チュートリアルを実装してみました。ところが Basic Fulfillment and Conversation Setup というパートを実装しているとき、チュートリアル通りに実装しているにも関わらずエラーが発生しました。


エラー内容

エラーが発生したのは上述のチュートリアルの最初の部分


Then create an index.js file in the project directory you just created, with the following code:


/*

* HTTP Cloud Function.
*
* @param {Object} req Cloud Function request context.
* @param {Object} res Cloud Function response context.
*/

exports.helloHttp = function helloHttp (req, res) {
response = "This is a sample response from your webhook!" //Default response from the webhook to show it's working

res.setHeader('Content-Type', 'application/json'); //Requires application/json MIME type
res.send(JSON.stringify({ "speech": response, "displayText": response
//"speech" is the spoken version of the response, "displayText" is the visual version
}));
};

というコードです。Dialogflow の agent からの問い合わせに対し、決め打ちのレスポンスを返すだけの単純なスクリプトです。しかしこれを実装し、Dialogflow のテストを行うと、こんな JSON が返ってきます(responseID など固有の値は * に置き換えています)。

{

"responseId": "**********",
"queryResult": {
"queryText": "東京の天気は",
"parameters": {
"geo-city": "東京",
"date": ""
},
"allRequiredParamsPresent": true,
"fulfillmentText": "すみません、天気は分かりません",
"fulfillmentMessages": [
{
"text": {
"text": [
"すみません、天気は分かりません"
]
}
}
],
"outputContexts": [
{
"name": "**********",
"lifespanCount": 5,
"parameters": {
"geo-city": "東京",
"date.original": "",
"date": "",
"geo-city.original": "東京"
}
}
],
"intent": {
"name": "**********",
"displayName": "AskWeatherIntent"
},
"intentDetectionConfidence": 1,
"diagnosticInfo": {
"webhook_latency_ms": 324
},
"languageCode": "ja"
},
"webhookStatus": {
"code": 3,
"message": "Webhook call failed. Error: Failed to parse webhook JSON response: Cannot find field: speech in message google.cloud.dialogflow.v2.WebhookResponse."
}
}

???なぜチュートリアル通りの実装なのにこんなことになるのか、JSON は返ってきているので関数自体は動いているはず。。。


解決策

調べたところ、以下のような記事が見つかりました。

https://stackoverflow.com/questions/48211405/what-json-response-format-to-use-for-v2beta1-fulfillment-webhook?rq=1

https://productforums.google.com/forum/#!topic/dialogflow/zWLIMnQIOP0

どうやら Dialogflow のバージョン違いにより、チュートリアルのようなレスポンスは無効なようです。正しい実装は以下のようになります。

exports.weatherWebhook = function weatherWebhook (req, res) {

response = "This is a sample response from your webhook!" //Default response from the webhook to show it's working

res.setHeader('Content-Type', 'application/json'); //Requires application/json MIME type
res.send(JSON.stringify({
"fulfillmentText": response,
}
));
};

この関数をデプロイしてテストすると、無事以下のような JSON が返ってきます。

{

"responseId": "**********",
"queryResult": {
"queryText": "東京の天気は",
"parameters": {
"date": "",
"geo-city": "東京"
},
"allRequiredParamsPresent": true,
"fulfillmentText": "This is a sample response from your webhook!",
"fulfillmentMessages": [
{
"text": {
"text": [
"This is a sample response from your webhook!"
]
}
}
],
"outputContexts": [
{
"name": "**********",
"lifespanCount": 5,
"parameters": {
"date.original": "",
"date": "",
"geo-city.original": "東京",
"geo-city": "東京"
}
}
],
"intent": {
"name": "**********",
"displayName": "AskWeatherIntent"
},
"intentDetectionConfidence": 1,
"diagnosticInfo": {
"webhook_latency_ms": 329
},
"languageCode": "ja"
},
"webhookStatus": {
"message": "Webhook execution successful"
}
}

無事サンプルを動かすことができました。


まとめ

こういうチュートリアルで詰まると混乱するので、現行のバージョンに合わせて修正してもらいたいものです。まあプログラマならちゃんとドキュメントを読め、ということかもしれませんが。。。