DialogflowでLINE Botの応答をWebhookで成形してみた

DialogflowからWebhookでLINE Botの応答をWebhookで成形してみました。

# はじめに
DialogflowからLINE Botと連携する部分に関しては割愛してます。
今回はプログラム部分のみの解説です。
DialogflowにあるInline EditorからLINEに表示する部分を作成します。

ボットが反応する言葉に関しては下記のように全てDialogflowで制御しています。

<img width="1320" alt="スクリーンショット 2019-01-05 19.23.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/154355/bd5bb2e9-34ce-2993-a456-386d80619156.png">

# ポイント
Dialogflowのresponseには`fulfillmentMessages`という項目があり、その中の`Message`にLINE Botに表示させたい応答を成形して返す仕組みがあります。詳細はこちらの記述されています。

https://cloud.google.com/dialogflow-enterprise/docs/reference/rest/Shared.Types/WebhookResponse

# 1.テキストを返す
単純にテキストを返すやり方です。Inline Editorにそのまま記述してください。
Intent名は環境に応じて変更してください。

```javascript:index.js
'use strict';

const {dialogflow} = require('actions-on-google'); 
const functions = require('firebase-functions');
const app = dialogflow({debug: true}); 

// Intent名はDialogflow側で設定したものを指定します
app.intent('TextIntent', (conv, params) => 
{
    const ret = conv.json(
        JSON.stringify(
        {
            "fulfillmentText": "",
            "fulfillmentMessages": 
            [
                {
                    "text": 
                    {
                        "text": 
                        [
                            "テキスト返す1行目",
                            "テキスト返す2行目",
                            "テキスト返す3行目",
                            "テキスト返す4行目",
                        ]
                    },
                    "platform": "LINE"
                }
            ]
        })
    );
    
    return ret;
});

exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);

```

### 結果
てっきり、配列の中からランダムで表示されるかと思ったら、全部の文字が返ってきました。
![Screenshot_20190105-190518.png](https://qiita-image-store.s3.amazonaws.com/0/154355/ba4f72de-b409-0a44-d743-5c6bbc83f25f.png)

# 2.画像を返す
単純に画像を返すプログラムです。イメージのURLはご自身で用意してください。

```javascript:index.js
'use strict';

const {dialogflow} = require('actions-on-google'); 
const functions = require('firebase-functions');
const app = dialogflow({debug: true}); 

app.intent('ImageIntent', (conv, params) => 
{
    const ret = conv.json(
        JSON.stringify({
            "fulfillmentText": "",
            "fulfillmentMessages": 
            [
                {
				    "image": 
				    {
                        "imageUri": "https://画像URL.png",
                        "accessibilityText": "イメージタイトル"
				    },
                "platform": "LINE"
            }]
        })
    );
    
    return ret;
});

exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);

```

### 結果
単純に画像のみが返ってきました。`accessibilityText`は無視されてますね。
![Screenshot_20190105-190549.png](https://qiita-image-store.s3.amazonaws.com/0/154355/2cec2152-5d60-a42c-8ac8-48e7fddca67e.png)

# 3.選択肢
複数の選択肢から選ばせる場合に使います。

```javascript:index.js
'use strict';

const {dialogflow} = require('actions-on-google'); 
const functions = require('firebase-functions');
const app = dialogflow({debug: true});

app.intent('QuickRepliesIntent', (conv, params) => 
{
    const ret = conv.json(
        JSON.stringify({
            "fulfillmentText": "",
            "fulfillmentMessages": 
            [
                {
				    "quickReplies": 
				    {
					    "title": "どれが好き？4択まで",
					    "quickReplies": ["和食","洋食","中華","イタリアン"]
				    },
                    "platform": "LINE"
                }
            ]
        })
    );
    
    return ret;
});

exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);

```

### 結果
選択肢は配列で格納しますが、4つまでしか反応しませんでした。ボタンをタップするとその文字が表示されます。
![Screenshot_20190105-190626.png](https://qiita-image-store.s3.amazonaws.com/0/154355/a19c9916-6e08-4e2a-c587-57626440d4a8.png)

# 4.カスタム表示
これまで紹介したものはDialogflowで用意されているテンプレートに過ぎません。
LINE Bot Designerというツールを使えば簡単に作成することができます。
https://developers.line.biz/ja/services/bot-designer/

GUIで結果を確認しながら作れるのが良いですね。右下のJSONをコピーするだけで使えます。
<img width="1462" alt="スクリーンショット 2019-01-05 19.54.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/154355/e1f551c6-adc9-c142-b4d4-89c89ed587cf.png">

このツールを使ってリッチなものを作ってみました。

```javascript:index.js
'use strict';

const {dialogflow} = require('actions-on-google'); 
const functions = require('firebase-functions');
const app = dialogflow({debug: true}); 

app.intent('CustomIntent', (conv, params) => 
{
    const ret = conv.json(
        JSON.stringify({
            "fulfillmentText": "",
            "fulfillmentMessages": 
            [
                {
                    "payload": 
                    {
                        "line": 
                        {
                            "type": "flex",
                            "altText": "通知用メッセージ",
                            "contents": 
                            {
                                "type": "bubble",
                                "direction": "ltr",
                                "header": 
                                {
                                    "type": "box",
                                    "layout": "vertical",
                                    "contents": 
                                    [
                                        {
                                            "type": "text",
                                            "text": "りんご",
                                            "align": "center"
                                        }
                                    ]
                                },
                                "hero": 
                                {
                                    "type": "image",
                                    "url": "https://画像URL.png",
                                    "size": "full",
                                    "aspectRatio": "1.51:1",
                                    "aspectMode": "fit"
                                },
                                "body": 
                                {
                                    "type": "box",
                                    "layout": "vertical",
                                    "contents":
                                    [
                                        {
                                            "type": "text",
                                            "text": "美味しいりんごだよ",
                                            "align": "center"
                                        }
                                    ]
                                },
                                "footer": 
                                {
                                    "type": "box",
                                    "layout": "horizontal",
                                    "contents": 
                                    [
                                        {
                                            "type": "button",
                                            "action": 
                                            {
                                                "type": "message",
                                                "label": "りんごボタン",
                                                "text": "りんご"
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "platform": "LINE"
                }
            ]
        })
    );
    
    return ret;
});

exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);

```

### 結果
LINE Bot Designerで作ったものがそのまま出力されました。
ポイントは`payload`の部分に`line`を追加してその中にLINE Bot Designerで作成したJSONを記述します。

![Screenshot_20190105-190757.png](https://qiita-image-store.s3.amazonaws.com/0/154355/7c3f498a-681b-7308-5dee-fe25dc503afb.png)

# まとめ
使い慣れているDialogflowでLINE Botを連携してみたかったので色々調べてみました。
基本的にはLINE Bot Designerで作ったものを指定するほうが確実ですね。

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