はじめに
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交換をしてみる(後編)
記事を参考頂きありがとうございます!
簡単な操作で連絡をとれるのは子供に効果高そうですね。
うちの子も大きくなったらアイデアを使わせて頂こうと思います!
@miso_develop コメントありがとうございます![:grinning: :grinning:](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAMAAABiM0N1AAAAwFBMVEVMaXH/zEz/zlH/zE3/zEz/zEz/y0z/y0z/xkv/zEz/zEz/zU7/zEz/zEz/zEz/zEz/zEz/zEz/zEv/zE3/zEz/zEz/zEz/zE3/zU3/zEz/zEz/y0z/zEz/y03/zE1mRQBrSQPtvENyTwZ7VwpxUhL2w0iqgSLisj7e18js6OCSbBXJnDGlkmmGYRC1pYScdBv///+5jSnQojX49vP+/v13Wh3FuJ69kiuHbTfSpDZ/ZCrYqjmYglSkex7Pxa+Se0qAAzOiAAAAHnRSTlMAYwtu0UD5/gXuhyKScvFbsrkart3r5stWdVA0MuAShyFhAAAC4klEQVR4AazTRXpjMRAE4HrYkpnxS5m2kwnscv+DmVEm0b8UNwgvqGlSaeU9XZa6l7cqyVTBQydrNWhotLIOnKTNtvAhaTeV/THZgC/0KylsqLHmG7pu8aoip4VegddUTWhFagovVIe0Nqy+CKtBB42n4U1KOilHeCgROpLk4XuEzuTBm4qSHsoChmqDXhpG7dSQnoYK12r0VsOVQuhNrtKkcgbIFU7GDFLHUdpnkH769EGLr+Xya0HL8dOT1ICGxXK2tVzYjg9S7DRpkM/Z3qfYjZNN7LRp+J0d/dqNk21sdYSGr9OGL7txUjoAMppWpw0ru/GtDECLpvlpw9xufKsLKB3jIK0wZYzQOEVChiebTFAhn5b/z258p4IWGdaQp2znJAO+yEmOD5IBn/akB80o+igZRRnvoE0rVpEdNxAFzcxKNqHfTOoRk/n+pwrbHn3homutV+KiYLf2PQzRp8HrPx53pqWjDtAHeawIMKdiPUl3rGPlGBDVPyJCv0gOb+BO5fG9plTKHz+kpFTfx7lyHN6Qo1+k/9NuYDU26Kf9iiRnJbAoffsjbIgoaXxHZgg63ySY6PQESS0HAGGzrLKmSfxr91ALQQCIEPVD9+qTxtgqy6zA6hZh8XfwG7XNZmFr+A2Hxb9nRy38gTBzPEbAH7TYjnoGSf8/B19O0ZTJ/+dHsUHuXI/pct2UozRNPabb18MQoeENwpuqz1IZL+ANGocIHGue4QPiKXkxtqyq0pqX5EnAB55RrBkGLclhBbgcC1o7l9v0msAiiMbvfiyMFrCIAofR8XhcLF1TjOLxZGB/ZDAD9ogC+0yFoDNysqGoQsyWmuOcTFxO3lfG0/OlmiXVCBVREtesFcVPtugGN61cLn7jVZTGynFGCONOxXSkioYqx2Hq+ulhqAEh1KQRZGQ5OFwx+1x+Xowe+yfhh6h5nASZxt7GuugUs5xGK8c6hJNvu2fR23wYne1+m7uWX1iL7IE5/nCDAAAAAElFTkSuQmCC)
入出力のインターフェースが音声というのは、子供と老人には非常に相性いいですよね。
またいろいろと参考にさせていただきます!