はじめに
前回の記事で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) } })
これでグループトークにも対応できます!