[Dialogflow v2]Google Homeで国名コード検索


BELってどこの国…?

ワールドカップ2018、とうとう終わってしまいました。個人的にはベルギー優勝!という予想でしたが、皆様の予想はいかがでしたでしょうか。

こういった国際大会を見ていると、国名がアルファベットの略記で表示されます。日本であればJPNのような。ワールドカップくらいの参加国数であれば推測できるのですが、他の大会、オリンピックともなると参加国も多数となり、「これどこの国だっけ?」とわからなくなります。
これは…Google Homeに「BELってどこの国?」と聞くと教えてくれる機能があれば便利そうだ!

というのが建前で、Dialogflowを使ってGoogle Homeの機能拡張をやったことがなかったので、ちょうどいい題材見つけた!という次第です。なので中身はほぼチュートリアル。

2018/07/19現在、少し前にDialogflowのv2が正式リリースされたからか、UIが変わって、いろいろな記事を見ても微妙に言葉遣いが違っておりました。そういった苦労をしたこともあり、今回の投稿のモチベーションにもなっています…。

大まかな流れ

Actions on GoogleとDialogflowの2つのサービスで構築します。
1. [Actions on Google] Actions on Googleにプロジェクト作成
2. [Actions on Google] Actionを作成
3. [Dialogflow] Intentで問い合わせの文言を定義
4. [Dialogflow] Entityで対応する国名コードを定義
5. [Dialogflow] Fulfillmentで国名コードに対応する国名を検索して返信
6. [Dialogflow] テスト
7. 完成!Google Homeに遊んでもらう

リリースまではしてないです。あくまで個人利用。

[Actions on Google] Actions on Googleにプロジェクト作成

プロジェクトを作成

Actions on GoogleのACTIONS CONSOLEが全てのスタートです。

Add/import projectからプロジェクトを作成します。言語、国とかお好きなものを。見かけた記事だと、以前は、言語とか国はもうちょっと後っぽかったんですが、今はこの段階で設定できます。

カテゴリの決定

このプロジェクトはどんなカテゴリか決めるらしいです。お好きなものを。スキップも可。リリースしないなら何選んでも問題ないと思ってます。

Displaynameの決定

次にこのサービスを起動するためのDisplay name(=起動ワードって理解です)を設定します。

「Decide〜」をクリックすると設定画面に飛びます。

声も決められます。MaleとFemale、それぞれ1,2。Display nameは発音を確認できるのに、Assistantの声は確認できず…

[Actions on Google] Actionを作成

次にActionを作成するらしいです。このあたりもUIが変わったみたいですね。

左のBuildの下のActionsから...

ADD YOUR FIRST ACTION。

そしてCustom intentを選んでBUILD!

これでこのプロジェクトに紐付いたDialogflowのagentの作成画面に移動します。
次からはDialogflowでの作業になります。

[Dialogflow] Intentで問い合わせの文言を定義

最初に言語してagentを生成。

今回作成するIntentは全部で4種類。

  • Welcome Intent:起動したときにしゃべるメッセージ等
  • Fallback Intent:合致するIntentが見つからない場合の処理
  • 本体:実施したい処理。今回はここに国名コードを検索して国を返すロジックを組みます。名前は「searchcode」にしました。この名前自体に意味はないですが、以降の説明でsearchcodeと出てきたら本体のIntentと読み替えてください。
  • 終了:接続を切る処理。

1,3,4は2ができれば簡単なので、説明は2にしぼります。

ちなみにIntentはドキュメントによると↓。

An intent represents a mapping between what a user says and what action should be taken by your software.

Intentの作成

左のメニューからIntentsを選んでCREATE INTENT。

画面の一番上にIntentの名前を設定できる箇所があるのでsearchcodeと設定。個人的にはちょっとわかりにくかった…SAVEボタンも上にあって少し探したりしました。

Training phrases

Google Homeへの問い合わせに使う文言を定義します。
これがUIが変わってつまづいたところです。見かけた記事によると「USER SAYS」って前は言ってたみたいですね。

Add user expressionに文言を入力してENTER。

そうすると、本体動作(Fulfillment)への入力となるパラメータが、その文言のどこかを定義するところが表示されます。今回はJPの部分。ここのJPはただの例みたいなものらしく、別になんでもよさそうです。ここに入る値はEntityで定義するようです。

問い合わせの文言は複数登録できますのでお好みで。

Action and parameters

Training phrasesのすぐ下。Fulfillmentへの入力となるパラメータの定義です。といっても上で定義したら自動で追加されてます。必要に応じてRequireとか設定するとよさそうです。
ちなみにここでもひっかかりました。ActionというのがActions on GoogleのActionと混同して、説明がどっちを指してるのか混乱しました。

ResponsesとFulfillment

このIntentの動作とその結果を定義します。Fulfillmentの中身を定義するわけではなく、このIntentが動くとFulfillmentを起動しますよ〜という設定です。通常処理はFulfillmentで完結するため、Responseは基本使われない模様。Fulfillmentがコケたときにこのメッセージが読まれるみたいです。

ちなみにWelcome、FalloutのIntentはコメントを返すだけならTraining等々はいらず、Responseだけ設定すれば動きます。
終了のIntentは、Training Phraseに終了するためのキーワード(例えばありがとう)と、その応答Response(例えばyour welcome)を登録して、Resonsesの下の「Set this intent as end of conversation」を有効にするだけです。

[Dialogflow] Entityで対応する国名コードを定義

Entityはドキュメントによると↓。

Entities are powerful tools used for extracting parameter values from natural language inputs. Any important data you want to get from a user's request, will have a corresponding entity.

パラメータに入る可能性のあるものを定義して、言い回しの違いを吸収するための設定と理解してます。今回、パラメータに入るのは国名コード。しかし、それを全部手打ちするのはつらい。CSVのアップロードで一括登録できるらしいので、Wikipediaの表をちょちょいとCSVに加工。国名コードってISOらしいんですよ、ご存知でした???

ファイル名がそのままEntityが対応するパラメータの名前になりますので、今回はcountrycode.csvとして↓のようなファイルを作成。1列目がパラメータにわたす値、2,3列目が言い回しの種類。今回は2文字、3文字に対応してみました。

これを右上のメニュー「Upload Entity」からアップロードすると…

こんな感じに一括登録できます。楽ちん。

[Dialogflow] Fulfillmentで国名コードに対応する国名を検索して返信

ここまでの設定で、Google Homeから「JPNってどこ?」と問い合わせると、JPNが本体動作:Fulfillmentに届くようになりました。次は本体動作の作成です。

左のメニューからFulfillmentを選んで、今回はInline Editor(JavaScript)を使いました。

ちなみにInline Editorで作成したコードは、FirebaseのFunctionsに自動登録されます。便利。

Inline Editorにはデフォルトの処理が既に入っているので、大枠はそれをそのまま利用します。

今回書き換えるのはyourFunctionHandler(処理は一つだけですし、めんどくさいので名前はデフォルトのまま...)。

今回は国名コード→国の名前を調べることですので、国名コードの連想配列にしてみました。
これまたWikipediaの表をちょちょいと加工してこんな記述に。地域もついでに。

そして連想配列から国名と地域を抜き出して、Google Homeに送り返す処理です。

なんか小賢しいことをいろいろやっていますが重要なのはagent.add()でGoogle Homeを喋らせられるということだけです。


agent.add(vcode + "" + db[code].name + "" + db[code].area + "です。");

最後にこの関数とIntentを結びつければおしまいです。yourFunctionHandlerのところをコメントアウトして、第一引数に本体処理のIntentの名前を書けばOKです。

最後にDEPLOY。結構時間がかかるので、慎重にやったほうがいいです。

[Dialogflow] テスト

これで設定はおしまいなのであとは挙動確認。
Dialogflowの右上の「Try it now」に「JPNってどこ?」と放り込んでやると...

JPNは日本、東アジアです。おお、そのとおり。INTENTを見ると、意図通り紐づけたINTENTが起動しています。
アマゾン川がどこにあるかわからず、中学時代に社会科の先生に笑われた地理雑魚勢なので地域も重要。今回のワールドカップもセネガルとセルビアは一瞬ウン?となりました。

ちなみにJPNが少し横にふくらんでいるのは、スペース入れて文字と文字を区切っているからです。ひっついていると英単語として読まれてしまった…

なお、プログラムがコケるとResponseに設定した文言が返されます。
その原因を探るには、このFulfillmentが動作しているFirebaseに出力されているログが役立ちます
DEPLOYの左にある「View execution logs〜」からその画面にジャンプできます。

エラーだとこんなの。このときはタイポ。お恥ずかしい限り。

ちなみにFulfillment自体見つからないときはFalloutのintentが動作します。Fallout Intentと、本体動作IntentのResponseで別の文言を指定しておくと、どっちでミスってるのかわかりやすくなります。

このログ、Request bodyというところでFulfillmentで使えるrequestの中身を見ることができたりします。便利。

完成!Google Homeに遊んでもらう

これで準備OK。あとは、このActions on Googleを作ったアカウントに紐づけたGoogle Homeに、
1. ねぇ Google
2. カントリーコードにつないで → Welcom Intentが起動
3. BELってどこ? → 本体のIntentが起動
※問い合わせは連続で実行可能。ここがGoogle Home単体よりいいところ。
4. ありがとう → 終了のIntentが起動

という感じで遊べます。

Google on Actionsにシミュレータがありますので、そちらでも遊べます。左のSimulatorからどうぞ。2文字でもちゃんと答えてくれます。RとLですごい違い…という例にしようと思いましたが、わりと近かった。

おわりに

ここまでで、Google Homeで問いかけ → 自分で作ったプログラムで処理 → 結果をGoogle Homeに返す、というサービスの基本形ができました。Fulfillmentは直接APIを叩くこともできるみたいです。そこまでこれば通常のAPI開発になりますので、一気にできることが増えそうです。振り返ってみればほとんどコード書いてない。すごいな〜

アイデア一発の国名コード検索でしたが、Actions on Google、Dialogflowのチュートリアルとしては楽しい題材という感想でした。

なお、この記事は、2018/07/19現在のUIを基に作成しています。今後の更新でUIは変わっていくはずですのでご注意を…

ちなみにオリンピックで使われるのはIOCが定義したIOCコードなのでISOの国名コードでは見つからない国もあります。
ドイツはDEU…これはわからない。 Deutschlandが由来らしいですが。

たしか日本の「ドイツ」って呼び方はこっち由来なんでしたっけ?

IOCのコードは3文字の一種類しかないため、あたかもEntityの説明用にわざわざISOのコードを使ったみたいですが、素で気づいてなかったです。ドイツが見つからないなー → もしかしてオリンピックってISOコード使ってない?と検索したら発覚したという。結果オーライ。

…CSVと連想配列作り直さなきゃ。