Posted at

Google Homeに命令する

More than 1 year has passed since last update.


はじめに

もうだいぶ語られてる感じはありますが、Google Homeにカスタムの命令をする方法について、自分の調べたことをまとめます。


Google Homeにカスタムの命令をする

Google Homeにカスタムの命令をし、それを解釈させる方法としては、以下の2つがあります。


  • IFTTT

  • Actions on Google - Dialogflow


IFTTT

IFTTTについては他の用途で使っている方も多いのではないでしょうか。簡単に言うと、複数のウェブサービスを連携させるサービスです。

トリガとしてGoogle Assistantを設定できるので、アクションとして命令に応えるものを選べば完成です。


利点


  • シンプルで、利用経験のある場合も多く、学習コストが低い

  • 所望のアクションがIFTTTにある場合はそれを使えば済む


欠点


  • あまり複雑な命令はできない

  • レイテンシが相対的に低い(らしい)

レイテンシの低さは非常に感じるところですが、Actions on Googleにして改善されるかどうかは試していません。


Actions on Google - Dialogflow

よくわかっていないのですが、Dialogflowで命令を処理するアプリケーションを作成し、Actions on Googleによって、作成したアプリケーションをGoogle Assistantから利用するという関係のようです。


利点


  • 複雑な命令を処理できる

  • レイテンシが高い(らしい)

  • 目的のためにWebHookを開発する必要がある場合には、Cloud Functions for Firebaseをインラインで編集できて便利かも


    • ただし、Cloud Functions for Firebaseから外部リソースを利用する場合は、有料プランでなければならない



単語や表現のゆれを吸収できるアプリケーションが作成できます。また、Dialogflowはその名の通り対話を通して要求を理解することもできます。


欠点


  • 学習コストが高い

  • 外部連携の手段はWebHookしかない

その他、ウェイクワードは1回言うだけで済むという点もあります。最初にウェイクワードを使ってGoogle Assistantにアプリケーションを起動するように言い、そこからはアプリケーションとの対話に移るためです。これは立て続けに命令したいときにはいいですが、単発の命令の場合にも2回のやりとりが必要です。また関係ない発話も拾ってしまうので、一長一短と言えるでしょう。


ホームネットワークにアクセスさせる

Google Homeに命令してやらせたいこととして、家電を操作するなど、ホームネットワークにアクセスすることは多いと思います。

その場合IFTTTまたはDialogflowのWebHookからホームネットワーク内に連携させる必要があるかもしれません。その手段としては以下の2つがあるようです。


  • ngrok

  • Firebase


ngrok

ngrokを使うとローカルのサーバにNATしてくれるようなグローバルのHTTPSサーバが払い出されます。まさにうってつけですね。


利点


  • やりたいことに対して明快

  • 認証も簡単(多分)


欠点


  • グローバルホスト名が起動のたびに変わる。これを固定するには有料プランでなければならない


Firebase

Firebaseは、ここではリアルタイムデータベースに焦点を当てて利用します。

WebHookからRESTにてデータを更新。ローカルのサーバは予めそのデータをリッスンしておき、更新されたら即座に検知して動作。という感じですね。


利点


  • このくらいのユースケースなら無料で賄える


欠点


  • WebHookから認証してデータを変更することは単独では不可能


認証

FirebaseをRESTで使うときの認証方法はここに書いてあるのですが、結論としてはWebHookで通すのは無理です。

従って、認証してFirebaseを更新するAPIを作り、WebHookでそのAPIに認証情報を送るという方法が考えられます。

ではそのAPIを何処でホストするかですが、これはCloud Functions for Firebaseがちょうどよいのではないかと思います。例えば以下のような感じ。

const functions = require('firebase-functions');

const firebase = require('firebase');

// Initialize Firebase
var config = {
// プロジェクトのコンフィグをコピペ
};
firebase.initializeApp(config);
var auth = firebase.auth();

exports.test = functions.https.onRequest((request, response) => {
const username = request.body.username;
const password = request.body.password;
auth.signInWithEmailAndPassword(username, password).then(user => {
// 処理
}).then(() => {
return auth.signOut();
});
// ...
});


google Homeに喋らせる

google Homeに喋らせたい場合、Node.jsパッケージのgoogle-home-notifierがあります。他言語でもあると思いますがちゃんと調べていません。

Actions on Googleを使って命令を受けさせているなら、WebHookの応答を真面目に作り込めば、音声で回答させることも出来るはず。


まとめ

以上調査して、自分は「google Homeに服装指数を聞くと答えてくれる」というアプリケーションを以下の組み合わせで作りました。


  • IFTTTで要求をキャッチしてCloud Functions for FirebaseのHTTPトリガを呼び出す

  • Cloud Functions for FirebaseがFirebase Databaseを更新

  • Firebase Databaseの更新を検知したアプリケーション@自宅サーバが服装指数を取得してGoogle Homeに喋らせる

レイテンシの低さ以外は概ね満足しています。

音声で聞いて音声で返っているので、DialogFlowがベストだと思います。DialogFlowを使うならばFirebaseは使わないので、認証の問題もなくなります。

学習コストと、2回やり取りしなければいけない点がどうにかなれば……


参考にした情報

色々見すぎて挙げきれないです。