LINEで送ったメッセージをGoogleHomeで喋らせる 第2弾

LINEで送ったメッセージをGoogleHomeで喋らせる 第2弾

はじめに

前回の記事でLINEで送ったメッセージをGoogleHomeに喋らせることができました。
しかし、実は前回のbotはグループトークに対応していません。

例えば「グループラインにbotを招待して、GoogleHomeにも喋らせるし、LINEメッセージとしても残しておきたい!」といった使い方ができません。

今回はグループトーク対応設定と、コードの修正を行います。

関連記事

  • 第1弾:基本的な設定
  • 第2弾:グループトークに対応させる(本記事)
  • 第3弾:取りこぼしがない様にする(作成中)

現状

作成済みのbotをグループトークに招待してメッセージを送信してみると
①botがすぐに退出してしまう
②Raspberry Pi上のプログラムがエラーを吐き、以降動かなくなってしまう
という2つの問題が発生します。

ちなみにエラーは下記の様なものです。

@firebase/database: FIREBASE WARNING: Exception was thrown by user callback. TypeError: Cannot read property 'text' of undefined

それでは、それぞれの問題を解決していきましょう。


botの設定見直し

前回同様、LINE Developersのコンソールからプロバイダー、チャンネルを選択し、対象のbotの管理画面へ進みます。

前回webhookなどの設定を行ったのと同じ「チャンネル基本設定」の中から「Botのグループトーク参加」を探し、「利用する」に変更します。

これで、グループトークから勝手に退出してしまうことがなくなります。


プログラムの修正

改めてエラーを確認します。

@firebase/database: FIREBASE WARNING: Exception was thrown by user callback. TypeError: Cannot read property 'text' of undefined

「text」なんて名前がついた要素は見つからないと言われています。

firebaseのデータを見てみると

こんな項目が追加されています。

いつものメッセージのデータとは構成が異なり、
末尾のtypeが”join”になっています。

どうやら、トークルームに招待されて参加した時もhttpリクエストが送信されている様です。
そして、このデータも読み込もうとしてしまうためにエラーを吐いてしまいます。

というわけで、構造が異なるデータが来る場合があることがわかったので、
try catchで逃げておきましょう。

//lineを送った人のID
const father = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
const mother = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy";

//google-home-notifierの準備
const googlehome = require('google-home-notifier')
const language = 'ja';

googlehome.device('リビングルーム', language); //リビングルームはgooglehomeの名前。ipを設定する場合は間違っていてもOK
googlehome.ip("192.168.xx.xx");

//firebaseの準備
const fnc = require("../home-controler/functions.js")
var firebase = require("firebase")
var firebaseConfig = {
        apiKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        authDomain: "project-name.firebaseapp.com",
        databaseURL: "https://project-name.firebaseio.com",
        projectId: "project-name",
        storageBucket: "project-name.appspot.com",
        messagingSenderId: "9999999999999999",
        appId: "1:9999999999999:web:xxxxxxxxxxxxxx"
      };
firebase.initializeApp(firebaseConfig);
const path = "/line/recieve";
const keyword = "recieve";
var db =firebase.database();
var ref = db.ref(path);

//dbの更新があったら全てを取得するfunction起動
// ref.on("value", function(snapshot){
//   var word = snapshot.val();
//   console.log(word)
// })

//dbにレコードが追加されたら追加されたところだけを取得するfunction起動
ref.on("child_added",function(snapshot){

  //トークルームにメンバーが追加された時などはjsonの構造が異なるため、下記の力技ではデータを取得できずにエラーとなる
  //try-catchで括って、エラー対策とする。
  try{
    var newMessage = snapshot.val();
    var spokenMessage = (newMessage.events[0]['message']['text']);
    var userId = newMessage.events[0]['source']['userId'];
    console.log(spokenMessage);

    var person = false;

    if (userId == father){
      person = "パパからラインです。"
    }else if (userId == mother) {
      person = "ママからラインです。"
    }

    if (person){
      googlehome.notify(person+spokenMessage, function(res){
        console.log(res);
      })
    }
  }catch(e){
    console.log(e.message)
  }
})

これでグループトークにも対応できます!