みなさまこんにちは、ユニファCTOの赤沼です。先日やっと日本でも Google Home が発売されましたね。このブログを読んでいる方の中には買われた方もそれなりに多いのではないでしょうか。ユニファでも Google Home でどのぐらいのことができるのか検証してみるために、オフィス近くのビックカメラで購入してきました。普通に使っているだけでも天気やニュースを教えてくれたりと便利ではありますが、やはりエンジニアとしてはアプリを開発したり他のものと繋げてみたくなるものです。そこで今回は Google Home から使えるオリジナルのアプリを作ってみたいと思います。公式のドキュメントで紹介されているチュートリアルでは、バックエンドとして Firebase を使っていますが、それをそのままやっても面白くないので、今回は AWS Lambda でバックエンドの処理を実装してみたいと思います。
Google Home で使うアプリの構成
Google Home の中で実際に音声アシスタントとして動いているのは Google Assistant で、Apple の Siri や Amazon の Alexa に当たるものです。なので Google Home で使うアプリを作るということは、 Google Assistant 用のアプリを作るということになります。ということは Google Assistant が動いていれば、 Google Home だけでなく、 Android 端末や iOS 端末でも使うことができるということになります。
Google Assistant のアプリは Actions on Google というプラットフォーム上で開発します。主に下記のような要素から構成されています。
Actions on Google developer project
アプリのプロジェクトを管理するベースとなるもので、アプリの分析や、テストのためのシミュレータ等の機能を持っています。Action package
Google Assistant がアプリをどのように起動するかや、どのように Fulfillment を呼び出すかなどのメタデータを定義しています。Fulfillment
HTTP Web サービスとしてホストされる、アプリの実機能を提供するファンクションです。JSONベースの Actions Protocol で Google Assistant からのリクエストを受け付け、処理結果を返します。
アプリ開発方法の選択肢
Actions on Google でアプリを開発する際の開発方法の選択肢としては、下記の3つがあります。
Templates
あらかじめ用意されているテンプレートを使う方法で、クイズやフラッシュカードなどのアプリのテンプレートが用意されています。コードを書く必要がなく、 Google Spreadsheet でデータの用意だけすれば使えるので、アプリの種類がマッチするならこの方法が一番お手軽です。Dialogflow
以前は API.AI という名前だった、自然言語で会話できる bot を作るためのAPIを提供しているサービスで、2016年9月に Google に買収されました。そして最近 Dialogflow という名前に変わりました。(Introducing Dialogflow, the new name for API.AI)Dialogflow は Actions SDK を Web IDE でラップしたもので、Action package を簡単に作成、デプロイできるようになっています。また、NLUエンジンを含んでいるので、自前で自然言語解析をする必要がなくなります。Actions SDK
限られたユーザとシンプルなやりとりを行うだけの場合に選択される方法で、既に自前のNLUエンジンを持っていてそれを使いたい場合などは Actions SDK を用いて開発する必要があります。また、 Actions SDK はIDEを提供しないので、テキストエディタなどで Action package を作成し、CLIから Google Developer project へデプロイする必要があります。
今回は上記の3つの中から、Dialogflowを使う方法で実装します。
Actions on Google と Dialogflow での設定
それではアプリを作成していきます。 Actions on Google と Dialogflow での設定は、基本的にはチュートリアルで紹介されている内容を踏襲していきます。
Overview | Actions on Google | Google Developers
まず Actions on Google のコンソールにアクセスすると、プロジェクトの作成画面になりますので、+マークと Add/Import project
と書かれているところをクリックします。
するとプロジェクトの作成ダイアログが表示されますので、プロジェクト名と国・地域を選択して、 CREATE PROJECT
をクリックします。
プロジェクトが作成され、プロジェクトのOverviewの画面が表示されます。先ほど紹介した3つの開発方法のパネルが表示されますので、今回は Dialogflow のパネルの BUILD
をクリックします。
Action を追加するためのダイアログが表示されますので、 CREATE ACTIONS ON DIALOGFLOW
をクリックして、Dialogflow のコンソールへ移動します。
Dialogflow のコンソールが表示されたら、 Description にActionの内容を入力し、 DEFAULT LANGUAGE を選択して SAVE
をクリックして保存します。
すると Intents の画面が表示されます。ここでまず Fulfillment を使うためのとりあえずの設定をするため、左メニューから Fulfillment
をクリックします。
Fulfillment の画面が表示されたら、右上のトグルが DISABLED になっていますのでクリックして ENABLED に変更し、URL にとりあえずのダミーのURLを設定して、画面下部の SAVE
をクリックします。
余談ですが、 Dialogflow に名前が変更になったのと同時にこの画面に Inline Editor が用意されたので、例えばチュートリアルで紹介されていたような、テキストエディタで Function を書いて CLI で Firebase にデプロイするというようなことは、 Inline Editor のみで完結できるようになっているようです。
保存したら左メニューから Intents
をクリックして Intents の画面に移動します。
作成済みの Intent の一覧が表示されます。最初から Default Fallback Intent と Default Welcome Intent が用意されています。まずは Default Welcome Intent をクリックします。
Default Welcome Intent はユーザが Action を呼び出した際の WELCOME イベントによって最初に起動されます。各項目の設定方法の詳細はチュートリアルで紹介されているので割愛しますが、今回は下記のような内容で設定しています。保存したら再度左メニューから Intents
をクリックして Intent の一覧画面に戻ります。
次にユーザが Slack にポストしたい内容を受け取るための Intent を作成するため、画面上部の CREATE INTENT
をクリックします。
新しい Intent の作成画面が表示されたら、下記のような内容で設定します。この Intent ではユーザが話したことをそのまま Slack にポストするため、パラメータとしては @sys.any で全文を使用するようにしています。リクエストを受け取ったら Slack へ投稿するための処理を Fulfillment にリクエストするため、 Fulfillment の設定は Use webhook
を選択し、Slack にポストして処理は完結なので、 Google Assistant の設定で End conversation
にチェックを入れています。
ここまでで一旦 Actions on Google と Dialogflow コンソールでの設定は終了し、 AWS Lambda と API Gateway の設定を行います。
AWS Lambda Function の作成と API Gateway の設定
今回は AWS Lambda Function と API Gateway、 Slack の Webhook の詳しい作成方法は主題ではないので割愛しますが、まず Lambda の Function は下記のような内容で作成し、postToSlackFromGoogleHome という名前で保存しました。 SLACK_POST_URL には実際の Slack の Webhook のURLを設定してください。
#-*- coding:utf-8 -*- from urlparse import urljoin from urllib import urlencode import urllib2 as urlrequest import json import random SLACK_POST_URL = "https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX" def build_payload(message): payload = { "username": "Google Home", "text": message } return payload def post(payload): payload_json = json.dumps(payload) data = urlencode({"payload": payload_json}) req = urlrequest.Request(SLACK_POST_URL) response = urlrequest.build_opener(urlrequest.HTTPHandler()).open(req, data.encode('utf-8')).read() return response.decode('utf-8') def post_to_slack(message): payload = build_payload(message) return post(payload) def lambda_handler(event, context): return post_to_slack(event['result']['parameters']['any'])
チュートリアルで紹介されているように node.js で Fulfillment を実装する場合には Actions on Google の SDK が利用できるので、SDKが提供するメソッドでリクエスト内容を取り出したりできますが、今回は Lambda で Python による実装なので、送信されてくる JSON から目的のパラメータを取り出しています。送信されてくる JSON で使用するパラメータに関する部分を抜粋すると下記のような内容になります。 Intent の設定でパラメータとして @sys.any を指定したので、 parameters の中で any として目的の内容が送信されてきています。今回はとりあえずユーザが話した内容だけ取れれば良いので、他の部分についてはあまり調べていません。
{ "id": "7a27e8ff-4e18-4e80-89a0-141dbb3965a5", "timestamp": "2017-10-12T17:17:21.169Z", "lang": "ja", "result": { "source": "agent", "resolvedQuery": "投稿テスト", "action": "", "actionIncomplete": false, "parameters": { "any": "投稿テスト" } } }
作成した Lambda Function を API Gateway と紐づけ、API をデプロイしたら、そのURLを Dialogflow のコンソールの Fulfillment の画面で URL の項目に設定して保存します。
アップデートとテスト
ここまでで一通りの設定は終了なので、テストをしてみます。まずは Dialogflow コンソールの左メニューから Integrations
をクリックします。 Integration の一覧画面に移動したら、 Google Assistant のパネルをクリックします。
初回は下記のようなダイアログが表示されるかと思いますので、そのまま DONE
をクリックします。
Google Assistant の Integration の設定ダイアログが表示されたら、下部の TEST
をクリックすると、下記の画面のように Test now active と表示され、シミュレータでのテストができるようになりますので、 VIEW
をクリックして Actions on Google のシミュレータに移動します。
シミュレータに移動すると、 Input フォームにはあらかじめ「スラックポストにつないで」というテキストが入っているかと思いますので、Input フォームを選択して Enter します。
すると Action が起動し、右側にはリクエストの JSON の内容が表示されます。続けてユーザが話した想定の文言を Input フォームから入力して Enter します。
追加で作成した Intent の設定内容に従って処理が行われ、レスポンスが表示されます。
実際に Slack の Webhook へのリクエストも行われ、下記のように Slack にメッセージが表示されます。
これでとりあえず Google Home に話した内容を Slack にポストするアプリを作ることができました。
まとめ
今回はお試しということで、ごくシンプルな内容でテスト段階までということでしたが、 Lambda 等と連携できればそこから先は自由度高く色々なことができると思います。また、一般的に使ってもらえるようなアプリを作って公開すれば、多くのユーザに使ってもらうこともできます。会話で処理を進めるというUIは画面を使うアプリと比べて用途が絞られると思いますが、もうすぐ Google Home mini も発売されますし、色々試して新しい使い方を模索してみたいと思います。