GoogleHomeに話しかけて検索結果をブラウザに表示させる ❸FirebaseのFunctions実行時 Databaseにデータを追加する

GoogleHome(mini)を購入したので、聞き取ったキーワードから
PCのブラウザにGoogleの検索結果1位のサイトを表示して、そのサイトのタイトルを読み上げるアプリを作成しました。検索したキーワードがDBに無かった場合はキーワードとURLとタイトルを登録します。

最終的に出来たアプリ

1_久慈の生うに大好き💛.png

ワタシがやったこと

極力Googleさんのサービスだけで完結したいなーということで、DialogflowとFirebaseを使用
Firebaseがホスティングサーバーとデータベースと関数の管理と色々サービスを担ってくれているので
全部お任せしました。
2_ワタシがやったことjpg.png

:one: Dialogflowを使用して簡単なチャットボットを作成
:two: FirebaseのFunctions(cloud functions)を使用して、:one:で作ったボットが適切な返事するように設定
:three:  :two: を実行する際にFirebaseのDatabaseにデータを追加するように設定
:four:  :three: のデータ追加をトリガーにFirebaseのHostingで作成したページ(htmlファイル)にパラメータを渡し、
   windowopenで対象のページを開くように設定
:five:  Google検索で一番上に表示されてるページを一発で表示させてみる(I'm feeling luckey!)
:six:  データ登録時にページタイトルとサイトURLはオリジナルのものを保存する
   (webスクレイピングにはcheerio-httpcliを使用しました )
:seven:  フリーのMP3データをFirebaseのStorageに入れてレスポンスに音声データを返す(SSML)


:three: FirebaseのFunctions実行時 Databaseにデータを追加する

3_stage3.png

さて、では早速Firebaseを開いてDatabaseタブを選んでRealtime Databaseをクリック
4_databeseいきます.png

Realtime Database のセキュリティルールの画面でテストモードで開始を選び有効にするを押す
5_DBセキュリティルール.png

するとこんな画面が出てきます。Realtime Database側の用意は出来ました。
6_RealtimeDBの画面.png

では、Databeseにアクセス出来るような記述をindex.jsに追加します。

前回までのindex.jsはこちら
index.js
const functions = require("firebase-functions");//クラウド関数を作成してトリガを設定するためのFirebase SDKのクラウド関数。

exports.hoyatalk = functions.https.onRequest((request, response) => {
    const dialogflow_param = request.body.queryResult.parameters.Greeting_in_the_morning;  //Dialogflowから来てるパラメータを受けとる 

    response.setHeader("Content-Type", "application/json"); //Dialogflowに情報を返す
    response.send(
        JSON.stringify({
            "fulfillmentText": "おはようございます"
        })
    );
});

☟こちらが今回の最終的なコードです。

index.js
const functions = require("firebase-functions");//クラウド関数を作成してトリガを設定するためのFirebase SDKのクラウド関数。

//★★ ココから(1)
const admin = require("firebase-admin");//Firebase Realtime DatabaseにアクセスするFirebase Admin SDK
admin.initializeApp(functions.config().firebase);
//★★ ココまで(1)

exports.hoyatalk = functions.https.onRequest((request, response) => {
    const dialogflow_param = request.body.queryResult.parameters.Greeting_in_the_morning;  //Dialogflowから来てるパラメータを受けとる 
    const dialogflow_user_say = request.body.queryResult.queryText; 

    const nd = new Date();
    nd.setTime(nd.getTime() + 1000*60*60*9);//UTC→JSTに変換(9h追加)
    const year = nd.getFullYear(),month = nd.getMonth()+1,day =nd.getDate(),hour = nd.getHours(),minute = nd.getMinutes();
    const time = year + "年" + month + "月" + day + "日" + hour +  "時" + minute + "分" ;

    //★★ ココから(2)
    const hoyapath = "/hoya/boya"
    admin.database().ref(hoyapath).once("value", function(snapshot) { 
        response.setHeader("Content-Type", "application/json"); //Dialogflowに情報を返す
        response.send(JSON.stringify({"fulfillmentText": "おはようございます"}));
        admin.database().ref(hoyapath).push({user_say:dialogflow_user_say, param_value:dialogflow_param , timestamp: time }) 
    });
    //★★ ココまで(2)
});

☟firebase-adminがRealtime Database のデータの読み取りと書き込みを実行する開発ツール
そのfirebase-adminを初期化(initializeApp)しています

★★(1)
const admin = require("firebase-admin");//Firebase Realtime DatabaseにアクセスするFirebase Admin SDK
admin.initializeApp(functions.config().firebase);

☟hoyapath で Database のルート以下のパスを指定しています。
そしてsnapshotという機能を使ってこの関数が実行された瞬間の情報を取り出しています。
adminを使って、hoyapathにsnapshotの情報を追加してね。というのをやってます。

★★(2)
const hoyapath = "/hoya/boya"
admin.database().ref(hoyapath).once("value", function(snapshot) { 
   admin.database().ref(hoyapath).push({user_say:dialogflow_user_say, param_value:dialogflow_param , timestamp: time }) 
});

今回ワタシは Database に以下の3項目を追加しています。
-user_say(ユーザーが話した言葉) -param_value(パラメータの値) -timestamp(実行された時間)

では、deployしてActions on GoogleのSimulatorでテストしてみます。
ルートの下にhoya/boyaというのが作成され、その配下に 3項目とも追加されました。:v_tone2:
DBに追加されました.png

データを追加する書き方は複数あるみたいなのですが、ワタシが使いそうだなと思ったのはこの2つ
1つ目は上でも書いたパスの後にpushと書くやり方。実はコレ関数が呼ばれる度にデータがジャンジャン追加されます。この英語と数字の羅列は何かと言いますと、キーです。pushすると新しくこのキーが作成されて、その下にuser_sayやらparam_valueやらがデータとして保持されます。

pushだとデータがジャンジャン追加されます。
admin.database().ref(hoyapath).push({
    user_say:dialogflow_user_say, param_value:dialogflow_param , timestamp: time 
}) 

こんな感じで呼べば呼ぶほどキーが増えていきます。
ジャンジャン追加されます.png

setだとデータが上書きされます。
admin.database().ref(hoyapath).set({
    user_say:dialogflow_user_say, param_value:dialogflow_param , timestamp: time 
}) 

setだとキーは作成されずにデータが上書きされています。
setだと上書きされる.png

今までワタシはDBというとSQLというイメージでデータに触れてきていたので、
FirebaseRealtimeDatabaseのNoSQLという考え方がイマイチしっくりこなかったのですが、
自分でデータを追加したり参照してみたりするうちに何となく理解できたように思います。

さて、ここまででFirebaseのDatabaseにデータを追加することが出来ました。
今回も最後まで読んで頂き有難うございました。


    次の記事:❹Databaseへのデータ追加をトリガーに特定のページへ遷移させる

    前の記事:❶Dialogflowで簡単なチャットボットを作成
         ❷FirebaseのFunctionsでボットに返事をさせる(Dialogflow V2 API)

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.