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

LINEとGoogle Homeで双方向のやりとりをする

More than 1 year has passed since last update.

やりたいこと

書き出すと単純
・LINEで文字を打つ → Google Homeが読み上げる
・Google Homeで話す → LINEに投稿される

何をしたいかって、家にいる子供からLINEにメッセージを送りそれに返事をしたい。
家で留守番中にゲームしてるのを見計らって(みまもりSwitchを作ってくれた任天堂に感謝)「宿題したか!?」とか送ってビビらせたい。

電話はあるけど仕事中でとれなかったりするし、まだスマホを持たせるには早い。
今時の子供はデジタルネイティブなので、気まぐれでリビングに設置したGoogle Homeも僕より使いこなしているから案外使えるのではないか。

最初の挫折

まず最初に参考にしたのは
Google Home mini で双方向の音声でのLINE送受信を実現する
動画もあるように既に実現しているのをそのままなぞるのが一番簡単である。
が、herokuの環境を構築するところで、なんだかわからなくなって一度やる気をなくす。
もうちょっと真面目に取り組めよって感じではあるが。
構成図を見て、結局自宅PCにgoogle-home-notifierが必要ということで、なんかもうちょっとやりようがあるんじゃないかと思い始める。

プロジェクト(?)再起動

ポイントは、google-home-notifierで、サンプルのソース見てるとexpressでpost受けてgoogle homeに渡してるだけ。そのpostはngrokを通してグローバルで待ち受けている。
おお、ngrok、なんて素晴らしいサービス。
いや、その前にGoogle AssistantがPush用のAPIを公開してくれれば簡単なわけだが、うっかり脆弱性とか突かれたら面倒くさいからやらないんだろう。
ともかく、家庭内に必ずサーバーを立てる必要があることと、ngrokによってそこにアクセスできるというところで光明が見えた。

構成

ざっとこんな感じ。
構成.png
自前でLAN内にサーバーを立てることで、利用する外部サービスはIFTTTとngrokだけとシンプルに。
というか、この形でいろんなデバイス・サービスと連携することが簡単にできそう。

セキュリティ的な話

ngrokの入り口が弱点になるので、IFTTTのwebhookにtokenつけるとか、LINEのgroupIdやuserIdで区別すれば良さそうだけど、今回はやらない。
そもそもかけたコストに見合った見返りのない事に人は労力をかけないものだ、と信じる。

準備すること

  • LINEのDeveloperアカウントをとる
  • IFTTTのアカウントをとる
  • 家庭内サーバー(Raspberry Pi3)をセットアップする

詳細はそれぞれググってね

サーバーで動かすプログラム(node.js)

var express = require('express');
var googlehome = require('./google-home-notifier');
var ngrok = require('ngrok');
var bodyParser = require('body-parser');
var request = require('request');

var app = express();
var urlencodedParser = bodyParser.urlencoded({ extended: false });

app.use(urlencodedParser);
app.use(bodyParser.json());

app.post('/linetohome', function (req, res) {
  if (!req.body) return res.sendStatus(400)
  //ここでreqの中身を表示することで、ユーザーIDやグループIDが見れるので
  // 控えておいて下の'/hometoline'で宛先に記載する
  if(req.body.events[0].message.type == 'text'){    //メッセージのみでスタンプとか除外
    var text = req.body.events[0].message.text;
    //var userid = req.body.events[0].source.userId;    //ユーザーで選別したり

    googlehome.ip('192.168.11.19', 'ja');   //Google HomeのIP
    googlehome.device('Google Home', 'ja');
    if (text){
      try {
        googlehome.notify(text, function(notifyRes) {
          console.log(notifyRes);
        });
      } catch(err) {
        console.log(err);
        res.sendStatus(500);
        res.send(err);
      }
    }
  }
  res.send('ok');
})

app.post('/hometoline', function (req, res) {
  if (!req.body) return res.sendStatus(400)
  var text = req.body.text;
  var options = {
    uri: "https://api.line.me/v2/bot/message/push",
    headers: {
      "Content-type": "application/json",
      "Authorization": "xxxxxxxxxxxxxxxxxxx",   //LINEのアクセストークン
    },
    json: {
      "to": "Cxxxxxxxxxxxxxxxxxxxx",        //メッセージを送るグループのgroup id
      "messages": [
        { "type" : "text",
          "text" : text
        }
      ]
    }
  };
  request.post(options, function(error, response, body){});
  res.send('ok');
})

app.listen(8091, function () {
  ngrok.connect(8091, function (err, url) {
    console.log('LINE webhook : ' + url + '/linetohome');
    console.log('IFTTT webhook : ' + url + '/hometoline');
  });
})

node hoge.js
と実行すれば、LINEとIFTTTに喰わせるwebhookのURLを表示するので控えておく。
このURL、実行する度に変化します。
なので、サーバーの設定で自動実行するようにするなら、URLを自分のLINEに送るような処理にしておくと出先でもIFTTTとLINEの設定更新できるかもね。
いやいや、毎回変化するとかダルすぎやろ固定化できないのかと、そういう場合はngrokに毎月なんぼか払えば固定のURLをゲットできる模様。
もっと活用できるようになったら挑戦してみたい。

IFTTTの設定

My AppletsからNew Applet
ifttt1.png
「if this then that」の「this」と「that」を決めていく。
ifttt2.png
まずthisで、Google Assistantを選択
ifttt3.png
上のように書いてCreate trigger
ifttt4.png
次にthat
ifttt5.png
webhookを選ぶ
ifttt6.png
URLに例のURL、他上のように。
Bodyは

var text = req.body.text;

で取り出してLINEに渡してる。

LINE側の設定

Developerコンソールでプロバイダー、チャネル作成していろいろ設定しておく。
(グループ参加可、自動応答なし、友達追加時あいさつなし、etc)
line1.png
line2.png
アクセストークンはさっきのコードAuthorizationのところへ
Webhook URLに例のURL。
このbotを画面の下の方にあるQRコードで追加して、必要ならグループに入れてメッセージ送る。ログで出力して確認できるグループIDをhometolineのtoのところへ。

これで、LINEとGoogle Homeの双方向のやりとり完成。

Why do not you register as a user and use Qiita more conveniently?
  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
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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