Slackの受信メッセージをGoogle Homeに音読してもらう

## 概要

自宅の何も会話のない空間が寂しくなったので、Slackのチャンネル上で繰り広げられる会話をGoogle Homeが音読してくれるようにしてみました。何か役に立つかというと立ちません。

ローカルPCで[Bolt](https://github.com/slackapi/bolt-js/)を動作させてSlackのイベントを受け取り、Google Homeにメッセージを送信します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43116/f2875b3d-3cbe-90db-1b93-d7ef5786d325.png)

## やったこと

### Slackアプリの設定

[Bolt入門ガイド](https://slack.dev/bolt-js/ja-jp/tutorial/getting-started)に従ってアプリを作成します。アプリにはチャンネルの内容を読み取る権限を付与しておきます。

### アプリケーションの実装

実装内容はシンプルです。

```js:app.js
const { App } = require('@slack/bolt');                
const app = new App({                                  
  token: process.env.SLACK_BOT_TOKEN,                  
  signingSecret: process.env.SLACK_SIGNING_SECRET      
});                                                    
                                                       
const googlehome = require('google-home-notifier');    
googlehome.ip('192.168.1.174', 'ja');                  
                                                       
app.message('', async ({ message, say }) => {          
  await googlehome.notify(message.text, function(res) {
    console.log(res);                                  
  });                                                  
});                                                    
                                                       
(async () => {                                         
  await app.start(process.env.PORT || 3000);           
                                                       
  console.log('⚡️ Bolt app is running!');              
})();                                                  
```

#### Slackからメッセージを受信する

[Bolt](https://github.com/SlackAPI/bolt-js)を利用します。

```sh
npm install @slack/bolt
```

下記のような処理をコマンドラインで実行し、Slackからのメッセージを受信します。`app.message()`の第一引数にある文字列がメッセージに含まれるときにハンドラが動作しますが、今回はすべてのメッセージを対象とするために空文字にしています。

```js:app.js
const { App } = require('@slack/bolt');
const app = new App({
  token: process.env.SLACK_BOT_TOKEN,
  signingSecret: process.env.SLACK_SIGNING_SECRET
});

app.message('', async ({ message, say }) => {
  // チャンネルに何らかのメッセージが投稿されたときの処理
});

(async () => {
  await app.start(process.env.PORT || 3000);

  console.log('⚡️ Bolt app is running!');
})();
```

#### Google Homeにメッセージを送信する

[google-home-notifier](https://github.com/noelportugal/google-home-notifier)を利用します。

```sh
npm install google-home-notifier
```

下記のようなスクリプトを実行するだけでGoogle Homeは語りだします。

```js:app.js
var googlehome = require('google-home-notifier');
var language = 'ja';
 
// TODO:同一ネットワーク上のGoogle HomeのIPを指定
googlehome.ip('xxx.xxx.xxx.xxx', language);
googlehome.notify('こんにちは', function(res) {                             
  console.log(res);                                                         
});
```

意図通りに動作しないときは下記の記事を参考にさせていただきました。

- [google-home-notifierで"Error: get key failed from google"とエラーが出る問題の対処法](https://qiita.com/ktetsuo/items/21f4f85a98145772be3d)
- [google-home-notifierが日本語を喋ってくれない？
](https://qiita.com/sohsatoh/items/69bcad398ffae11359f0)

### Botの起動

```sh
# 事前にSLACK_BOT_TOKENとSLACK_SIGNING_SECRETをexportしておく
node app.js
```

ローカルの3000番ポートで起動していますが、このままではSlackからのペイロードを受け取れないためngrokでプロキシを作成します。※Bolt入門ガイドの[イベントの設定](https://slack.dev/bolt-js/ja-jp/tutorial/getting-started#%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%AE%E8%A8%AD%E5%AE%9A)の項目に詳細が記載されています

```sh
ngrok http 3000
```

フォワード用のURL「[https://xxxxxxxxxxxx.ngrok.io](https://xxxxxxxxxxxx.ngrok.io)」が作成されるので、これをRequest URLに登録します。

この状態でSlackのチャンネルにメッセージを投稿すると、Google Homeが内容を音読します。

## むすび

私はお遊びで設定しましたが、急ぎの通知や家族の面倒を見るために画面を離れる必要がある場合など、何かしら使い道もあるかもしれません。

なお、ngrokは便利なサービスですが、会話の内容を外部に晒したくない場合は自前でプロキシサーバを立てるのが望ましいと思います。