GoogleHomeとSlackを連携させてみた

  • このエントリーをはてなブックマークに追加
  • Pocket
  • LINEで送る

こんにちは、おてらです。

第5回秋葉原IoTツアーズ開催にあたり、自宅で持て余しているGoogle Home miniを利用することにしました。

前回もGoogle Homeを使ったんですが、Google Homeに話しかけた言葉をスプレッドシートに記録するだけというめちゃくちゃシンプルな作りだったので、今回はちゃんと会話したいなぁという思いから再チャレンジすることにしました。

作ったもの

概要

おうちにいる子どもが、職場にいるパパ(ママ)とGoogle HomeとSlackを通じて会話ができるIoTを作りました。

全体構成

使っているサービスを含めた全体構成図はこんな感じです。

最初はAWSも考えましたが、Google Homeを使うならGoogleのサービスにこだわろう!という気持ちでやりました。(Slackを除く)

GCPのサービスを使っているので今回は「iot-tours2018」というGCPのプロジェクトを作成して全てこのプロジェクトに紐づけています。

GoogleHomeに話しかけた言葉をSlackにPOSTする

Google Homeに話しかけた言葉をSlackに投稿するには、Slack上のBotが必要です。

また、自然言語を解析するプラットフォームとしてはGoogleが買収したDialogflowが有名ですのでこれを使っていきます。

Slackの設定

以下のURLからSlackのBotを作成します。

https://myteam.slack.com/apps/A0F7YS25R-bots

「myteam」の部分は参加しているSlackチームのホスト名に適宜変えてください。

Botを作成したらAPIトークンをメモし、任意のチャンネルにBotを招待しておきます。Slack側の設定は一旦これでOKです。

Dialogflowの設定

Intentsの設定

Dialogflowで新たなAgentを作成したら、まずは「Intents」を作成します。

「Intents」では、どういうフレーズを受け取った時にどう認識、反応すべきかを定義します。

個人で製作したGoogle Homeアプリを呼び出すには「OK Google、○○につないで」と話しかけます。さらにアプリに繋いだ後のGoogle Homeからの応答を「Default Welcome Intent」で以下のように定義します。

「Set this intent as end of conversation」のトグルをOFFにしておくと、会話が終了せずに入力待機の状態になります。

 

続いてもう1つIntentsを追加します。

今回、受け取った言葉を丸々全てSlackにPOSTするため、以下のように例文の「こんにちは」を全て選択(ドラッグ)し、Entityに「@sys.any」をセットし、Valueを「$any」とします。

Responseにこの処理が終わったあとにGoogle Homeのレスポンス内容を設定します。ここで「$any」というパラメータを利用することが出来るので、下記の画像の例で言えば「スラックにこんにちはとポストしました」というレスポンスがなされます。

Fulfillmentの設定

「Fulfillment」は、受け取ったフレーズに対して実行する処理を定義します。

これは「Webhook」と「Inline Editor」の2種類があります。

  • Webhook … 外部のWebhookを受けられるサービスに連携、処理は外部で行う。
  • Inline Editor … FirebaseにCloud functionsがデプロイされ、そこで処理が実行される。

今回はCloud functionsを利用しましたが、Webhookを使って実行できたことも確認しています。
※AWS API Gatewayでエンドポイントを作成し、そこを経由してLambda上のスクリプトを実行させる形です。

index.js はこちらのコードを流用させていただきました。リンクはこちら

package.jsonはこんな感じです。

{
  "name": "dialogflowFirebaseFulfillment",
  "description": "This is the default fulfillment for a Dialogflow agents using Cloud Functions for Firebase",
  "version": "0.0.1",
  "private": true,
  "license": "Apache Version 2.0",
  "author": "Google Inc.",
  "engines": {
    "node": "~6.0"
  },
  "scripts": {
    "start": "firebase serve --only functions:dialogflowFirebaseFulfillment",
    "deploy": "firebase deploy --only functions:dialogflowFirebaseFulfillment"
  },
  "dependencies": {
    "slackbots": "^1.1.0", # 追加
    "actions-on-google": "^1.0.0", # 修正
    "firebase-admin": "^4.2.1",
    "firebase-functions": "^0.5.7",
    "dialogflow": "^0.1.0",
    "dialogflow-fulfillment": "0.3.0-beta.3"
  }
}

設定が完了したら「DEPLOY」を実行します。

DEPLOYを実行すると、紐づけたGCPプロジェクト内にCloud functionsが作成されます。

Integrationの設定

Integrationでは連携するサービスを選びます。今回、入力元にはGoogle Homeを使うので「Google Assistant」を選択しました。
※他社サービスとアイコンの大きさの差が露骨~と感じますね(^○^)

選択すると以下のようなポップアップが表示されるので、「MANAGEMENT ASSISTANT APP」を選択します。

するとActions on GoogleというGoogle Assistantアプリのテストや管理が行えるコンソールが表示されます。

テストする

Actions on Googleで、作成したGoogle Assistantアプリに関する情報の登録が必要なので適当に入力、設定します。
※画像を用意する必要があって意外と面倒でした。。

今回は「パパとおしゃべり」という名前のアプリケーションとして登録しました。

そして、左メニューのSimulatorで実際のやり取りをテストを行います。

「パパとおしゃべりにつないで」と発言するとアプリに繋がり、Dialogflowで設定した「スラックに何とポストしますか」とGoogle Assistantが応答を返します。

ここで「明日の晩ご飯はお好み焼きが食べたいです」と入力すると、以下のようにGoogle Assistantが返事をしてくれます。

するとすぐにSlackに以下のようにPOSTされます。

テストは大丈夫そうですね。実機でもテストしてみてSlackにPOSTされたらGoogle Home ➡ Slackは完了です!

SlackにPOSTした内容をGoogle Homeに喋らせる

Raspberry Pi3の設定

約1年ぶりにラズパイを取り出したのでまずは諸々のアップデートからw

ちなみにRaspbian Stretchにアップデートしました。

google-home-notifierをインストールする

Google Homeを喋らせるには google-home-notifier というNode.js製のパッケージを使うのが簡単で主流っぽかったのでこちらを利用しました。

google-home-notifier(Github)

まずはラズパイにNode.jsをインストール。

nvm install --lts

続いてgoogle-home-notifierをインストール。

npm install google-home-notifier

その後はGithubの記述に従って設定を進めてテストしてみます。

Google HomeのIPアドレスを確認するにはスマートフォンのGoogle Homeアプリを利用します。

$ node example.js
Endpoints:
    http://{GoogleHomeのIP}:8091/google-home-notifier
    https://xxxxx.ngrok.io/google-home-notifier
GET example:
curl -X GET https://xxxxx.ngrok.io/google-home-notifier?text=Hello+Google+Home  - to play given text
curl -X GET https://xxxxx.ngrok.io/google-home-notifier?text=http%3A%2F%2Fdomain%2Ffile.mp3 - to play from given url
POST example:
curl -X POST -d "text=Hello Google Home" https://xxxxx.ngrok.io/google-home-notifier - to play given text
curl -X POST -d "http://domain/file.mp3" https://xxxxx.ngrok.io/google-home-notifier - to play from given url

このような感じで出力されるので「http://{Google HomeのIP}:8091/google-home-notifier?text=HelloGoogleHome」にアクセスして、Google Homeが「Hello Google Home」と喋り出せばOKです。

ngrokのURLにアクセスすると外部ネットワークから実行できるので、このURLをメモしておきましょう。

ngrokのURLは実行するたびに変わってしまうので注意が必要です。(ngrokの有料プランでは固定させることが出来る様子)

Slackの設定(Outgoing Webhook)

Slackの管理画面から「Outgoing Webhook」を追加してインストールします。

チャンネルとトリガーとなるワード、Hook先のURL(後述するGoogle Apps Script)を設定します。

また、Google Apps Scriptを実行する際にトークンが必要なのでメモしておきます。

Google Apps Scriptの設定

SlackからのWebhookを受け取るGoogle Apps Scriptを設定します。

適当な名前でファイルを作成し、以下のコードで動かします。

token には先ほど取得したOutgoing Webhookのトークンを指定し、urlにはgoogle-home-notifierを起動した際に表示されるngrokのURLを指定します。

ちなみに、Outgoing Webhookをキックするためのトリガーワードである「ねぇGoogle」も読み上げてしまうため、

var text = e.parameter.text.replace('ねぇGoogle', '');

として、トリガーワードをカットしています。

function doPost(e) {
  var token = "Your Token"; 

    if (token != e.parameter.token) { 
      return; 
    } 
    var text = e.parameter.text.replace('ねぇGoogle', '');
    text = 'パパからのメッセージ' + text; 
    return request(text); 
} 


function request(text) { 

    var url = 'https://********.ngrok.io/google-home-notifier'; 
    var urlFetchOption = { 
        'method' : 'post',     
        'contentType' : 'application/x-www-form-urlencoded', 
        'payload' : { 'text' : text}  
    }; 
 
    var response = UrlFetchApp.fetch(url, urlFetchOption); 
    return response; 
}

設定したら「公開」⇒「ウェブアプリケーションとして導入」を選択し、「アプリケーションにアクセスできるユーザー」を「全員(匿名ユーザーを含む)」に設定します。

これで外部から実行できるようになります。

完成!

デモ動画になります。

おわりに

今回で5回目の開催となった秋葉原IoTツアーズですが、何だかんだ初回以外はプロダクトを完成させることが出来なかったので、さすがにそろそろ「完成できませんでした」じゃ許されないだろうな~という気持ちがあり、1週間くらい前からゴリゴリに準備していました。

インターネットに転がっている色々な先人の方々の知恵の組み合わせで今回のプロダクトを完成させたわけなんですが、結果、最優秀賞を頂きました。

ひとえに完全に自分1人で作り上げた、とは言いにくいですし、他の参加者の方々のアイディアやコンセプトも素晴らしいものばかりだったので、最優秀賞を頂くには荷が重い気持ちもありました。

ただ最近のエンジニア界隈の動向としては、1からゴリゴリコードを書く力ももちろん必要ですが、既にある色々なサービスや情報を組み合わせて新たなサービスを生み出す、といったことも重要になってきていると思います。

要は「一生懸命コード書いてこれ作りました!」っていうものでも「いやそれ○○使えばすぐじゃない?」みたいなことも増えてきてるので、そういうのを上手に使っていきたいですね。

 

秋葉原IoTツアーズに関しては秋にも開催する予定ですのでみなさまの次回のご参加をお待ちしております!!

 

最優秀賞のAmazonギフト券で何買おうかな~(*‘ω‘ *)

SNSでもご購読できます。

コメントを残す

This site uses Akismet to reduce spam. Learn how your comment data is processed.