GoogleAssistant向けのDicebotを作った話(1)
かねてから書きたかった技術系の記事になります。(遅い) 今回は最近自分がはまっているGoogleHomeやGoogleAssistantで使えるアクションの開発のお話をします。 簡潔にまとめようとしましたがどうしても長くなるので今回は何回かに分割して書こうと思います。
開発動機
スマートホームの勉強の一環としてやってみたかったのもあるが、一番の動機としては
GoogleHomeを買ってすぐにうきうきした気持ちで「OK,Google。100面ダイスを振って」とした時に
「3面から20面の間でサイコロを振ってください」と言われ、
「あ゛ぁ!?」となったことが原因です。
自分はTRPGも趣味で嗜んでいるので3面から20面のダイスを一つではまあ物足りないわけです。
しかも「1D6」のようなnDmの形式の発話に対応していないのでこれでは使い物にならん、じゃあ調教しようアプリ作ろう。
というのが大体の経緯です。
馴染みがない方向けに念のため解説しておくと、
nDmという表記は
「m面ダイスをn個振る」という意味です。
成果物
こんな感じで公開されております。
開発環境準備
機材
- 年代物のゲーミングノートPC(7、8年ぐらい使ってる)
- GoogleHome(あってもなくてもいい)
以上です。PCさえあればOKです。
Webブラウジングさえ出来ればなんとかなります。
自宅サーバー等もあるとより高度なことが出来ますがDicebotくらいならいらないです。
ソフト
- 特になし
VisualStudio等なくてもヨシ!
後々説明するFulfillmentを書く際はNode.jsを用いているのでjavascriptを書き慣れている方は
慣れたテキストエディタを用意するといいでしょう。
特になくてもGoogleが用意しているInlineEditorがあるのでWeb上でちょちょいと書けます。
開発開始ィ!
何を作るのか
GoogleHome向けにアプリを作る場合、
DialogFlowというGoogleが用意しているWebエディタを用いて「Agent」と呼ばれるアプリを作成します。
今回は
「1D6を振って」というような発話に対して
「1D6を振ります。(1~6)です。」と返してくれるようなアプリを作ることを考えます。
また、1D6だけでなく2D6や1D100、果ては1000D1000のような存在しない任意のダイスを振れるようにするところまでやりました。
DialogFlow
dialogflow.com
まずはここで作成するAgentの登録を行います。
使用にはGoogleアカウントが必要です。
DialogFlowの概要に関してはこちらの記事で分かりやすくまとめてくださっています。
一応当記事内でも事例を交えつつ簡単に説明していきます。
Intent
ユーザーの発話に対して、どのようなアクションを起こすか。
を決めるのが「Intent」です。(以下、Intentにマッチする。と表現します。)
今回、Intentは
- BeginIntent : OK,Google。〇〇にマッチして、挨拶をするアクション
- Default Fallback Intent : 意図しない発話が入力された際に例外のセリフを返すアクション
- MainIntent : nDm振って、にマッチしてダイスロールして結果を返すアクション
このような構成で作っています。
(本当はEndIntentを作るべきなのですが今回は割愛)
Intentの画面に行くと上図のように項目が分かれています。 項目の簡単な説明は以下の通り。
- Context:複数のIntentをまたいでフロー制御を行うためのパラメータ。
- Events:ユーザーの発話とは別に、Intentにマッチするイベントを定義します。(ex.OK,Googleに対応するWelcomeイベント)
- Training phrases:ユーザーの発話にマッチするフレーズの一例を登録する場所。ここに登録したフレーズと似た言葉が入力された時、Intentにマッチします。(Dicebotの例では「1」 D 「100」の数字部分がパラメータ)
- Action and parameters:ユーザーの発話の中の一部をパラメータとして登録できます。Training phrasesの中から任意の文字列をパラメータに登録する形です。
- Responses:ユーザーに対する返答を登録します。ここにパラメータを追加することで動的に返答を変えることも可能です。
- Fulfillment:Fulfillmentを有効にするかのチェックです。Fulfillmentに関しては後程。
これらを設定し、Intentの流れを作ることでAgentの作成を行っていきます。
Entity
Entityはユーザーの入力する単語の「分類」を定義する機能です。
例えば、「魚」のEntityとして「マグロ、サバ、サケ」という登録を行うことで、
「マグロの相場価格は?」という発話はマッチさせ、「ブリの相場価格は?」という発話をマッチさせないような設定が可能になります。
今回Dicebotでは、デフォルトで用意されているsys.numberというEntityを使い、
「"1" D "100"」の数字部分をそれぞれ
Dの前の数字(1)→dicenum
Dの後の数字(100)→dicemax
と認識させています。(下図参照)
Fulfillment
ユーザーの発話内容を解析し、結果を指定したサーバー or Googleが用意しているサーバーに送り、返答を作成する処理をしてユーザーに返す機能。
Webhook または InlineEditorのどちらかを選択可能。
- Webhook:任意のサーバーにリクエストを送ることが可能。サーバーのアドレスや認証情報、ヘッダーを指定する。サーバー内でユーザーの発話内容から返答を作成する。
- InlineEditor:Googleが用意しているサーバーにリクエストを送る。Agentを新規作成するときにデフォルトで処理が書いてあるので簡単なものであれば追記するだけで動的に返答を作成可能。
今回DicebotではInlineEditorを使用して書きました。
上で指定した、「dicenum」と「dicemax」が入力されていた場合に乱数を生成して値を返すようにしています。
思ったより長くなりそうなので、InlineEditorの使い方は別記事にまとめます。
以上が基本のDialogFlowの使い方になります。
まだまだ追記しますがDialogFlowのところ書けたので一旦公開しちゃいます。
在宅で仕事ストップしてお暇なのでガリガリ更新はする予定です。