Edited at

LINEに送信したメッセージを、Google Homeで読み上げ、家族に通知

More than 1 year has passed since last update.

仕事から帰る前に、LINEで「今から帰りまーす」とメッセージを送るが、嫁が気づかないことが多いため、Google Homeにメッセージを読み上げてもらうことにしました。


全体像


  • LINEのMessaging APIにある、メッセージ受信(など)した時、指定URLに通知するwebhook機能


  • Google Homeに好きな言葉をしゃべらせるgoogle-home-notifier


を使い、自宅にhttpサーバを起動しておき、LINE@のアカウントからPOSTされたら、google-home-notifierを使ってGoogle Homeにしゃべってもらう。

家のGlobal IPはちょくちょく変わってしまうので、ngrokを使用してURLを公開。

qiita投稿_line_googlehome.001__.png


LINE Channelの作成


  • LINE developers で「Messaging API(ボット)をはじめる」を選択し、新規Channelを作成



  • 作成したLINE Channelの設定画面で、以下を設定


    • Webhook設定を「利用する」

    • Webhook URLを、自宅サーバのURL(後ででてくるngrokで生成したURL)




これで、作成したChannelのIDにメッセージを送信すると、webhookイベントが指定したURLに通知されるようになる。


HTTPサーバ準備

Node.js, npmが動作する環境が前提


Install ngrok

ngrokは、localhostをXXXXXXXX.ngrok.comで、外部からアクセス可能にするサービス。

localで作成した環境をサクッと外部に公開できる。


  • https://ngrok.comからdownload


  • downloadしたngrokをpathの通った場所に格納



macの場合の例

# copy to Applications directory

$ mv ngrok /Applications/

# cd into your local bin directory
$ cd /usr/local/bin

# create symlink
$ ln -s /Applications/ngrok ngrok



Install google-home-notifier

google-home-notifierは、JavaScriptでGoogleHomeに発話させることができるライブラリ。

$ npm install google-home-notifier

ref : Github - Send notifications to Google Home


httpサーバソース

GitHub - play_with_googlehome

webhook eventはJSON形式で通知され、メッセージ受信時は、

- events[0].typeに、"message"

- events[0].message.textに、メッセージ本文

- events[0].source.userIdに、送信者のUserId

が入る

他のformatは、Messaging API - Webhookイベントオブジェクト参照


server_for_line.js

const config = require('./config/default.json');

// for http server
const http = require('http');

// for googlehome
const googlehome = require('google-home-notifier');
const language = 'ja';

function googlehome_init() {
googlehome.device(config.googlehome_name, language);
googlehome.ip(config.googlehome_ip, language);
}

function googlehome_speak(text) {
googlehome.notify(text, function (res) {
console.log('googlehome_res : ' + res + ' speech_text : ' + text);
});
}

// main()
googlehome_init();

http.createServer(function (request, response) {
let post_data = '';

request.on('data', function (chunk) {
post_data += chunk;
});

request.on('end', function () {
console.log('post_data : ' + post_data);

const webhook = JSON.parse(post_data).events[0];
if (webhook.type != 'message' || webhook.message.type != 'text') {
return;
}

// 特定の人からのメッセージのみ発話
if (config.speakable_userid == '' || webhook.source.userId == config.speakable_userid) {
const data_text = webhook.message.text;
googlehome_speak(config.beginning_sentence + data_text);
}

response.writeHead(200, { 'Content-Type': 'text/plain' });
response.end();
});
}).listen(config.server_port);


config/default.jsonの

- server_portは、webhookのeventを受け取るport。ngrok使用時に指定するport番号とする

- googlehome_ipに、GoogleHomeのIPアドレス

- googlehome_nameは、GoogleHomeのDeviceNameだが、設定しなくても大丈夫かも

- beginning_sentenceに、メッセージの冒頭に発話したい文を記載(「メッセージが届きました。${メッセージ本文}」)

- speakable_useridは、特定Userからのメッセージのみ発話させたい場合に記載。空白の場合、誰のメッセージでも発話。UserIdは一度メッセージを受信させ、webhook eventの、source.userIdを見て確認


default.json

{

"server_port": "8080",

"googlehome_ip": "192.168.XX.XX",
"googlehome_name": "device name of google home",

"beginning_sentence": "メッセージが届きました。",
"speakable_userid": ""
}



HTTPサーバ起動


start ngrok


ngrok起動

# create symlink. default.jsonで指定したportとする。

$ ngrok http 8080

# 起動すると、下記の様な画面が表示される。
# https://XXXXXXXX.ngrok.ioを、LINE Channel設定の webhook URLに設定。
ngrok by @inconshreveable
(Ctrl+C to quit)

Session Status online
Version 2.2.8
Region United States (us)
Web Interface http://127.0.0.1:4040
Forwarding http://XXXXXXXX.ngrok.io -> localhost:8080
Forwarding https://XXXXXXXX.ngrok.io -> localhost:8080



run http_server


server起動

$ node server_for_line.js

# LINE message受信すると、下記のようなログが出力される。
# "userId"が、送信者のuserId。
post_data : {"events":[{"type":"message","replyToken":"0f3a5cccea3543f89f502345eb3df90","source":{"userId":"Uxxxxxxxxxxxxxxxxxxxxxxxxx","type":"user"},"timestamp":1515074416236,"message":{"type":"text","id":"7256796266214","text":"メッセージ本文"}}]}



動作


  • 作成したLINE Channelのアカウントにメッセージを送り、GoogleHomeがしゃべればOK


  • LINEのGroupを作成し、送りたい相手と、作成したLINE Channelのアカウントを登録しておけば、メッセージ文とGoogle Homeの発話で相手に通知できる



おまけ

逆の、Google Homeにしゃべりかけ、認識した文をLINEメッセージで通知するのは、IFTTTを設定するだけでできます。GitHubのREADMEに、簡単な設定例を記載しました。GitHub - play_w_googlehome#ifttt連携

娘がしゃべるようになったら、Google Homeにしゃべりかけてメッセージを送ってもらうの楽しみ。