Edited at

GoogleHomeとiftttとDialogflowとfirebaseとLINEBOTとラズパイを使って子供と音声によるLINE交換をしてみる(前編)

More than 1 year has passed since last update.


はじめに

AWS Summitで始めてみたalexaさんに心奪われAIスピーカに興味を持ち、気が付いたらGoogleHomeが家に置いてありました。

家族の無茶な命令で謝ってばかりのGoogleHomeの地位を向上させるべく、今回のプロジェクトを始めました。

まだスマホを持っていない子供との遠隔コミュニケーションが取れるようになれば、売れっ子間違いなしです。

※このプロジェクトを実現するにあたり、以下の記事が非常に参考になりました!ありがとうございました!

https://qiita.com/miso_develop/items/be562d8a823ad2639d94

絵が非常にわかりやすかったため、インスパイアされてパクって作ってみました。


実現イメージ


子供がGoogleHomeでLINEメッセージを送信


親がLINEメッセージをGoogleHomeへ送信


子供がGoogleHomeから未読のLINEメッセージを聞く

ポイントは子供が使うので、GoogleHomeとのやり取りはシンプルな言葉でできること。


  • LINEでただいま → "ただいま"メッセージをLINEへ送る

  • 新しいLINE → 未読のメッセージを読み上げて既読にする

  • さっきのLINE → 既読になってから数分前までのメッセージを読み上げる


    • 新しいLINEで聞き取れなかった時にもう一回読み上げてもらうイメージ




実現手段

本当なら自宅サーバーのラズパイとLINEBOTサービスだけで完結させたかったけど、一刻も早く地位を向上させる必要があるため、いろいろ情報を調べて以下のサービスを活用することでまずは実現させることを優先とします。


実現に必要なサービス


  • LINE Messaging API

  • IFTTT

  • Dialogflow

  • Cloud Functions

  • Firebase

LINE Messaging APIはなければ今回のLINEで云々プロジェクトが始まりません。

IFTTTはGoogleHomeとFirebase(webhook)との連携で必要となります。

その他は、自宅サーバーが外部公開できていればwebhookで発火できますが、めんどくさくてしていません・・・。ngrokを使うことも考えましたが、常にトンネリングするのと、ネットワークが切れたら再接続でURLが変わるため、試作段階で却下です。


準備


各サービスへ登録しよう


LINE Messaging API

LINE BOTはpushサービスを使うので、「Developer Trial」で登録します。

Channel基本設定で、以下のように設定します。


  • Webhook送信 → 利用する

  • Botのグループトーク参加 → 利用する

  • 自動応答メッセージ → 利用しない

WebhookのURLはFirebaseを登録してからなので後で設定。


Dialogflow

Googleアカウントでサクッと登録してみます。

自分のプロジェクトを作成するので、他のブログを参考にして作ってみてください。

とりあえず、LANGUAGEは「Japanese — ja」で。TIME ZONEも忘れずに。

では「Intents」を作っていきましょう。

その前に、「Integrations」でLINEにチェックを入れるのと、「Fulfillment」でInline EditorをENABLEDにしましょう。

Fulfillmentは最終的にはInline EditorではなくWebhookになりますが、最初をInline Editorにすることで自動的にCloud Functionsに関数が作られます。

その関数を使っていく過程で、Webhookに強制的に移行されます。


LINEの設定

以下の設定はLINE Messaging APIの管理画面から持ってきましょう。


  • Channel ID

  • Channel Secret

  • Channel Access Token

「Webhook URL」はURLをコピーして LINE Messaging APIの「Webhook URL」に設定してください。


Intentsの作成

ここでの役割は親のLINEメッセージをLINEBOTがそのまま横流しするのが役目となります。

要するに、メッセージに対して何もアクションを起こさず、全てFallbackとしてLINEのPayloadをFulfillmentにそのまま渡してあげるということです。

「CREATE INTENTS」の右にある3点をクリックして「Create Fallback Intents」を選択します。

Actionに「input.linetext」を入力するのと、FulfillmentのUse Webhookをチェック入れるだけです。

Actionの「input.linetext」はこの文字列でなくても大丈夫です。Fulfillmentの実装時にルーティングで使用するので、そこと整合が取れればOKです。

では次はFulfillmentを実装していきます。


Fulfillmentの実装

ここまで、駆け足で書いてきましたが、どうも何か忘れているような気がする・・・。

・・・あ、Firebaseの登録ですね。うん。忘れました。

どこかの流れで、登録した気がするのですが・・・。

とりあえず、登録してある前提で話を進めます。

今回は、Inline Editorで作成されたCloud Founctionsを改修する形で実装します。

まずは、右側にあるダウンロードをクリックしてローカル環境に落としましょう。

ローカルでの開発&デプロイは以下を参照してください。

https://firebase.google.com/docs/functions/get-started?hl=ja

https://firebase.google.com/docs/hosting/deploying?hl=ja


改修内容

index.jsの先頭付近に以下2行を追加します。

const firebase = require('firebase-admin');

firebase.initializeApp(functions.config().firebase);

こんな感じになるはずです。

'use strict';

const functions = require('firebase-functions'); // Cloud Functions for Firebase library
const DialogflowApp = require('actions-on-google').DialogflowApp; // Google Assistant helper library
const firebase = require('firebase-admin');
firebase.initializeApp(functions.config().firebase);

'input.unknow'と'default'の間に'input.linetext'を追加します。

はい。これだけです。

// The default fallback intent has been matched, try to recover (https://dialogflow.com/docs/intents#fallback_intents)

'input.unknown': () => {
// Use the Actions on Google lib to respond to Google requests; for other requests use JSON
if (requestSource === googleAssistantRequest) {
sendGoogleResponse('I\'m having trouble, can you try that again?'); // Send simple response to user
} else {
sendResponse('I\'m having trouble, can you try that again?'); // Send simple response to user
}
},
'input.linetext': () => {
if (requestSource !== "line") {
sendResponse('LINEからじゃないよ');
return;
}
if( !(requestData.type === "message" && requestData.message.type === "text") ){
sendResponse('テキストメッセージしか送れないよ');
return;
}

let update = {
'/linebot/receive':requestData
};

Promise.resolve().then( () =>{
return firebase.database().ref().update(update);
}).catch((err)=>{
sendResponse("送信に失敗したよ:"+ err );
return
}).then(()=>{
let msg = requestData.message.text + " を送ったよ";
sendResponse(msg);
});

},
// Default handler for unknown or undefined actions
'default': () => {

どこかで、$ firebase initみたいなことをしたりしましたが、何とかなるので乗り切ってください。

最後に、$ firebase deployをすれば終了です。

もう一度、Fulfillmentの画面に戻ると、Inline Editorではエラーとなるはずです。

Webhookに切り替えましょう。


FirebaseのDatabase

Firebaseは非常にシンプルですね。jsonの階層がそのままURLの階層で扱えます。

始めて使いましたが、このようなスキーマとなります。

基本的な使い方としては、googlehomeは通知用のみ。linebotはreceiveにlineのpayload、sendにbotに話させる言葉を格納します。


ラズパイにNodejsとサービスを入れましょう。


ラズパイとNodeのセッティング

これは、そこらじゅうに転がっているので、そちらを見てください。

ちなみに、自分はラズパイ3とケースをAmazonで買いました。


サービスのインストール

ソースをGitHubに上げたのでそちらを参照してください。

今回、QiitaもGitHubも初です。

https://github.com/nk-tamago/googlehome-linebot

これで、LINEに投稿した内容がサービス内のDBの蓄えられて、未読メッセージとして聞けるようになります。

次はIFTTTと連携して、未読メッセージを聞いてみましょう。

今日は遅くなったので、これまで。明日更新します。


2017年11月10日更新

GoogleHomeとiftttとDialogflowとfirebaseとLINEBOTとラズパイを使って子供と音声によるLINE交換をしてみる(後編)