LoginSignup
8
5

More than 5 years have passed since last update.

DialogflowのWebhookでカルーセル型リストのレスポンスを返す

Posted at

@radiocat さんの記事を参考にして今後発売されるスマートディスプレイに重宝しそうな
カルーセル型リスト表示をJsonレスポンス作って返してみました。

参考URL: https://qiita.com/radiocat/items/8def1d9ba0eb38b8a04e

環境

IBMクラウドにNode-REDを構築してそちらからJsonレスポンスを返すようにしました。
IBMクラウドの環境構築はこちらの資料を参考にしてください。

完成動画

スマートディスプレイが手元に無いのでAndroid携帯で試しています。

1. Dialogflowの設定

まずはDialogflowの設定を行います。

1-1. リスト表示用Intent作成

適当にIntentを作成します。
Training phrasesに「リストみせて」と入力します。最後に一番下のwebhookを有効にしています。

s100.png

1-2. リストタップ応答用Intent作成

表示されたリストをタップしたときに反応させるIntentを作成します。

s101.png

Contexts

設定項目
Add input Context actions_intent_OPTION
Add output Context actions_intent_OPTION

Events

設定項目
Add event actions_intent_OPTION

Action and parameters

設定項目
Enter action name send.action
PARAMETER NAME myVal
ENTITY @sys.any
VALUE #actions_intent_OPTION.OPTION

2. Node-REDの設定

Node-REDはこんな感じにノードを作りました。

s200.png

ノードのソースコードは以下の通り

ソースコード
[
    {
        "id": "94a2d39c.75582",
        "type": "http in",
        "z": "10d2bba3.1d0484",
        "name": "",
        "url": "/api/hello",
        "method": "post",
        "upload": false,
        "swaggerDoc": "",
        "x": 120,
        "y": 540,
        "wires": [
            [
                "d80fb5f0.3d1778"
            ]
        ]
    },
    {
        "id": "7380d152.0e70c",
        "type": "template",
        "z": "10d2bba3.1d0484",
        "name": "くだもの検索",
        "field": "payload",
        "fieldType": "msg",
        "format": "json",
        "syntax": "mustache",
        "template": "{\n    \"fulfillmentText\": \"てすと\",\n    \"payload\": {\n        \"google\": {\n            \"expectUserResponse\": true,\n            \"richResponse\": {\n                \"items\": [\n                {\n                    \"simpleResponse\" : {\n                        \"textToSpeech\": \"果物一覧\"\n                    }\n                }]\n            },\n            \"systemIntent\": \n            {\n                \"intent\": \"actions.intent.OPTION\",\n                \"data\": {\n                    \"@type\": \"type.googleapis.com/google.actions.v2.OptionValueSpec\",\n                    \"carouselSelect\": {\n                        \"items\": [\n                        {\n                            \"optionInfo\": {\n                                \"key\": \"リンゴ\"\n                            },\n                            \"description\": \"リンゴ(林檎、学名:Malus pumila)は、バラ科リンゴ属の落葉高木樹。またはその果実のこと。植物学上はセイヨウリンゴと呼ぶ。春、白または薄紅の花が咲く。果実は食用にされ、球形で甘酸っぱい。\",\n                            \"image\": {\n                                \"url\": \"https://2.bp.blogspot.com/-oTqVMb3zbQ4/UgSMNNLY2wI/AAAAAAAAW-o/4nxDWnz7YsQ/s800/fruit_apple.png\",\n                                \"accessibilityText\": \"リンゴ画像\"\n                            },\n                            \"title\": \"リンゴ\"\n                        },\n                        {\n                            \"optionInfo\": {\n                                \"key\": \"オレンジ\"\n                            },\n                            \"description\": \"オレンジ(英名: orange、学名: Citrus sinensis)はミカン科ミカン属の常緑小高木、またはその果実のこと。 (syn. C. aurantium)、柑橘類に属する。\",\n                            \"image\": {\n                                \"url\": \"https://1.bp.blogspot.com/-l61TqzrDRz8/UnyGAHKhxBI/AAAAAAAAaYs/MI7pnI28hSI/s800/cut_fruit_orange.png\",\n                                \"accessibilityText\": \"オレンジ画像\"\n                            },\n                            \"title\": \"オレンジ\"\n                        },\n                        {\n                            \"optionInfo\": {\n                                \"key\": \"バナナ\"\n                            },\n                            \"description\": \"バナナ(甘蕉、実芭蕉、英: banana [bəˈnænə, bəˈnɑːnə]、学名 Musa spp.)はバショウ科バショウ属のうち、果実を食用とする品種群の総称。また、その果実のこと。いくつかの原種から育種された多年性植物。種によっては熟すまでは毒を持つものもある。\",\n                            \"image\": {\n                                \"url\": \"https://4.bp.blogspot.com/-t3Fr_Y_xuc0/VNH6f0IGMjI/AAAAAAAArSY/Q0f6FXo84uc/s800/banana_kawa_muke.png\",\n                                \"accessibilityText\": \"バナナ画像\"\n                            },\n                            \"title\": \"バナナ\"\n                        }]\n                    }\n                }\n            }\n      \n        }\n    }\n}",
        "output": "json",
        "x": 380,
        "y": 540,
        "wires": [
            [
                "61f817a5.071628"
            ]
        ]
    },
    {
        "id": "61f817a5.071628",
        "type": "http response",
        "z": "10d2bba3.1d0484",
        "name": "",
        "statusCode": "",
        "headers": {},
        "x": 610,
        "y": 540,
        "wires": []
    },
    {
        "id": "d80fb5f0.3d1778",
        "type": "switch",
        "z": "10d2bba3.1d0484",
        "name": "actionチェック",
        "property": "payload.queryResult.action",
        "propertyType": "msg",
        "rules": [
            {
                "t": "null"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 120,
        "y": 600,
        "wires": [
            [
                "7380d152.0e70c"
            ],
            [
                "f933355a.9f15b8"
            ]
        ]
    },
    {
        "id": "f933355a.9f15b8",
        "type": "function",
        "z": "10d2bba3.1d0484",
        "name": "くだもの選択処理",
        "func": "const myVal = msg.payload.queryResult.parameters.myVal;\n\nmsg.ret = {\n    \"val\":myVal\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 390,
        "y": 600,
        "wires": [
            [
                "c93a1f69.04e0a"
            ]
        ]
    },
    {
        "id": "c93a1f69.04e0a",
        "type": "template",
        "z": "10d2bba3.1d0484",
        "name": "テキスト返す",
        "field": "payload",
        "fieldType": "msg",
        "format": "json",
        "syntax": "mustache",
        "template": "{\n    \"fulfillmentText\":\"{{ret.val}} を選択しました\"\n}",
        "output": "json",
        "x": 400,
        "y": 660,
        "wires": [
            [
                "61f817a5.071628"
            ]
        ]
    }
]

2-1. レスポンス解説

レスポンスはどのように返しているのか見ていきましょう。
果物検索のノードはtemplateノードで設定しています。中身はこんな感じです。

ポイントはcarouselSelectで、カルーセル型のリストを設定しているところです。
他のリストにしたいって人はコチラに様々な形式がありますので参照してください。

果物検索templateノード

{
    "fulfillmentText": "てすと",
    "payload": {
        "google": {
            "expectUserResponse": true,
            "richResponse": {
                "items": [
                {
                    "simpleResponse" : {
                        "textToSpeech": "果物一覧"
                    }
                }]
            },
            "systemIntent": 
            {
                "intent": "actions.intent.OPTION",
                "data": {
                    "@type": "type.googleapis.com/google.actions.v2.OptionValueSpec",
                    "carouselSelect": {
                        "items": [
                        {
                            "optionInfo": {
                                "key": "リンゴ"
                            },
                            "description": "リンゴ(林檎、学名:Malus pumila)は、バラ科リンゴ属の落葉高木樹。またはその果実のこと。植物学上はセイヨウリンゴと呼ぶ。春、白または薄紅の花が咲く。果実は食用にされ、球形で甘酸っぱい。",
                            "image": {
                                "url": "https://2.bp.blogspot.com/-oTqVMb3zbQ4/UgSMNNLY2wI/AAAAAAAAW-o/4nxDWnz7YsQ/s800/fruit_apple.png",
                                "accessibilityText": "リンゴ画像"
                            },
                            "title": "リンゴ"
                        },
                        {
                            "optionInfo": {
                                "key": "オレンジ"
                            },
                            "description": "オレンジ(英名: orange、学名: Citrus sinensis)はミカン科ミカン属の常緑小高木、またはその果実のこと。 (syn. C. aurantium)、柑橘類に属する。",
                            "image": {
                                "url": "https://1.bp.blogspot.com/-l61TqzrDRz8/UnyGAHKhxBI/AAAAAAAAaYs/MI7pnI28hSI/s800/cut_fruit_orange.png",
                                "accessibilityText": "オレンジ画像"
                            },
                            "title": "オレンジ"
                        },
                        {
                            "optionInfo": {
                                "key": "バナナ"
                            },
                            "description": "バナナ(甘蕉、実芭蕉、英: banana [bəˈnænə, bəˈnɑːnə]、学名 Musa spp.)はバショウ科バショウ属のうち、果実を食用とする品種群の総称。また、その果実のこと。いくつかの原種から育種された多年性植物。種によっては熟すまでは毒を持つものもある。",
                            "image": {
                                "url": "https://4.bp.blogspot.com/-t3Fr_Y_xuc0/VNH6f0IGMjI/AAAAAAAArSY/Q0f6FXo84uc/s800/banana_kawa_muke.png",
                                "accessibilityText": "バナナ画像"
                            },
                            "title": "バナナ"
                        }]
                    }
                }
            }

        }
    }
}

s201.jpeg
表示はこのようにされます。

2-2.選択処理

画像をタップするとactions_intent_OPTIONのイベントがDialogflowに飛んでいきます。
Contextsも同時に格納されているので、その中にあるOPTIONという部分の値をパラメータとして受け取っています。

Node-REDではfunctionノードでDialogflowからくるパラメータを取得しています。

くだもの選択処理function
const myVal = msg.payload.queryResult.parameters.myVal;

msg.ret = {
    "val":myVal
}
return msg;

最後にtemplateノードで選択した値を表示しています。

テキスト返すtemplate
{
    "fulfillmentText":"{{ret.val}} を選択しました"
}

まとめ

今後増えてくるスマートディスプレイはAndroidでいうJavaやKotlinといった専用言語での開発ではなく、
Node.jsやPythonを使ってレスポンスをJsonで返して表示する開発になります。
他にもいろんな表示形式があるので、是非試してみてください!

システム化のご検討やご相談は弊社までお問い合わせください。
https://i-enter.co.jp/contact/

8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5