JavaScript
LINEmessagingAPI
GoogleHome
google-home-notifier

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

仕事から帰る前に、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にしゃべりかけてメッセージを送ってもらうの楽しみ。