GoogleHome(mini)を購入したので、聞き取ったキーワードから
PCのブラウザにGoogleの検索結果1位のサイトを表示して、そのサイトのタイトルを読み上げるアプリを作成しました。検索したキーワードがDBに無かった場合はキーワードとURLとタイトルを登録します。
##最終的に出来たアプリ
##ワタシがやったこと
極力Googleさんのサービスだけで完結したいなーということで、DialogflowとFirebaseを使用
Firebaseがホスティングサーバーとデータベースと関数の管理と色々サービスを担ってくれているので
全部お任せしました。
Dialogflowを使用して簡単なチャットボットを作成 (前回の記事)
FirebaseのFunctions(cloud functions)を使用して、で作ったボットが適切な返事するように設定
を実行する際にFirebaseのDatabaseにデータを追加するように設定
のデータ追加をトリガーにFirebaseのHostingで作成したページ(htmlファイル)にパラメータを渡し、
windowopenで対象のページを開くように設定
Google検索で一番上に表示されてるページを一発で表示させてみる(I'm feeling luckey!)
データ登録時にページタイトルとサイトURLはオリジナルのものを保存する
(webスクレイピングには**cheerio-httpcliを使用しました )
フリーのMP3データをFirebaseのStorage**に入れてレスポンスに音声データを返す(SSML)
## FirebaseのFunctionsでチャットボットに返事をさせる##
Googleが提供している「Firebase」はアプリのバックエンド機能を提供するクラウドサービスです。
これを使えばワタシのようなバックエンド構築に慣れていない開発初心者でも思ったことが実現できます。
**前回**で、GoogleHomeに話しかけたらそれっぽいことを言ってくれるチャットボットは作成できました。
でも、これではIntentsで登録した言葉しか返せません。ゆくゆくは難しいことを返してもらいますが
今回はとりあえずFirebaseのCloudFunctionsの関数で応答してもらうというのがゴールです。
最初に新しくディレクトリ(フォルダ)を作っておきます。
ワタシはデスクトップにHOYAという名前で用意しました。
では、Actions on googleの画面でBackend serviceタブを選び、
その中のCloud FunctionsにあるGET STARTEDをクリック
FunctionsはNode.jsを使用します。だからコマンドでfirebase-toolsをインストールしてねと言ってます。
npm:Node Package Managerの略
NodeのPackage Manager に firebase で必要なツールをインストールするのね
という訳で先ほど作ったHOYAの中で実行します。
npm install -g firebase-tools
**HOYAの中で実行するというのがピンとこない方はこちらを読んでください**
![cmd.png](https://qiita-image-store.s3.amazonaws.com/0/237418/065f16b6-4aeb-f6cd-647b-d0821f0a3182.png) コマンドプロンプトで先ほど作成したディレクトリに移動して(cdコマンド)、npm installを実行して下さい。この画面は、コマンドを教えてくれている画面なので終了ボタンを押します。
- プロジェクトを開始(初期化)する時のコマンドはfirebase initと入力するよ。
- 関数をアップロードして使えるようにする時のコマンドはfirebase deployと入力してね。という内容
すると最初のデプロイを待機していますと表示されます。さあ、いつでもOKよってことですね。
さて、ではプロジェクトを始める前にFirebaseにログインします。
firebase login
? Allow Firebase to collect anonymous CLI usage and error reporting information? (Y/n)
Firebaseが匿名で使用法とエラー報告情報を収集できるようにしますか?と聞いてます
Yでもnでもお好みで入力して下さい。そしてEnterすると‼‼
ブラウザがパーンと切り替わりました。アカウントを選んで許可ボタンを押します。
ログインに成功するとこの画面が表示されます。
٩(ˊᗜˋ*)وヤッタネー!これですぐに始められるよ~と言ってます。
###では、いよいよプロジェクトを始めます###
firebase init
準備はいいですか?にはY
どの機能を設定しますか?にはFunctionsを選択します。
このディレクトリをFirebaseプロジェクトに関連づけましょうと言われてるので
Dialogflowで作成したFirstAPPを選びます。
何の言語を使用したいですか? → JavaScript
ESLintを使用してバグを見つけ、スタイルを強制しますか? → No
npmで依存関係をインストールしますか? → Yes と答えています。
また色々とインストールされて・・・+ Firebase initialization complete!が出れば初期化完了です。
functionsの中はこのようになっていて、この中にあるindex.jsにコードを書いていきます。
とりあえずindex.jsに書いてあるコードのまま、fuctionsが使えるか試してみます。
requireはjavaとかでいうところのimport文みたいな感じです。
helloWorldというのが関数名、"Hello from Firebase!"というリクエストを送信してねという関数です。
const functions = require('firebase-functions');
// Create and Deploy Your First Cloud Functions
// https://firebase.google.com/docs/functions/write-firebase-functions
exports.helloWorld = functions.https.onRequest((request, response) => {
response.send("Hello from Firebase!");
});
このままdeployします。
firebase deploy
Function URL(helloWorld)の後に書いてあるURLをブラウザに表示するとリクエストが確認できます。
https://us-central1-ここにプロジェクトIDが入る.cloudfunctions.net/ここは関数名が入る
という訳で、コードを書き換えます。
前回作ったIntents 朝の挨拶に返事をさせます。(おはようって話しかけるやつ)
-関数名はhoyatalkに変更しました。
-request.body.queryResult.parameters.の後ろにパラメータ名を指定することで
Dialogflowから送られてきたパラメータが受け取れます。
-fulfillmentTextに返事してほしい言葉を入力します。
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から来てるパラメータを受けとる
//ログの3行は実行時に不要なので消して下さいね。(解説のために入れてるだけです)
console.log(request.body);
console.log(request.body.queryResult.parameters.Greeting_in_the_morning);
console.log(request.body.queryResult.queryText);
response.setHeader("Content-Type", "application/json"); //Dialogflowに情報を返す
response.send(
JSON.stringify({
"fulfillmentText": "おはようございます"
})
);
});
このままdeployします。関数名を変えるとFunction URLも変わります。
※このFunction URLは今からDialogflowで連携させるのに使います。
**dialogflow V1 APIとV2 APIの違い**
というわけで、もう1つgoogleさんのアカウント作って 一からアプリを作成しながら書いてます。 前のを作ったときは V2 がベータ版とか書いてあったのでデフォルトのV1 APIで作ったのですが 今後はV2 APIがデフォルトになるみたいで、まぁいいかとV2でそのまま作成していたら ここのコード書くところで違いがハッキリしてまして、見事に躓きました。
<変更点1> parameters が result → queryResult の中に変更
<変更点2> response の speech → fulfillmentText に変更
const functions = require("firebase-functions");//クラウド関数を作成してトリガを設定するためのFirebase SDKのクラウド関数。
exports.hoyatalk = functions.https.onRequest((request, response) => {
const dialogflow_param = request.body.result.parameters.Greeting_in_the_morning; //Dialogflowから来てるパラメータを受けとる
response.setHeader("Content-Type", "application/json"); //Dialogflowに情報を返す
response.send(
JSON.stringify({
"speech": "おはようございます"
})
);
});
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": "おはようございます"
})
);
});
他にも変更になっているフィールドが沢山あるので**V1とV2の比較ページ**で確認して下さい。
###Dialogflowへ戻って仕上げていきます!###
左側のFullfillmentを選んでWebhookを DISABLED → ENABLEDにします。
URLのところにFunction URLを貼り、下にあるボタンでSAVE
では、Intents(朝の挨拶)を手直しします。Training phrasesの「おはよう」を選択
すると@sys.colorとか@sys.emailとか色々出てきました。この中から自分で登録したEntitiesの
**@Greeting_in_the_morning
**を選択します。すると「おはよう」の下とAction and parametersの欄に
PARAMETER NAME ENTITY VALUE
Greeting_in_the_morning @Greeting_in_the_morning
$Greeting_in_the_morning
が表示されます。これでGreeting_in_the_morningというパラメータを送る設定が出来ました。
@sys.colorとか@sys.emailとかいっぱい出てきてるのは何?
これはデフォルトで登録されているEntitiesです。 デフォルトで「色だよ」とか「メアドだよ」という定義はしてくれているのです。 だから、日付とか時間とか汎用なものはいちいちEntitiesに登録しなくてもよくて、 このTraining phrasesでこの言葉は日付だよとか指定すればいいんです。 ※ワタシのアプリでは使ってないのでこの辺の説明は飛ばします。続いて、Responsesに入れてあったText responseの「おはようございます」を消します。
Fulfillmentの右側にある ∨ を押して、表示された Enable webhook call for this intentをオンにしてSAVE
これでこのIntentsが呼ばれたときにFunction URLを貼ったwebhookを呼びますよの設定が出来ました。
###さてー!シミュレータでテストしてみます!おー!出ました###
では、どうなってるか せっかくログ出したので確認します。
Firebaseに戻りFunctionsタブでログを選択します。おー出てますね。
最初に出した赤枠のところはrequest.bodyの中身です。これを見れば中の構造が分かりますよね。
だから2番目のログではqueryResult.parameters.Greeting_in_the_morningで おはよう が
3番目のログではqueryResult.queryTextで おはよー が取れています。
今回も長々と書きましたが、最後まで読んで下さりありがとうございました。
次の記事:❸FirebaseのFunctions実行時 Databaseにデータを追加する
前の記事:❶Dialogflowで簡単なチャットボットを作成