GoogleHomeとWatsonでChatbotを作ってみた

#はじめに
・今回は、Google HomeとIBM Cloud(Watson)を使ってChatbotを作ってみようと思います。
・この記事はIBM Cloud Advent Calendarに掲載されます！
・たぶん書いてから20日もあれば先に誰かやるだろうと思ったら案の定だったけど
　[Google Home MiniとWatson Conversationを連携する](https://qiita.com/e21084/items/38e2407e3b6fff0e40f3)

#使うもの
・Actions on Google
 　　(Dialogflowを使わずActions SDKを使います)
・Node-RED on IBM Cloud
・Watson Conversation

#メモ
・Google HomeとWatsonを使ったチャットボット
・フロー作成者：夫、Qiita記事作成者：私
・WatsonのConversationのDialogエディタはフローが作りやすそうだから一度やってみたいと思ってた(夫談)

#1.固定メッセージを返すbotを作る
・「[Actions on Google](https://developers.google.com/actions/)にアクセスします。
・右上の「Actions Console」をクリックしてコンソールにアクセスします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/41fd523c-df2c-0ae8-67d1-6cca03e7baa2.png)
・Add/Import Projectをクリックして、「Project Name」と「Country/Region」を設定して「Create Project」します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/a6729866-6b5d-f6d1-636d-4c9822eff173.png)
・「Actions SDK」を選択し、Buildします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/831a1305-a6a3-6347-8292-a67f36097e43.png)
・Actions SDK Getting Started Guideに従って準備をします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/6b2007b7-819d-81be-6872-a238277787f5.png)
・基本的には、「Build」-「Create Project and Action Package」に従っていきます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/26058d4d-8c6a-6798-82bf-d76dce6f996e.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/26604804-cdb5-c566-251b-17365f028433.png)
・gactions CLIをダウンロードします。
・自分の環境にあったgactions CLIを選択し、保存します。

##Action Packageを作成する。
・gactionsが使えるようになったら、(Macの場合)ターミナルを立ち上げます。
・作業ディレクトリを作成し、```gactions init```を実行します。
・できあがったパッケージを編集します。

##Node-REDを立ち上げる
・パッケージを編集する前にIBM Cloud側の受け口を作成するために先にIBM Cloud上にNode-REDを立ち上げます。
・[IBM Cloudのコンソールにアクセス](https://console.bluemix.net)します。
・右上の「カタログ」を押すと、サービスの一覧が出てきます。
　検索窓に「Node-RED」と入力したら出てくる「Node-RED Starter」をクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/b9e2c3ae-7c0c-1a61-6bcf-ca727a3fe33d.png)
・必要な情報を入力し、全て入力し終わったら「作成」をクリックします。
　基本的には、アプリ名だけ入力すれば良いでしょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/1973774d-0a7a-3797-c8e5-1fe7060ec37e.png)
・Node-REDがデプロイされたら、「アプリURLにアクセス」をクリックします。
・Node-REDにアクセスするためのユーザー名とパスワードを設定するように求められますので設定してください。(IBM CloudのIDとパスワードと同一でなくて構いません。)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/68158372-7de8-28a6-d0ff-d235e6eb7d3c.png)
「Go to your Node-RED flow editor」をクリックして、先ほど設定したIDとパスワードを入力し、Node-REDのエディタに入ります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/717a9647-924b-a5e1-ddc6-dccefc9d4f93.png)
・「入力」から「http」ノードを選択し、フロー上の適当な場所に置きます。(左寄りがいい)
・httpノードをダブルクリックしてノードの設定画面に入ります。
　メソッドを「POST」にして、URLにGoogle Homeと通信するためのURL名を設定します。
　設定できたら「完了」を押します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/13517249-b239-cb22-8b81-b82aafca6615.png)
・「出力」から「debug」ノードを選択し、「http」ノードの右側に置きます。
　（フロー上に置いたらdebugノードの名前が変わります）
　httpノードの右端と「debug」ノードの左端を線で結びます。
・結べたら右上の「デプロイ」をクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/84f15106-3a05-a0e8-9802-ba30ceff6d3c.png)

##Action Packageを編集する
・先ほどgactionを使って作成したAction Packageを編集します。
　下のような感じにします。
　　・1行目にlocaleを指定し日本語対応させる
　　・conversationNameを設定→同じものをconversations内に記入
　　・conversations内のurlに先ほどNode-REDのhttpノードで設定したURLを記入

```javascript:actions.package
{
  "locale":"ja",
  "actions": [
    {
      "description": "Default Welcome Intent",
      "name": "MAIN",
      "fulfillment": {
        "conversationName": "watson-home"
      },
      "intent": {
        "name": "actions.intent.MAIN",
        "trigger": {
          "queryPatterns": [
            "talk to watson-home"
          ]
        }
      }
    }
  ],
  "conversations": {
    "watson-home": {
      "name": "watson-home",
      "url": "https://ymunemasa1208.mybluemix.net/entrance"
    }
  }
}
```

・できたら、Actions Packageをアップロードします。
　ターミナルに```gactions update --action_package action.json --project (あなたのプロジェクト名)```を入力します。
・認証パスとなるURLが出てくるのでブラウザでアクセスします。
・出てきたコードをターミナルに入力します。
　（コードにたどり着く前に、アカウントの選択やアクセス許可のリクエストなどを求められることがあります）
・Actions on Googleのコンソールに戻ります。
・プロジェクトを選択し、左欄の「Simulator」で実際にきちんと動作するか確かめます。
　右上のLanguageをJapaneseに変更し、Start Testingをクリックします。
　すると、テスト用の入力欄が出てくるので、何かを入力します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/3f0cebc6-08d6-8178-dca5-3aad1c98d604.png)
Node-REDの右側のデバッグ欄を見れば、Actions on GoogleからNode-REDに入力があったことが確認できるでしょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/d40f1a3e-9c65-0bc3-06bb-be5ca8eab21c.png)

##botの返答メッセージを作成する
Node-REDの「機能」から「functions」ノードを選択し、フローに置きます。
「functions」ノードをダブルクリックし、下のように入力します。

```javascript:
msg.payload=JSON.stringify({
 finalResponse:{
     richResponse: {
         items: [{
             simpleResponse: {
                 textToSpeech: 'こんにちは、ワトソンチャットボットです'
             }
         }]
     },
 }
});
msg.statusCode = 200;
return msg;
```

・「出力」から「http」ノードを選択し、「functions」ノードの右側に置きます。
　できたら、下のように線で結び、右上のデプロイを押します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/0535105c-4996-5aa6-de7d-c6cbb47faf88.png)
・再びActions on Googleでテストしてみましょう。
　下のように返ってくるでしょう。
　もし、お使いのgoogleアカウントがご自宅のGoogleHomeデバイスに接続されているならば、GoogleHomeに音声で同じようにテストしても、テキストでテストした時と同様に「こんにちは(略)」とGoogleHomeが音声で返してくれるでしょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/e7fef2d2-39c0-b641-bb07-1ba9dbb6cc4e.png)

#2.Watson Conversationサービスに接続する
##WatsonサービスをCloud Foundry(Node-RED)に接続
・IBM Cloudのコンソールに戻り、右上の「カタログ」をクリックして、検索窓からConversationを探してクリックします。
・「作成」をクリックしてサービスを立ち上げます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/5d1cb0c1-2bd3-ebb3-3ccd-abfdeb301035.png)
・サービスが立ち上がったら、左側の「接続」をクリックします。
・「接続の作成」を押して、Node-REDにWatsonサービスを接続します。
・再ステージングが走るのでしばらく待って、もう一度アクセスします。
・管理タブの「Launch tool」をクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/f6f2bc9d-993d-4c21-4d0e-cdd5138899c8.png)
・Conversationツールが立ち上がったら、Create a new workspace内のCreate＋ボタンをクリックします。
・会話フローの名前を入力し、ワークスペースを立ち上げます。
・Conversationワークスペース一覧に戻り、該当するワークスペースの右上の3つ縦に並んだ点をクリックし「View Details」を選択すると、カードが裏返り、workspaceIDが表示されるのでメモします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/d23cf9f9-5390-8e54-5dfe-b56561ec127c.png)

##Watsonノードを設置する
・Node-REDフローに戻り、「IBM Watson」から、「Conversation」ノードを選択し設置します。
　Conversationノードをダブルクリックし、先ほど得たworkspaceIDを入力します。
・Conversation IDの両脇に「機能」の「function」ノードを設置します。
　便宜上、左に置いたものの名前を「To Watson Conversation」とし、ダブルクリックして、下のコードを入力します。

```javascript:
var query = msg.payload.inputs[0].rawInputs[0].query;
msg.payload = query;
return msg;
```

Conversationノードの右に置いたものを、「Response To AoG」とし、下のコードを入力します。(適当に書きましたby夫)

```javascript:
intent = msg.payload.intents[0].intent;
response_msg = msg.payload.output.text[0];

if( intent!='goodbye' ){
    response = {
        expectUserResponse: true,
        expectedInputs: [{
            inputPrompt:{
                richInitialPrompt:{
                    items:[{
                        simpleResponse:{
                            textToSpeech: response_msg
                        }
                    }]
                }
            },
            possibleIntents:[{
                intent: "assistant.intent.action.TEXT"
            }],
            speechBiasingHints:[]
        }]
    }
}else{
    response = {
        expectUserResponse: false,
        finalResponse:{
            richResponse: {
                items: [{
                    simpleResponse: {
                        textToSpeech: response_msg
                    }
                }]
            }
        }
    }
}

msg.payload = JSON.stringify(response);
return msg;

```

終わったらデプロイを押します。
フロー全体としては以下のようになります。
(一番最初に作ったfunctionノードは使いません)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/cd8134d5-d7a7-aff1-f1e3-2906665195f1.png)

#3.Watson Conversationの会話フローを作成する
##Welcome Intentの作成
・まずはGoogle Homeの起動ワードに対応するためのIntentを作成します。
・Watson Conversationツール上でAdd Intentをクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/31f95ed4-9caf-13b0-c479-3079596caf6d.png)
・Intent nameを入力し、Create Intentをクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/2ee47726-7308-7811-abde-cdb21d2ed80c.png)
起動のキーとなるキーワードを入力し、Add Exampleをクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/648b0298-cab2-6f1c-6386-2cc03fd81083.png)
##Welcome Dialogの作成
・Dialogタブに移り、Createを押します。
・デフォルトで用意されている「ようこそ」を編集します。
・「If bot recognizes」欄を先ほど選択したwelcome Intentにします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/4f021b3e-217b-87e0-20b6-a0453fff3759.png)
##goodbye Intentの作成
・先ほどのfunctionノードの都合上「goodbye Intent」が来たら、フローを終了するという流れになっていますので、goodbye Intentを作成します。
　Google Homeとの会話を終わらせるためのキーワードをいくつか入力しておきます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/370b2a7c-fc0b-750b-aaea-e91d1eb2c4f0.png)
##goodbye Dialogの作成
・Dialogタブで新しいノードを作成します。
　「If bot recognizes」欄にgoodbye Intentを選択し、Then respond with欄にGoogle Homeにどのように返して終わって欲しいかを入力します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141025/2fb12ab8-a3ad-7a7a-4d56-82154958a140.png)
#完成・・・？
それでは、Google Homeとおしゃべりしてみましょう。
フローの通りに会話できたでしょうか！！！
今の状態では口から食べたものが即座に体外に排出されているという状態ですが、
今後の会話フローはみなさまの想像力で豊かに独創的に構築していってください。
Conversationのフローの構築の仕方はQiita内外にたくさんノウハウが落とされているので、ぜひ探してみてください！