Google Assistantでは応答メッセージだけを返すSimple Responses以外に、スマホの画面向けに画像やURLのリンクを付けた応答メッセージ返すRich Responsesという種類のレスポンスがあります。
詳細は公式ドキュメントを参照。
Responses | Actions on Google | Google Developers
Basic Cardの場合、このように応答メッセージに加えてサイトの情報を表示してリンク先に誘導することができます。
DialogflowのWebhookでこのような応答を作る場合、大きく2種類の手段があります。
- Firebaseで用意されているNodeのライブラリを使う
- 自前でJsonのレスポンスを作って返す
今回は(Firebaseを使わなかったので)後者の手段を選びたかったのですが、Dialogflowのドキュメントにはあまり説明が書かれておらず少し苦労したのでまとめます。
Simple Responsesの場合は以下のように speech
と displayText
にメッセージを入れて返すだけです。
response.setHeader("Content-Type", "application/json")
response.send(JSON.stringify({'speech':"これはテストです",'displayText':"これはテストです"})
しかし、Rich Responsesのほうは上記Dialogflowのドキュメントによると書式付きメッセージということになるのでおそらく data
にJsonオブジェクトを作って返してやる必要がありますが、あまり説明がありません。DialogflowはSlackやFaebookとも連携できる仕組みなのでそれぞれのサービスに合わせるということだとは思いますが、フォーラムでもうまくいかないということで議論されているようです。
Google Assistant rich message responses - Integrations - Dialogflow (API.AI) Forums
このフォーラムの内容を参考に以下の記述でBasic Cardを作ることができました。上記で紹介した Action on Googleの公式ドキュメント のBasic Cardのところで書かれているサンプルコードを当てはめると以下のようになります。
response.setHeader("Content-Type", "application/json")
response.send(
JSON.stringify({
"speech": "This is a simple response for a carousel",
"data": {
"google": {
"expectUserResponse": true,
"richResponse": {
"items": [
{
"simpleResponse": {
"textToSpeech": "This is a simple response for a carousel"
}
},
{
"basicCard": {
"title": "Math & prime numbers",
"formattedText": "42 is an even composite number. It\n is composed of three distinct prime numbers multiplied together. It\n has a total of eight divisors. 42 is an abundant number, because the\n sum of its proper divisors 54 is greater than itself. To count from\n 1 to 42 would take you about twenty-one…",
"image": {
"url": "https://example.google.com/42.png",
"accessibilityText": "Image alternate text"
},
"buttons": [
{
"title": "Read more",
"openUrlAction": {
"url": "https://example.google.com/mathandprimes"
}
}
]
}
}
],
"suggestions": []
}
},
"possibleIntents": [
{
"intent": "actions.intent.TEXT"
}
]
}
})
);
Simple Responsesの場合とは違い、 displayText
は指定せず、 data
の中に google.richResponse.items
という配列を作り、その中に displayText
相当の
simpleResponse
を作り、 basicCard
を追加します。 List Selector
などの他の種類のレスポンスも同じように実現できると思われます(試してませんが)。
フォーラムに書かれている このコメント を参考にしました。