DialogflowのサンプルBotからエージェントのビルドとフルフィルメントのデプロイを学ぶ

Bot作成のために、GoogleのDialogflowを使ってみました。
今回、DialogflowのQuickstartドキュメントを元に、Bot作成のさわりだけを記事にまとめました。

# 環境

* Dialogflow ES

Dialogflowには、Dialogflow CX（Advanced）と Dialogflow ES（Standard）の 2 つのエディションがありますが、この記事で取り上げるのはESの方だけです。

https://cloud.google.com/dialogflow


# 対象

* Dialogflowというサービスの触りだけさらっと知りたい方
* DialogflowからAPIを利用する方法

GCPから利用する方法や、プロダクションで利用したい方向けの解説はありません。


# Dialogflowとは？
DialogflowはざっくりGoogle製のBot等が作れるサービス。

https://cloud.google.com/dialogflow/es/docs

# Quickstarts
クイックスタート

https://cloud.google.com/dialogflow/es/docs/quick

## Setup
設定

https://cloud.google.com/dialogflow/es/docs/quick/setup

クイックスタートを動作させるだけなら設定は必要ありません。
Dialogflowのコンソールにログインしてエージェントを作成すれば良いです。

Dialogflowのコンソールから[エージェント](https://cloud.google.com/dialogflow/es/docs/basics#agents)を作成すると、自動的にGCP(Google Cloud Platform)のプロジェクトが作成されます。

Dialogflowコンソールで作成したプロジェクトをGCPコンソールで確認するには、作成したエージェントの設定(歯車マーク)から、General→Project IDを確認して、そのProject IDのリンクからGCPのプロジェクトを開きます。
![スクリーンショット 2021-06-20 15.49.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/40652951-cbae-9b40-796f-b1ccdf649547.png)


フルフィルメントで APIを利用する場合の注意点は、GCP(Google Cloud Platform)の無料枠を使い切っている場合、Dialogflowのコンソールで自動で作成されるGCPのプロジェクトの課金設定をする必要があります。


## Dialogflowプロジェクトに課金を有効にする

GCP(Google Cloud Platform)のコンソールにログインします。

https://console.cloud.google.com/?hl=ja

フルフィルメントからInline Editorを選択
![スクリーンショット 2021-06-20 21.45.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/674b832a-ca7a-a0ca-f9ca-7f6a405a5b1f.png)

OPEN CLOUD CONSOLEを選択
![スクリーンショット 2021-06-20 21.45.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/1c871404-1b11-2d88-1748-fbafae2af109.png)

請求先アカウントを選択
![スクリーンショット 2021-06-20 21.46.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/35dc6646-7382-f3ac-5d33-40c440b2a69f.png)

SET ACCOUNT を押下
![スクリーンショット 2021-06-20 21.46.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/874d4565-bdfa-3e6a-71ef-04d52b099d22.png)

プロジェクトのダッシュボードに Billingが表示されます
![スクリーンショット 2021-06-20 21.47.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/8a145830-b9e0-9ba7-18ed-65f04935fe39.png)


# Build an agent
エージェントの作成

https://cloud.google.com/dialogflow/es/docs/quick/build-agent#create-an-agent

上記の手順より、エージェントを作成します。
その後、サンプルファイルをインポートします。

# Intents
インテンツ

サンプルファイルをインポートすると、デフォルトWelcomeインテントが下記のように設定されます。

![スクリーンショット 2021-06-21 8.00.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/0fa44f31-ee51-a4ee-ebc3-d4e042632355.png)


# サンプルインテントのテスト

Dialogflowコンソールの右側のシミュレータに入力すると、エージェントのテストができます。

シミュレータに入力すると、"Default Welcome Intent"の "Responses" のリストから自動で選択されてレスポンスが返されます。

![スクリーンショット 2021-06-21 8.09.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/89996fdf-a20d-437a-e962-76083b52ebcd.png)

## APIレスポンス
"DIAGNOSTIC INFO"を押下すると、APIレスポンスを確認できます。

![スクリーンショット 2021-06-21 8.08.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/06fcfb77-09bc-fb3d-b202-859fb64a9ae0.png)


# Fulfillment

フルフィルメント。

プログラムを使ってレスポンスを返すような処理を設定できます。
GCPのプロジェクトからAPIを作成しても良いのですが、今回はAPIを使った時の動きをさわりだけ確認するために、インラインエディタを利用します。

## Inline Editor

インラインエディタを使って簡単にフルフィルメントを作成できます。
インラインエディタのプログラムはNodeのみのサポートです。
ライブラリにDialogflow フルフィルメント ライブラリを利用します。

フルフィルメントからInline EditorのDISABLEDをオンにします。
![スクリーンショット 2021-06-20 21.45.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/344b8449-3549-8d5c-b59d-7e4158e8f9dd.png)

※"Billing Required" が表示されたら、GCPのコンソールから課金を有効にします。
 ![スクリーンショット 2021-06-20 21.45.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/3bcce7a6-6f55-b1f3-33d5-8c67d4596f10.png)

## デプロイ

DEPLOYを押下してサンプルコードをデプロイします。
![スクリーンショット 2021-06-17 13.33.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/04199616-a02e-0805-0981-4205da8ff3d1.png)

## デプロイの確認
デプロイが成功すると、GCPにCloud Functionsの関数として追加されます。

GCPコンソールのCloud Functionsを選択する
![スクリーンショット 2021-06-17 13.37.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/d4353570-766b-13b3-3921-f624c6b1df12.png)

Cloud Functionsの画面
![スクリーンショット 2021-06-17 13.38.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/ea43b273-f568-622c-8c11-f499b434594c.png)


## Dialogflow フルフィルメント ライブラリ

https://github.com/dialogflow/dialogflow-fulfillment-nodejs

サンプルコードで利用している、Inline Editor用のライブラリです。


# サンプルコード解説

```javascript
'use strict';

// 1. firebase-functionsライブラリを読み込みます。
// https://firebase.google.com/docs/reference/functions
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
 
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements


// 2. FirebaseでHTTPSリクエストを待ち受けます
// https://firebase.google.com/docs/reference/functions/providers_https_?hl=ja#onrequest
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {

  // https://github.com/dialogflow/dialogflow-fulfillment-nodejs/blob/master/src/dialogflow-fulfillment.js
  const agent = new WebhookClient({ request, response });
  console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
  console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
 
  function welcome(agent) {
    agent.add(`Welcome to my agent!`);
  }
 
  function fallback(agent) {
    agent.add(`I didn't understand`);
    agent.add(`I'm sorry, can you try again?`);
  }

  let intentMap = new Map();
  intentMap.set('Default Welcome Intent', welcome);
  intentMap.set('Default Fallback Intent', fallback);

  // 3. リクエストハンドラにwelcome,fallback関数をセットします。
  // https://github.com/dialogflow/dialogflow-fulfillment-nodejs/blob/master/src/dialogflow-fulfillment.js
  agent.handleRequest(intentMap);
});

```

## 1. firebase-functionsライブラリを読み込みます。

`const functions = require('firebase-functions');`

https://firebase.google.com/docs/functions?hl=ja

[Cloud FunctionsのAPI](https://cloud.google.com/functions/docs/quickstart-nodejs?hl=ja)をそのまま利用することなく、firebase SDKライブラリを利用して、Cloud Functionsの機能を実装できます。

## 2. FirebaseでHTTPSリクエストを待ち受けます

`functions.https.onRequest((request, response) => {`

https://firebase.google.com/docs/reference/functions/providers_https_?hl=ja#onrequest

HTTPSリクエストを待ち受けて、Expressサーバー形式のレスポンスを返します。


## 3. リクエストハンドラにwelcome,fallback関数をセットします。

`agent.handleRequest(intentMap);`

https://github.com/dialogflow/dialogflow-fulfillment-nodejs/blob/master/src/dialogflow-fulfillment.js

リクエストハンドラに関数をセットします。
HTTPSリクエストを受け付けた際に、ここでセットしたハンドラ関数が実行されます。

handleRequestメソッドは、webhookクライアントにコールバック関数を登録するイメージです。


# 参考

https://cloud.google.com/dialogflow/es/docs

https://firebase.google.com/docs/functions?hl=ja