Help us understand the problem. What is going on with this article?

GoogleHomeとSlackを連携させてみた

More than 1 year has passed since last update.

こんにちは、Advent Calendarの参加は初めてなので緊張しています。
@CharaDenMitz さんにお誘い頂き、書かせて頂きます。

ちなみに書く内容は今年の5月に私が所属しているギークナビという団体で開催したハッカソンで発表したプロダクトになります。
更にちなみに【増席】IoT縛りの勉強会/SIer主催 SIerIoTLT vol9@サポーターズでも登壇した内容になります。
どんだけこのネタ引っ張るんだっていうね!

作ったもの

概要

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

全体構成

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

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

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

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です。
3.png

Dialogflowの設定

Intentsの設定

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

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

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

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

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

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

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

Fulfillmentの設定

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

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

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

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

index.js はこちらのコードを流用させていただきました。
package.jsonの内容は以下の通りです。

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」を選択しました。
※他社サービスとアイコンの大きさの差が露骨~と感じますね(^○^)
7.png

選択すると以下のようなポップアップが表示されるので、「MANAGEMENT ASSISTANT APP」を選択します。
するとActions on GoogleというGoogle Assistantアプリのテストや管理が行えるコンソールが表示されます。
8.png

テストする

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

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

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

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

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

するとすぐにSlackに以下のようにPOSTされます。
11.png
テストは大丈夫そうですね。実機でもテストしてみて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を実行する際にトークンが必要なのでメモしておきます。
12.png

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', '');

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

trigger.gas
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; 
}

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

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

完成!

デモ動画はこちらになります(Youtube)

個人的にIoTは好きなんですが、回路組んだりはんだ付けしたりするのは避けて通りたい派なのでそういうのを一切使わないIoTに今後もチャレンジしていきたいです。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away