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

LINEをトリガーに家のGoogleHomeを喋らせる

More than 1 year has passed since last update.

はじめに

Raspberry PiからGoogle Homeを喋らせる - Qiita で、GoogleHomeを自由に発話させることができるようになった。
いつも家に帰るときは妻に「帰るよ」というLINEを送っているが、それと同時に家のGoogleHomeが喋ったら面白いと思い、作ってみることにした。
ちょうど、参加中のOPEN BETA LABのメンバーの中でLINEbotが流行っており、調べてみるとLINEmessageingAPIというのがあり、LINEのメッセージを受信したり送信したりできることを知ったので、使ってみる。

2018/02/03 追記

なんでも喋らせられるようになりました!→LINEから家のGoogleHomeに好きな言葉を喋らせる

成果物

システム構成

最終的な構成はこんな感じになった。
LINE-GoogleHome.png

  1. LINEのbotアカウントにメッセージを送ると、botはメッセージ受信をトリガーにIFTTTにwebhookを送る
  2. IFTTTがwebhookを受信すると、webhookでbeebotteのREST APIを叩いてメッセージをPublish(配信)する
  3. beebotteは、届いたメッセージを貯める
  4. 家のRaspberry Piは、beebotteにMQTTでメッセージをSubscribe(購読)しておく
  5. RaspberryPiにbeebotteからメッセージが届いたら、google-home-notifierを使ってGoogleHomeを喋らせる

機能

  • LINEbotに何か送ると、GoogleHomeが固定の文章を喋る
  • LINEで送ったメッセージによって文章を変えることはできていない

構成の検討

この構成になるまでは紆余曲折あった。

RaspberryPiを外から制御する方法

まず参考にしたのは、下記の記事。
GoogleHomeスピーカーに外部からプッシュして自発的に話してもらいます - Qiita
RaspberryPiをサーバーにして、HTTPリクエストを投げることによってトリガーにしている模様。しかし、自宅に置いてあるRaspberryPiに家の外からアクセスするためには、RaspberryPiをインターネットに公開する必要があり、セキュリティなどの心配があるため不採用とした。

RaspberryPiをサーバーにするのは敷居が高いので、RaspberryPiはクライアントとしてWeb上のどこかを定期監視してもらい、変化があったら喋らせるようなことがしたい。そんなものを探していたところ、見つかったのが下記の記事。
IFTTTのトリガーおよびアクションをESP8266で実行する - Qiita
IFTTTというのは「If Then This Then That」の通り、「こういうトリガーがあったらこういうアクションをする」というアプリ(アプレット)を簡単に作れるサービス。TwitterやDropboxといった様々なサービスが連携できるパーツが提供されており、入力(トリガー)と出力(アクション)の組み合わせで簡単にアプレットを作ることがきる。
この記事では、IFTTTのアクションとしてbeebotteというMQTTブローカー(IoTのデータを貯めておいたりするサービス)にwebhookを使ってデータを送信し、ESP8266(Wi-Fiマイコン)でbeebotteからデータを取得することでアクションを実現している。
この記事のESP8266の部分をRaspberryPiに置き換えればできるので、RaspberryPiを外から喋らせるのはこの方法を採用することにした。

LINEからIFTTTにメッセージを届ける方法

IFTTTは様々なサービスと連携できるので、LINEのメッセージをトリガーにすることくらいできるだろうと思っていたが、IFTTTのトリガーに設定可能なサービス一覧にLINEがなかった。(アクションなら、LINEで通知する、というのが設定可能だった。)
LINEのAPIについて調べていると、LINE Developersというのを発見した。LINE Developersに登録すると、LINEbotが作成でき、メッセージを受け取ったときにwebhookが送信できることがわかった。本来はLINEのbotを作るためによく使われるようだが、これを単なる通知として使うことにした。

IFTTT不要説

感の良い読者なら気づくかもしれないが、LINEbotからwebhookをIFTTTに送信し、IFTTTからwebhookでbeebotteに通知しているため、IFTTTは省略できそうである。しかし、LINEbotから送信されるwebhookのJSONと、beebotteが受信できるwebhookのJSONの形式が一致せず、IFTTTは省略できなかった。

作成の手順

LINEbotにIFTTTのアクセスキーが必要で、IFTTTにはbeebotteのアクセスキーが必要なので、逆にbeebotte→IFTTT→LINEbotの順番で設定をするのが良い。

beebotteチャンネルの作成

基本的にはIFTTTのトリガーおよびアクションをESP8266で実行する - Qiitaを参考にする。
beebotteにアクセスし、アカウント登録とチャンネル、リソースを作成する。

  • チャンネル名: ifttt
  • リソース: action

を作成した。
My Channelsから作成したチャンネルをクリックすると、チャンネルの詳細が出て来ます。「Channel Token: ...」と書いてあるのが、そのチャンネルにアクセスするトークン。IFTTTに入力するのでとっておく。
beebotte.png

IFTTTアプレットの作成

ここも基本的にはIFTTTのトリガーおよびアクションをESP8266で実行する - Qiitaを参考にする。
IFTTTのアカウント登録を済ませ、IFTTT WebhooksをConnectしておく。

  • トリガー: webhooks
  • アクション: webhooks

のアプレットを作成する。
ifttt.png
URLには先ほどbeebotteで取得したチャンネルのアクセストークンを入力する。

https://ifttt.com/maker_webhooks の右上の「Documentation」をクリックすると、「Your key is: ...」にIFTTTのwebhookにアクセスするキーが書いてあるので取っておく。

LINEbotの作成

LINE Developersのアカウントを作成し、Messaging APIを作成する。作ったbotアカウントの「Channel基本設定」の「メッセージ送受信設定」で、

  • Webhook送信を有効に
  • Webhook URLに、先ほどIFTTTで取得した アクセスキーを入力する。

linebot.png

Raspberry Pi プログラムの作成

Node.jsとgoogle-home-notifierの設定

Raspberry PiからGoogle Homeを喋らせる - Qiita を参考にして、設定する。

Node.js用MQTTライブラリMQTT.jsのインストール

Node.jsでMQTTが簡単に使えるようにするライブラリMQTT.jsをnpm(Node Package Manager)でインストールする。
上記リンク先のInstallationに記載の通り、作業ディレクトリで下記を実行するとインストールできる。

$ npm install mqtt --save

--saveとつけるのは、npmで生成されるpackages.jsonに「MQTT.jsが必要だよ」という情報を記録するためらしい。

Node.jsプログラムの作成

作成したソースコードは以下。前回作成したgoogle-home-notifierのソースと、MQTT.jsのサンプルソースを合体させた感じ。

mqtt-googlehome.js
const googlehome = require('google-home-notifier');
const mqtt = require('mqtt');

const language = 'ja';
googlehome.device("Google-Home", language);
googlehome.ip("192.168.xxx.xxx");

const client = mqtt.connect('mqtt://mqtt.beebotte.com',
  {username: 'token:token_XXXXXXXXXXXXXX', password: ''} // XXX..の部分にはbeebotteのチャンネルのアクセストークンを入れる
);

client.on('connect', function() {
  client.subscribe('ifttt/action');
});

client.on('message', function(topic, message) {
  console.log(message.toString());
  googlehome.notify('こんにちは世界。', function(res) {
    console.log(res);
  });
});

動作確認

これで、作成したLINEbotにメッセージを何か送信すると、GoogleHomeが喋るようになるはず。うまくいかない場合は、IFTTTやbeebotteでは動作履歴が記録されているのでデバッグ時の参考にできる。
↓動作中の動画



妻が留守番中に外からこれを実行したら、ただただビックリしていた模様。。

所感

LINE MessagingAPI, IFTTT, beebotteといった小さいサービスでも工夫次第で連携して好きなことができて楽しい。「ピタゴラスイッチ的」というのをどこかで見たが、まさにその通り。

今後

今回は固定の文章しか喋れなかったが、好きな文章を喋らせるようにしたい。
IFTTTのwebhook受信が、JSONの細かいステータスを読み込むことができなかったのが敗因なので、IFTTTをAWS LambdaやAzure Functionあたりに差し替えて、LINEからどんなメッセージが来たかを読み取ることで実現できるのではないかと構想中。

Why not register and get more from Qiita?
  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