SwaggerでLambdaのデバッグ環境を作る(3)：Dialogflowをデバッグする

第1回投稿で、SwaggerでLambdaのデバッグ環境を作りました。

　[SwaggerでLambdaのデバッグ環境を作る(1)](https://qiita.com/poruruba/items/e3a46787c79517a815f9)

今回はこの環境を使って、Dialogflowをローカルでデバッグしてみます。
Lambdaに配置して動作確認するトライアンドエラーは、効率は悪いので、ローカルでブレイクポイント等を活用してデバッグした方が断然効率的です。

# DialogflowのAgentを作成する

まだ作成していない場合は、DialogflowのWebコンソールから新規にAgentを作成します。

Dialogflow Console
　https://console.dialogflow.com/

適当なAgent名を付けます。例えば、「TestAgent」とします。
LANGUAGEにはJapaneseを選択します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/2632ef6e-717a-57c3-acce-c8a7fe0af64a.png)

とりあえず、適当にIntentを追加します。
例えば、「Thanks」という名前で作成し、「ありがとう」というと「どういたしまして」と返すようにしてみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/be2fb3d8-4ebb-f0b2-3c0d-325045511e5e.png)

右側にある「Try it now」に、「ありがとう」と入力すると期待通りの答えが返ってきました。

# ローカル環境に転送する

上記までは、Dialogflowの中で、決まった入力に対して、決まった出力をしました。今度はこれを、別のサーバに転送して、入力内容に従ってレスポンスを自由に定義して返すようにします。
Intentごとに、別のサーバに転送する対象を選択できます。
Intentの「Fulfillment」のところで、「Enable webhook call for this intent」を有効にすることで、このIntentが転送されるようになります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/e1453b74-91b9-990b-2dd9-718185a8c253.png)

どのサーバに転送するかどうかは、左側のナビゲータのFulfillmentで指定できます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/5473c7fc-c2f2-d4b5-735d-8c42665bc211.png)

WebhookをEnableにして、URLに転送先のURLを指定します。
ここで指定するURLはこれから立ち上げるローカルデバッグ環境のエンドポイントと同じにする必要がありますので、覚えておきます。

# ローカルデバッグ環境にエンドポイントを作成する

それでは、Dialogflowからの転送を受け付けるエンドポイントを作成していきます。

まずは、Swagger定義ファイルに、エンドポイントを定義します。
今回は、「test-dialogflow」としました。

```:swagger.yaml
・・・
  /test-dialogflow:
    post:
      x-swagger-router-controller: routing
      operationId: test-dialogflow
      parameters:
        - in: body
          name: body
          schema:
            $ref: "#/definitions/CommonRequest"
      responses:
        200:
          description: Success
          schema:
            $ref: "#/definitions/CommonResponse"
・・・
```

次に、api/conntrollers/routing.jsに、実装の場所を指定します。

```:routing.js
const func_table = {
"test-dialogflow" : require('./test-dialogflow').fulfillment,
};
```

次は実装に入るのですが、DialogflowのAgentの開発に有用なnpmライブラリを使いましょう。

> npm install --save actions-on-google

それでは実装に入ります。以下のフォルダとファイルを作成します。

　api/controllers/test-dialogflow/index.js

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

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

app.intent('Thanks', (conv) =>{
    conv.ask('こちらこそ');
});

exports.fulfillment = app;
```

app.intentの第一引数に、Intent名を指定することで、このIntentの転送を受け取ることができます。
ここら辺のお作法は、actions-on-googleで決まっています。
処理内容は、単に「こちらこそ」と返すだけです。

それでは、ローカルデバッグ環境を再起動してみます。
Visual Studio Codeであれば、右上の丸い矢印のマークをクリックすることで、再起動されます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/7ddf0b85-a958-b9e2-a7bb-514fcfbe6abc.png)

もう一度、Dialogflowの右上の「Try it now」から「ありがとう」と入力してみると、ローカルデバッグ環境に転送され、ブレイクポイントを入れておけばそこで止まることがわかるかと思います。
継続すると、Dialogflowに、今度は「こちらこそ」と返ってきます。


# Lambdaにアップロードする

無事に動作が確認できたので、Lambdaにアップロードしてみましょう。
今回は、actoins-on-googleのnpmモジュールを使っているので、それらを含めてZIP化してアップロードします。

api/controllers/test-dialogflow のフォルダに移動します。

以下のように実行します。

> npm init -y
> npm install --save actions-on-google

（またactoins-on-googleをインストールするの？と思われるのかもしれませんが、ここで行っているのは、アップロードするZIPにこのモジュールを含めるためのものです。ローカルデバッグ環境で実行しているときにはここでインストールしたモジュールは使われません。）

そして、そのフォルダにあるすべてのファイルをZIPで固めておきます。

次に、AWSのWebコンソールから、Lambda関数を作成します。
例えば、名前を「test-dialogflow」とします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/091bd1d4-467c-e4e2-e8e9-23db2aad6555.png)

関数のコード、のところで、まずは、ハンドラを「index.fulfillment」に変更します。次に、作成したZIPファイルを選択して、アップロードします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/d2b19f07-d2b9-3706-1274-d0a7a7e65507.png)

次は、API Gatewayでエンドポイントを設定します。
Swagger定義ファイルからエンドポイントを作ってもよいのですが、今回は手動でエンドポイントを追加します。
「リソースの作成」を選択して、リソース名として例えば「test-dialogflow」を指定します。API Gateway CORSを有効にする、にチェックを入れます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/9d228a5e-eaab-1d7a-9c00-fe16fb5c7439.png)

できあがった「test-dialogflow」にPOSTメソッドを追加します。
Lambdaプロキシ統合の使用にチェックを入れ、Lambda関数には作成した関数「test-dialogflow」を指定します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/58bbaa8e-eb0e-01f4-bbe2-a9aff1475c20.png)

最後に、「APIのデプロイ」を実行します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/600fa5fc-87ba-54fa-cbb5-1047752ef7ca.png)

ステージとして表示されるURLに、先ほど作成したエンドポイント名「test-dialogflow」をくっつけたURLを覚えておきます。

# DialogflowからLambdaを呼ぶようにする

次に、Dialogflow Consoleに戻ります。
設定するところは、FulfillmentのWebhookです。

WebhookのURLにさきほどのAPI GatewayのURL＋/test-dialogflowに書き換えます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/2387db81-e1e4-0a1c-1949-3f5994d95154.png)

もう一度、右上の「Try it now」のところに、「ありがとう」と入力すると、「こちらこそ」と返ってくれば成功です。

# Googleアシスタントで試す

最後に、Googleアシスタントで試してみます。

Dialogflowの左側のナビゲーションから「Integrations」を選択し、「Google Assistant」を選択するため、「INTEGRATION SETTINGS」をクリックします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/d84441ff-ef32-d3c5-5b9c-ab2ed2536329.png)

そのあとに表示されるダイアログボックスで、TESTをクリックします。
その時、Auto-preview changesをOnにしておくと便利です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/c3d1c757-6889-2bdc-387f-764979bfbd42.png)

Google Assistantのエミュレータが立ち上がります。
ここで、「テスト用アプリにつないで」、「ありがとう」というと、「こちらこそ」と返ってくるはずです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/413fa9c4-ad6d-455b-cab5-608e98e10df6.png)

エミュレータでは動作したので、Androidでやってみます。
Androidのホームボタンを長押しして、Googleアシスタントを立ち上げてください。
ここでも同じように、「テスト用アプリにつないで」、「ありがとう」というと、「こちらこそ」と返ってくるはずです。

（ちなみに、まだテスト状態ですので、Dialogflowと同じGoogleアカウントでGoogleアシスタントを立ち上げる必要があります。）

![image.png](https://qiita-image-store.s3.amazonaws.com/0/261826/afc6c168-f0f4-80f7-b9cc-95abcff6ec86.png)

以上です。