Node.js
CircleCI
Slack
Polly
GoogleHome

Google HomeにSlackのメッセージを自発的に読んでもらう(Amazon Pollyの声で)


課題


  • スマートスピーカーが流行って久しいが、どれもこれも自分で話しかけないといけない。何か新着情報を知りたい時、プル型のコミュニケーションが必要

  • プッシュ型で通知を受け取ろうとすると、モバイル端末かデスクトップ通知に頼るので、視覚的に把握しなければならないし、認証だなんだで情報一つ見るのに手間がかかる

  • 耳という入力経路を持っているのに、耳への入力がプッシュ型ではないので、そこをなんとかしたい


解決策


  • スマートスピーカーが自発的に喋ればよい


どう実現するか


検討したこと


スマートスピーカー


  • 外から指示して喋ってくれるスマートスピーカーはほとんどない

  • 標準機能では、カレンダー連携やリマインダーで、ある時刻になったら喋るような感じにしかできない

  • Google Homeはどうやら任意の音声を再生することができるらしい


通知の受け渡し


  • AWSのSQSとSNSを評価したものの、コストが高かったり、通知を受ける側がモバイルデバイスやAWS内のリソースである必要があった

  • Google Cloud Pub/Subはよさそう

  • 新たにPub/Subする経路を設けるよりは、普通に使っているSlackがそのまま使えればいいのではないか


誰が処理を中継するか


  • ローカルマシンでDocker使う

  • もしくはRaspberry Piでやる


  • Google Home Notifierを試したけどどうもすんなり動かず、いろいろ手を加える必要があった。その他作るべきモノもある


最終的に実装したもの

image.png


1. Google Home - Amazon Polly - REST API

google-home-amazon-polly-bridgeを作った。


  • Google Homeに喋らせる言葉を受け取るHTTP APIエンドポイント

  • 諸設定と文言を受け取って、Amazon Pollyを使って音声合成


  • castv2-clientmdns-jsを使ってGoogle Homeに合成した音声を再生させる

の処理をする。

Dockerでも動くし、Raspberry Piでも動くようにした。


2. Slack - Google Home bridge

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 を動かす



  1. google-home-amazon-polly-bridgeを入手(git cloneでもzipでもok)


Dockerの場合



  1. docker build -t googlehome-polly-bridge . でDockerイメージをビルドする


  2. 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とか)



  1. .env ファイルか環境変数で必要情報を渡せるようにしておく


  2. 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 を動かす



  1. slack-google-home-bridge を入手(やはりgit cloneでもzipでも可)


  2. device-settings.sample.json を元に device-settings.json を用意する。 SlackのチャネルIDとPolly用の設定の組み合わせを記述する感じ


Dockerの場合



  1. docker build -t slack-google-home-bridge . でDockerイメージをビルドする


  2. 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とか)



  1. .env ファイルか環境変数で必要情報を渡せるようにしておく


  2. 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に通知させる



  1. Slack Appディレクトリへ行き、 CircleCIを検索しインストール、連携するチャネルを指定する

  2. インストール後に表示される指示に従ってCircleCIでプロジェクトのSettingページから、Notifications→Chat Notificationsを開く

  3. Slackの設定についてのボックスが表示されるので、Slackの設定後に表示されたWebhook URLをコピー&ペーストして Saveする(念のためTest Hookを押して、指定のチャンネルメッセージが来ることを確認する)

  4. Slack - Google Home bridge の device-settings.json にCircleCIの通知が来るチャンネルのIDと、読み上げ条件その他を好みに合わせて設定する(必要があればindex.jsもいじってメッセージの読み上げる箇所や表現を良い感じにする)。そしてプロセスを再起動しておく

  5. CircleCIで適当なプロジェクトのビルドを実行してみる(通知のテスト用に、exit 1exit 0を実行するだけのワークフローを作っておくと確認できる)