Google Home で「出でよシェンロン」


先日、IFTTT を使って、ツイッター上にポルンガを呼び出しました。
https://qiita.com/chibi929/items/fb580c21b7fc18411244

やっぱり、シェンロンも呼び出したいよね。ってことで、
今回は Actions on Google を使いつつ、ホログラムでシェンロンを呼び出します。

プロジェクト作成手順等、いくつもの記事で紹介があると思いますが、
自分自身の理解のため書いていきます。他記事と重複すると思いますがご了承下さい。

システム構成

本当は、電気も消したいところですが、
ハードウェアが揃ってないため電気は消せず。。。とりあえず今度作ることにします。

この辺使いました

  • Google Home / Mini
  • Actions on Google
  • Dialogflow
  • IBM Cloud (Cloud Foundry アプリ)
  • Node.js / Express
  • WebScoket
  • HTML/CSS/JS & ホログラム用CDケース

Actions on Google

プロジェクト作成

Add/import project をクリックします。

Project name , Country/region を入力し、
CREATE PROJECT をクリックします。

Dialogflow と繋げる

プロジェクトが出来ると以下のような画面が表示されます。

DialogflowBUILD をクリックします。
初めは、アカウントの設定やらパーミッションの要求やら表示されると思いますので、完了させましょう。

CREATE ACTIONS ON DIALOGFLOW を選択して Dialogflow を作成します。

Dialogflow (Step 1)

Agent 作成

Dialogflow の Project? の作成です。

各種設定を入力したら CREATE をクリック。

Intents 作成

ここで IN と OUT を作成していきます。

初期状態で何かありますが、とりあえず気にしないことにして、
CREATE INTENT をクリックします。

User says がトリガーとなり Response を返します。
入力したら SAVE をクリックします。

ここで End conversation にチェックを入れておくことで、
Google Home のやりとりはこの Intent で終了となります。
※ 終了しない場合は Google Home さんは聞き耳を立て続けてくれるのかな・・・?

Integrations

Intent が完成したら Actions on Google から使えるように Integration します。

Integrations から Google Assistant をクリックします。

ここで、初期状態から居た Default Welcome Intent がいらっしゃった。
(まだ良くわかってない)

とりあえず下側の Select intent からさっき作った Intent を選択して、
UPDATE DRAFT をクリック!

動作確認(Actions on Google)

とりあえずここまでで Hello World です。
シミュレーターで確認できます。

VISIT CONSOLE をクリックして Actions on Google の画面に遷移し、

TEST DRAFT をクリックするとシミュレーター画面に移動します。

こんな感じです。
「こんにちは!」は Default Welcome Intent ですね。

Dialogflow (Step 2)

Step 1 で作成した Intent を作り込みます。

Intent で変数的なものを使う

シェンロン以外も呼び出せるようにします。

User says を 出でよTarget のように変更し Target の部分をドラッグすると何か出てきます。
とりあえず @sys.any を選択しておきます。

すると何やらパラメーターが追加されます。
試しに Response で $any を使うと変数として扱われるようです。
@sys.any は、そのとき言った言葉が格納されるようです。

Entities 作成

パラメーター ( Target ) に使われる言葉を定義します。

シェンロンしぇんろんshenron として扱われ、
キノコ , きのこ , , 木野子kinoko として扱われるようになります。

Intent に Entity を設定

一旦、×ボタンを押してパラメーターを消しちゃいます。

再びドラッグすると先ほど作った Target が生まれているはず。

サーバーに Webhook する

さて、ここから音声入力をトリガーにサーバーを叩いてシェンロンを呼び出します。

Fulfillment を設定

ENABLED を ON にして、サーバーのURLを入れて完了。
shenrons API を叩きます。

Intent で Webhook を使う設定

今回レスポンスは Webhook に任せちゃうので消しておきます。
slot-filling は良くわかりませんが。。。とりあえず Use Webhook にチェックを入れます。

サーバー側の実装

Node.js で Express を使って実装しました。

Request

request
{
  "result": {
    "parameters": {
      "Target": "shenron" // ← ここの Key にあたる部分は Entity で作った名前
    }
  }
}

この辺を POST メソッドでハンドリングすれば良いようです。
ハンドリングしたらそれを Websocket を使ってブラウザ側へ通知します。

Response

request
{
  "speech": "レスポンス",
  "displayText": "レスポンス"
}

この辺を詰めて返せばよいようです。
今回は要らないので空文字列・・・と思ったら空だと「応答がありません」とか言われてしまったので
試しに . を入れたら無音になってくれた

  • speech は音声のレスポンス
  • displayText は文字列のレスポンス

ブラウザ側

Websocket を使ってサーバーとコネクションを張っておき、
通知が来るのを待ち続けます。

動作確認

「OK Google, テスト用アプリにつないで」
Google Home「わかりました。テストバージョンのテスト用アプリです。」
Google Home「こんにちは!」
「出でよシェンロン」

ついでに、
「出でよキノコ」

最後に

全然上手くいかないなーと思ったら、
「ideo きのこ」「医療 きのこ」「ビデオきのこ」
なぜか「塩きのこ」まで認識されました。

きっと自分の滑舌が悪いせいです。きっと。

確認の仕方は、スマホ版 Google Assitant をインストールしてきて、そいつに話しかけてみました。
文字起こししてくれるのでそれで確認できました。

なので Intent 作成時の User says には「ideo Target」とかも追加しました。

わからないこと/今後調べること

  • End conversation にチェックを入れない場合
  • 「テスト用アプリにつないで」を無しにしたい
    • publish しないとダメなのか?
  • Integration の上側 (Welcome Intent の方)
  • 「テスト用アプリにつないで」の場合、プロジェクトを2個作った場合は最後に Integration したほうが起動するのか?

参考