GoogleHomeに話しかけて検索結果をブラウザに表示させる ❺Google検索で一番上のページを表示させる


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)



Google検索で一番上に表示されるページを表示させる

突然ですが、I'm Feeling Luckyボタンって知っていますか?

ワタシは標準ブラウザをGoogle Chromeにしているので、いつも何かを検索する時は
この画面に大変お世話になっております。ココには表示されていないのですが

ウェブでGoogleの検索結果の一番上に出てくるページ
https://www.google.co.jp/を表示すると現れます。I'm Feeling Luckyボタン
このボタンは検索結果の一番上のページを一発表示させてくれるという機能を持っています

さて、さっそく試してみます。アマゾン ・・・と
おー!検索結果画面をすっ飛ばして、一発でアマゾンさんのトップページが出てきました。

前回までで、話した言葉から検索ワードにあたるパラメータを取得できているので、
URLにI'm Feeling Luckyボタンと同じ検索を入れ込んでやればいいですね。
"http://www.google.com/search?btnI=I%27m+Feeling+Lucky&lr=lang_ja&ie=UTF-8&oe=UTF-8&q=
btnI さえ入れとけば一発で表示されるみたいです。

じゃあI'm Feeling Luckyボタン使わずに、ブラウザに入力してみます。
http://www.google.com/search?btnI&q=) おー!こちらでも出ました!

というわけで q=の後に検索ワードが入ると検索トップが表示されます。
(※マイナーなワードだと一発表示されずに、検索結果一覧が出てしまいます)
ここまでわかれば後は簡単!では、コードに追加します。

ではindex.jsを書き換えます。DBのurlをI'm Feeling Lucky検索でkeywordを検索するようにすればOK

 url: "http://www.google.com/search?btnI=I%27m+Feeling+Lucky&lr=lang_ja&ie=UTF-8&oe=UTF-8&q="+keyword

こちらが最終的なコードです。さすがにもう意地悪言ってられないので
以後は「はい、 keyword+の検索結果を表示します。」と言ってもらうことにしました。
DBの登録も配列のデータは不要なので keyword のみを登録しています。

index.js
const functions = require("firebase-functions");//クラウド関数を作成してトリガを設定するためのFirebase SDKのクラウド関数。
const admin = require("firebase-admin");//Firebase Realtime DatabaseにアクセスするFirebase Admin SDK
admin.initializeApp(functions.config().firebase);

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

    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 + "" ;

    const hoyapath = "/hoya/boya"
    const musubipath = "/musubi/maru"

    admin.database().ref(hoyapath).once("value", function(snapshot) { 
        response.setHeader("Content-Type", "application/json"); //Dialogflowに情報を返す
        response.send(JSON.stringify({"fulfillmentText": "はい、"+keyword+"の検索結果を表示します"}));
        admin.database().ref(hoyapath).push({url: "http://www.google.com/search?btnI=I%27m+Feeling+Lucky&lr=lang_ja&ie=UTF-8&oe=UTF-8&q=" + keyword, param_value:keyword , timestamp: time });
        admin.database().ref(musubipath).set({timestamp: time, tx:keyword , url: "http://www.google.com/search?btnI=I%27m+Feeling+Lucky&lr=lang_ja&ie=UTF-8&oe=UTF-8&q=" + keyword });
    });
});

ではdeployします。今回はfunctionsだけのdeployでいいので以下のようにdeployしてみて下さい。

firebase deploy --only functions

では、テストしてみます。
おー!表示して って言ったページが本当に表示されるようになりました。

DBは長いと後ろが見切れますが、カーソル当てて確認すると、ちゃんと検索ワードも登録されています。

今回は以上です。
DBを見てると、正規のURLとページタイトルで登録出来たらいいのになーと思いますよね。
それを次回やります。では、最後まで読んで頂きありがとうございました。


   次回の記事:❻スクレイピングして検索結果のタイトルとURLを登録する

   以前の記事:❶Dialogflowで簡単なチャットボットを作成
         ❷FirebaseのFunctionsでボットに返事をさせる(Dialogflow V2 API)
         ❸FirebaseのFunctions実行時 Databaseにデータを追加する
         ❹Databaseへのデータ追加をトリガーに特定のページへ遷移させる