ifttt
RaspberryPi
LINEmessagingAPI
beebotte
GoogleHome

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からどんなメッセージが来たかを読み取ることで実現できるのではないかと構想中。