課題
- スマートスピーカーが流行って久しいが、どれもこれも自分で話しかけないといけない。何か新着情報を知りたい時、プル型のコミュニケーションが必要
- プッシュ型で通知を受け取ろうとすると、モバイル端末かデスクトップ通知に頼るので、視覚的に把握しなければならないし、認証だなんだで情報一つ見るのに手間がかかる
- 耳という入力経路を持っているのに、耳への入力がプッシュ型ではないので、そこをなんとかしたい
解決策
- スマートスピーカーが自発的に喋ればよい
どう実現するか
検討したこと
スマートスピーカー
- 外から指示して喋ってくれるスマートスピーカーはほとんどない
- 標準機能では、カレンダー連携やリマインダーで、ある時刻になったら喋るような感じにしかできない
- Google Homeはどうやら任意の音声を再生することができるらしい
通知の受け渡し
- AWSのSQSとSNSを評価したものの、コストが高かったり、通知を受ける側がモバイルデバイスやAWS内のリソースである必要があった
- Google Cloud Pub/Subはよさそう
- 新たにPub/Subする経路を設けるよりは、普通に使っているSlackがそのまま使えればいいのではないか
誰が処理を中継するか
- ローカルマシンでDocker使う
- もしくはRaspberry Piでやる
- Google Home Notifierを試したけどどうもすんなり動かず、いろいろ手を加える必要があった。その他作るべきモノもある
最終的に実装したもの
1. Google Home - Amazon Polly - REST API
google-home-amazon-polly-bridgeを作った。
- Google Homeに喋らせる言葉を受け取るHTTP APIエンドポイント
- 諸設定と文言を受け取って、Amazon Pollyを使って音声合成
- castv2-clientとmdns-jsを使ってGoogle Homeに合成した音声を再生させる
の処理をする。
Dockerでも動くし、Raspberry Piでも動くようにした。
2. Slack - Google Home bridge
- 最小限のSlackbotをBotKitで構成
- チャンネルと通知設定の組み合わせを定義しておいて、チャンネルごとに設定通りの音声で読み上げるように 1のAPIを叩く
セットアップ方法
必要なもの
- AWSアカウントとAmazon PollyがつかえるIAMのクレデンシャル(普通は無料の範囲内)
- SlackのAPIトークン(Slack APIでAppを作成、ボット機能を有効化して
Install App
メニューのBot User OAuth Access Token
を取得) - 当然、Google Homeデバイスが1つ以上
Google Home - Amazon Polly - REST API を動かす
- google-home-amazon-polly-bridgeを入手(git cloneでもzipでもok)
Dockerの場合
-
docker build -t googlehome-polly-bridge .
でDockerイメージをビルドする -
docker run
する時に環境変数一式を渡す
docker run --net=host \
-e "AWS_ACCESS_KEY_ID=ABCDEFG" \
-e "AWS_SECRET_ACCESS_KEY=zxcvbnm1234567789asdfghjkl" \
-e "AWS_REGION=ap-northeast-1" \
-e "POLLY_LANG=ja-JP" \
-e "POLLY_VOICE=Takumi" \
-e "POLLY_TYPE=text" \
-e "POLLY_SAMPLE_RATE=22050" \
-e "HTTP_PORT=8080" \
-e "HTTP_HOST=192.168.0.2" \
-e "GOOGLE_HOME=Kitchen" \
--restart=on-failure
googlehome-polly-bridge
直接動かす場合(Raspberry Piとか)
-
.env
ファイルか環境変数で必要情報を渡せるようにしておく -
npm install
してnpm start
する
共通)設定する環境変数
変数名 | サンプル | メモ |
---|---|---|
AWS_ACCESS_KEY_ID | ABCDEFG |
AWS 認証情報 |
AWS_SECRET_ACCESS_KEY | zxcvbnm1234567789asdfghjkl |
AWS 認証情報 |
AWS_REGION | ap-northeast-1 |
AWS リージョン |
POLLY_LANG | en-GB |
Pollyの動かすときのデフォルトになる言語指定 |
POLLY_VOICE | Brian |
Pollyのデフォルトにしたい声 |
POLLY_TYPE | text |
textかssml、これもPolyのデフォルトにしたいもの |
POLLY_SAMPLE_RATE | 22050 |
Pollyで生成するオーディオのサンプルレート |
HTTP_PORT | 8080 |
APIで開放するポート |
HTTP_HOST | 192.168.0.2 |
APIを動かすホストのIPアドレス(Google Homeから見たIPアドレス) |
GOOGLE_HOME | Kitchen |
デフォルトのGoogle Home端末の名前またはIPアドレス |
基本的に設定値はこのアプリケーションがデフォルトで使う値。リクエスト時にGETパラメータで指定することで上書きできる。
Slack - Google Home bridge を動かす
- slack-google-home-bridge を入手(やはりgit cloneでもzipでも可)
-
device-settings.sample.json
を元にdevice-settings.json
を用意する。 SlackのチャネルIDとPolly用の設定の組み合わせを記述する感じ
Dockerの場合
-
docker build -t slack-google-home-bridge .
でDockerイメージをビルドする -
docker run
する時に環境変数一式を渡す
docker run --net=host \
-e "SLACK_TOKEN=abcdefg1234567890xyz" \
-e "BRIDGE_URL=http://localhost:8080/" \
--restart=on-failure
slack-google-home-bridge
直接動かす場合(Raspberry Piとか)
-
.env
ファイルか環境変数で必要情報を渡せるようにしておく -
npm install
してnpm start
する
共通)設定する環境変数
変数名 | サンプル | メモ |
---|---|---|
SLACK_TOKEN | abcdefg1234567890xyz |
Slackボット用のBot User OAuth Access Token
|
BRIDGE_URL | http://localhost:8080/ |
Google Home - Amazon Polly - REST API のエンドポイントURL |
補足
- 同じ端末上で両方動かすのであれば、
BRIDGE_URL
はlocalhostでok -
device-settings.json
の仕組み的に、1つのチャネルで1つのルールになる(ssmlとtextの使い分けとか、声を切り替えるとかはチャネル単位になる) - メッセージの組み立て、読み上げ対象の取捨選択、等は
index.js
の中のcontroller.hears()
メソッド内をいじればいくらでも可能
CircleCIのビルド結果をGoogle Homeに通知させる
-
Slack Appディレクトリへ行き、
CircleCI
を検索しインストール、連携するチャネルを指定する - インストール後に表示される指示に従ってCircleCIでプロジェクトのSettingページから、Notifications→Chat Notificationsを開く
- Slackの設定についてのボックスが表示されるので、Slackの設定後に表示されたWebhook URLをコピー&ペーストして Saveする(念のためTest Hookを押して、指定のチャンネルメッセージが来ることを確認する)
- Slack - Google Home bridge の
device-settings.json
にCircleCIの通知が来るチャンネルのIDと、読み上げ条件その他を好みに合わせて設定する(必要があればindex.js
もいじってメッセージの読み上げる箇所や表現を良い感じにする)。そしてプロセスを再起動しておく - CircleCIで適当なプロジェクトのビルドを実行してみる(通知のテスト用に、
exit 1
やexit 0
を実行するだけのワークフローを作っておくと確認できる)