LINE BotへのメッセージをGoogle Homeに喋らせてみる

![System](https://storage.googleapis.com/zenn-user-upload/265e20e3b4a0-20231103.png)
LINE Botにメッセージを送るとGoogle Homeが送信内容を読み上げてくれるようにします。
パソコン上にサーバーをNode.jsで建てます。

## GoogleHomeを喋らせる

https://github.com/mihyaeru21/google-home-player

人気だったGoogle Home Notifierが使えないので、Google Home Playerというものを使います。
まずnpmでGoogle Home Playerをインストールしましょう。

```shell
$ npm install google-home-player
```

Google Homeアプリを開き、デバイス情報の一番下からIPアドレスを確認しておきます。
![HomeApp](https://storage.googleapis.com/zenn-user-upload/55c1107b8769-20231103.png)
以下のコードのIPアドレスを書き換えれば、もうGoogle Homeが喋ります。

```js
// インポート
import HomePlayer from "google-home-player";

// 初期設定
const ip = "192.168.x.x"; // GoogleHomeのIPアドレス
const lang = "ja";
const Home = new HomePlayer(ip, lang);

// 読み上げ
Home.say("こんにちは");
```
# LINEBot
## LINEBotを作成

https://manager.line.biz

こちらのサイトからLINE Botを作成してください。
![LINEBot](https://storage.googleapis.com/zenn-user-upload/e800bdeef0cb-20231103.png)
応答設定はすべてオフにしておきましょう。
また、「Messaging API」タブから「Messaging APIを利用する」を押して設定しておいてください。

### LINEBotのコード
Node.jsでサーバーを建てられるExpressとLINEBotを操作する@line/bot-sdkライブラリを入れます。

```shell
npm install @line/bot-sdk express
```

https://developers.line.biz

上のサイトでトークンを取得しましょう。コンソールから現在のLINEBotを選択して「チャネル基本設定」タブからチャネルシークレットを、「Messaging API設定」タブからチャネルアクセストークンを発行してそれぞれ以下のコードに張り付けてください。

```js
// インポート
import express from "express";
import { Client, middleware } from "@line/bot-sdk";

// トークン
const config = {
  channelSecret: "チャネルシークレット",
  channelAccessToken:
    "チャネルアクセストークン",
};
const client = new Client(config);

// Webhook
const PORT = process.env.PORT || 3000;
const app = express();
app.post("/", middleware(config), (req, res) => {
  Promise.all(req.body.events.map(handleEvent)).then((result) =>
    res.json(result)
  );
});
app.listen(PORT);

// 受け取り
function handleEvent(event) {
  let Message = event.message.text;
  console.log(Message);
}
```
### サーバーを公開
現時点ではLINEBotとサーバーの紐づけができていないので、サーバーを公開します。
今回は一番楽なNgrokを使用します。

https://ngrok.com

公式サイトでSignupしてくください。
![Ngrok](https://storage.googleapis.com/zenn-user-upload/a3a6cba2db04-20231103.png)
Ngrokをダウンロードして、exeを実行して公式サイトでコピーしたシェルを実行してAuthtokenを追加してください。

```shell
$ ngrok config add-authtoken xxxxxxxxxxxxxxxxxxxxxxx
```

次にhttpでサーバーを公開します。今回はポート3000番を指定したので3000を公開します。

```shell
$ ngrok http 3000
```

「Forwarding」に表示されているURLを先ほどのLINE Developersから「Messaging API設定」タブの下の「Webhook URL」に設定します。「検証」を押して成功すれば完了です。「Webhookの利用」のスイッチをオンにしてください。
実際にLINEBotにメッセージを送ってみて、送ったメッセージがサーバーコンソールに表示されることを確認してください。

## 融合！
今まで書いたコードを融合させれば完成です。実際にLINEBotに送ったメッセージをGoogleHomeが読み上げてくれることがわかると思います。

```js:index.js
import express from "express";
import { Client, middleware } from "@line/bot-sdk";
import HomePlayer from "google-home-player";

// 初期設定
const ip = "192.168.x.x"; // GoogleHomeのIPアドレス
const lang = "ja";
const Home = new HomePlayer(ip, lang);

// トークン
const config = {
  channelSecret: "チャネルシークレット",
  channelAccessToken:
    "チャネルアクセストークン",
};
const client = new Client(config);

// Webhook
const PORT = process.env.PORT || 3000;
const app = express();
app.post("/", middleware(config), (req, res) => {
  Promise.all(req.body.events.map(handleEvent)).then((result) =>
    res.json(result)
  );
});
app.listen(PORT);

// 読み上げ
function handleEvent(event) {
  if (event.message.type === "text") {
    let Message = event.message.text;
    Home.say(Message);
    console.log(Message);
  }
}

```

## おまけ
音声も再生できるみたいなので、URLが送信された場合は音声を再生するようにします。
URLとして認識させてエラーを吐くかどうかで認識しています。

```diff_javascript:index.js
//省略

// 読み上げ
function handleEvent(event) {
  if (event.message.type === "text") {
    let Message = event.message.text;
-    Home.say(Message);
-    console.log(Message);
+    try {
+      new URL(Message);
+      Home.play(Message);
+      console.log("Play:" + Message);
+    } catch (err) {
+      Home.say(Message);
+      console.log("Say:" + Message);
+    }
  }
}

```

## 参考サイト

https://qiita.com/miso_develop/items/b03810ea743cfb5a95bd

https://weseek.co.jp/tech/3394/