Actions on Googleチュートリアル

:::note warn
注意：
本記事で紹介している、Actions on Googleでの3rdパーティーによるConversational Action（会話アクション）は、 2023/06/13 にサービス終了しています。
https://developers.google.com/assistant/ca-sunset?hl=ja

この記事は過去の名残りとして残しておきます。
:::

GoogleHome向けのAction（3rdパーティーアプリ）を作成してみるチュートリアルです。
初めてActionを作成する人を対象に記載しています。

# 1. 何を作成するか
- ユーザーの発話に対して答えを返すアクション(GoogleHomeでのアプリ)
- 具体的には都道府県名を言うと県庁所在地を答えてくれる

# ２． 大枠
- スマートスピーカー
    - 主にマイク、スピーカー、Wifiから構成されておりユーザーの音声をクラウドに転送、クラウドからの応答音声を再生する機能を有する
- Actions on Google
    - 自然言語理解、テキスト化、Action起動機能等を有しており、発話に対応したアクションの起動等を実行してくれる
- Dialogflow
    - 自然言語処理を提供してくるサービス
    - フレーズに応じたIntent（意図）を発動するのがメインの機能である
- Cloud Functions for Firebase
    - サーバーをプロビジョニングしたり管理しなくてもコードを実行できるコンピューティングサービス
![kenchouarch2.jpg](https://qiita-image-store.s3.amazonaws.com/0/215250/b98a9f32-1fcd-5921-0dc1-e5808c95c99d.jpeg)

Actionを一つ作るのになんだかサービスが沢山絡んでるように感じますが、それぞれのサービスは独立しており相互に依存していません。
Actions on Google的にはDialogflowを必ずしも使用する必要はなく、Converse.AIを使用したり自前意図を認識する処理等を構築することも可能です。
Dialogflow的にはActions on Google専用のサービスという訳では無くSlack等と繋げてbotの作成が可能です。(Google傘下なのでActions on Googleと親和性は高いです)
Cloud Functions for Firebaseは言わずもがな独立したサービスですね。

# 3. アカウントの設定
Googleアカウントに権限を設定する必要があります。

1. [こちら](https://myaccount.google.com/activitycontrols)にアクセス
2. 「ウェブとアプリのアクティビティ」「端末情報」「音声アクティビティ」を許可


# 4. Actionsプロジェクトの作成

1. [Actionsコンソール](https://console.actions.google.com/)にアクセス
2. 「Add/import project」を選択
3. プロジェクト名を「todoufuken」のように設定
4. 言語等を日本に設定しプロジェクトを作成
![kia001_1.png](https://qiita-image-store.s3.amazonaws.com/0/215250/773375ca-3593-0065-66a6-2ede6beb878b.png)
5. カテゴリを選択せずに「SKIP」を選択
![89da5e88f95f1996.png](https://codelabs.developers.google.com/codelabs/actions-1/img/89da5e88f95f1996.png)
6. 左側メニュー「Actions」を選択
![kia002.png](https://qiita-image-store.s3.amazonaws.com/0/215250/973c5054-90c2-0a83-fddc-76cff35465c3.png)
7. 「ADD YOUR FIRST ACTION」を選択
8. Custom intentが選択されたまま「BUILD」を選択
![1db846829fb5da10.png](https://codelabs.developers.google.com/codelabs/actions-1/img/1db846829fb5da10.png)

# 5. Dialogflowエージェントの作成

Actionsプロジェクトの作成が完了したので自然言語処理をしてくるDialogflowエージェントを関連付けする必要があります。

1.設定を日本語に変更し「CREATE」を選択
![kia003.png](https://qiita-image-store.s3.amazonaws.com/0/215250/74c816d2-7dc9-3172-3661-41691bb20058.png)

# 6. Welcome Intentの作成(編集)

- Intentとは意図を意味しており、Dialogflowの主機能としてユーザーの発話に応じたIntentを発動させる事ができます
- すべてのプロジェクトはWelcome Intentを保有している必要があります
- Welcome Intentとはユーザーがアクション名でアクションを起動した際に発動するIntentです
- DialogflowはデフォルトのWelcome Intentを自動で作成してくれるので、それをちょっと編集します

1. Intent一覧画面から「Default Welcome Intent」を選択
2. デフォルトで設定されているResponsesを削除して、「こんにちは！県庁所在地を知りたい都道府県名を言って下さい。」と入力
3. 「SAVE」ボタンを選択

# 7. シュミレータで動作確認

Actionsコンソールには各種デバイスを想定したシュミレータが用意されているので、動作確認に使ってみましょう。

1. 左側メニュー「Integrations」から「Google Assistant」を選択
![kia004.png](https://qiita-image-store.s3.amazonaws.com/0/215250/0a31a52e-8397-6f73-6f15-04bf6f48a7e7.png)
2. ダイアログが表示されるので「TEST」を選択
3. auto-preview settingsはそのまま「CONTINUE」を選択
4. シュミレータで「テスト用アプリにつないで」と入力するとアクションを呼び出す事が出来ます
![kia005.png](https://qiita-image-store.s3.amazonaws.com/0/215250/89110958-d208-e61e-526f-ef22fb9af140.png)
「REQUEST」や「RESPONSE」タブを覗いてみるとActions on GoogleとDialogflowがやり取りしている内容を見ることが出来ます。ただのJSONでありお互いが独立したサービスであるのがなんとなく分かるかと思います。

この時点で今回Actionを作成したGoogleアカウントと同一のアカウントでサインインしているデバイス（スマートスピーカーやスマホ）でも「テスト用アプリにつないで」と話しかければ動作確認が可能なはずです。


**以上でユーザーがアクションを起動してWelcome応答する部分までを作成出来ました。
次は都道府県名に応じて県庁所在地を回答する部分の作り込みを実施していきます。**

# 8. Entitiesを設定
- Intentはユーザーの意図を示しているのに対してEntitiesとは意図からパラメータを取得する方法である
- 例
    - 「テレビを５チャンネルに変えて」「テレビ５チャン」「チャンネルを５にして」
        - Intent：テレビのチャンネルを変えて欲しい
        - Entities：５
- 今回のActionではユーザーが県庁所在地を知りたい都道府県を言ってくるはずなので、Intent=県庁所在地知りたい、Entities=都道府県のように作成します
- まずは都道府県のEntitisを設定しましょう

1. 左側メニュー「Entities」から「CREATE ENTITY」を選択
![kia006.png](https://qiita-image-store.s3.amazonaws.com/0/215250/cf7a1930-d7a4-4b77-7ed5-a17e6cff7386.png)
2. 「Entity name」をprefectureに設定し都道府県データを設定
![kia007.png](https://qiita-image-store.s3.amazonaws.com/0/215250/facd707b-564f-abe7-a212-f96ac301a6df.png)
左側にパラメータ右側にそのパラメータに丸め込むためのフレーズを登録します。
都道府県だと↑位かもしれないですが、例えば帯電話の場合、左側に「携帯電話」右側に「携帯電話、携帯、スマホ、スマートフォン、アイフォン、アンドロイド」等の用になるかと思います（携丸め込みたいレベルにもよりますが）。
3. 「SAVE」を選択

# 9. 県庁所在地Intentの作成

都道府県Entityに対するIntentを作成します。

1. 左側メニュー「Intents」から「CREATE INTENT」を選択
2. 「Intent name」を「prefecture office location」に設定
3. 「Training phrases」にユーザーが発話するであろう内容を設定
![kia008.png](https://qiita-image-store.s3.amazonaws.com/0/215250/b8c127d8-7553-e025-505c-73a3ecdde7ae.png)
「神奈川県」と打つと自動的に先程作成したprefectureパラメータと紐付きます。
「神奈川県」の部分はprefectureと紐付いてますので、"prefectureでお願いします"のようなニュアンスになるので、東京でも大阪でもこのIntentが発動してくれるようになります。
4. 「Action and parameters」からパラメータを必須に設定
![kia009.png](https://qiita-image-store.s3.amazonaws.com/0/215250/ca8f823b-487c-dbdd-01b9-dff73888aae0.png)
5. 更に「Define prompts」からパラメータが渡されなかった場合の応答を設定
![kia010.png](https://qiita-image-store.s3.amazonaws.com/0/215250/a1ffd35a-0d04-b3c1-b51b-2259a4797db2.png)
この部分は今回は必須では無いですが、[Slot Filling](https://dialogflow.com/docs/concepts/slot-filling)という必要なパラメータが全部揃うまでIntentを発動しない仕組みを使う場合に設定しておきます。
6. 「Fulfillment」をEnable![kia011.png](https://qiita-image-store.s3.amazonaws.com/0/215250/941fe64e-3e60-916d-1445-5c1cfcc02877.png)
7. 「SAVE」を選択

# 10. Fulfillmentを作成

- Fulfillmentは直訳すると履行という意味である
- DialogflowがIntentを発動させた結果呼び出すWebhookである
- パラメータの違いによりユーザーに応答する内容が変化する場合や、外部のサービス等と連携する必要がある場合はDialogflow上だけでは完結しないので、Webhookを呼んでもらいそちらで処理を実行する

1. 左側メニュー「Fulfillment」を選択
2. 「Inline Editor」を有効化
![kia012.png](https://qiita-image-store.s3.amazonaws.com/0/215250/18f54697-779c-4009-1583-daca87126363.png)
3. Node.jsコードを実装

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

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

// https://developers.google.com/actions/reference/nodejsv2/overview
const app = dialogflow({debug: true});

// https://actions-on-google.github.io/actions-on-google-nodejs/classes/dialogflow.dialogflowconversation.html

// 「prefecture office location」は「9. 県庁所在地Intentの作成」で作成したIntentです。
app.intent('prefecture office location', (conv, params) => {
    var speak = "すいません、まだ対応してない都道府県です。";

    // prefectureは「8. Entitiesを設定」で作成したパラメータです。
    switch(params.prefecture) {
        case "神奈川":
            speak = "神奈川県の県庁所在地は横浜市です。";
            break;
        case "東京":
            speak = "東京都の県庁所在地は東京です。";
            break;
        case "大阪":
            speak = "大阪府の県庁所在地は大阪市です。";
            break;
        default:
            break;
    }

    conv.close(speak);
});

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

```
4. 「DEPLOY」を選択
Dialogflow上の画面で完結するのでDialogflowの機能と思うかもしれないが、「Powerd by　Cloud Functions for Firebase」と書いてあるとおり外部のサービスをDialogflowから簡単に使用出来るようにしてくれてます。

**以上で県庁所在地を答えてくれるまでの一連の処理を実装完了したのでシュミレータ等でテストしてみて下さい**



# 参考
https://codelabs.developers.google.com/codelabs/actions-1/
https://dialogflow.com/docs
https://developers.google.com/actions/extending-the-assistant