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

GoogleHome(mini)を購入したので、聞き取ったキーワードから
PCのブラウザに**Googleの検索結果1位のサイトを表示**して、そのサイトの**タイトルを読み上げる**アプリを作成しました。検索したキーワードがDBに無かった場合はキーワードとURLとタイトルを登録します。
##**最終的に出来たアプリ**
![1_ウエストポイントのパングラタンは絶品です.png](https://qiita-image-store.s3.amazonaws.com/0/237418/a309d6fd-9487-0a38-5fa7-753399c95572.png "仙台駅前にある隠れ家的なお店です。個人的にはパングラタンが本当おススメ")
##**ワタシがやったこと**
極力Googleさんのサービスだけで完結したいなーということで、DialogflowとFirebaseを使用
Firebaseがホスティングサーバーとデータベースと関数の管理と色々サービスを担ってくれているので
全部お任せしました。
![2_ワタシがやったことjpg.png](https://qiita-image-store.s3.amazonaws.com/0/237418/ad8611c7-628d-7d79-3d09-d8805a0472cb.png "本当Firebaseって素敵なサービスです💛")


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

---
![3_stage4.png](https://qiita-image-store.s3.amazonaws.com/0/237418/880bd997-4310-5aec-6700-313ff9e7de1d.png)

---

##**:five: Google検索で一番上に表示されるページを表示させる**##
####**突然ですが、I'm Feeling Luckyボタンって知っていますか？**####
ワタシは標準ブラウザをGoogle Chromeにしているので、いつも何かを検索する時は
この画面に大変お世話になっております。ココには表示されていないのですが
![画面.png](https://qiita-image-store.s3.amazonaws.com/0/237418/88f295ad-a72c-c0db-4427-2aea1a08ac65.png)

ウェブでGoogleの検索結果の一番上に出てくるページ 
**https://www.google.co.jp/**を表示すると現れます。I'm Feeling Luckyボタン
このボタンは検索結果の一番上のページを一発表示させてくれるという機能を持っています:rabbit:
![google.co.jpの画面.png](https://qiita-image-store.s3.amazonaws.com/0/237418/fb65500f-6229-7a22-1e84-f8ac13611bc5.png)

さて、さっそく試してみます。アマゾン　・・・と
おー！検索結果画面をすっ飛ばして、一発でアマゾンさんのトップページが出てきました。
![amazon一発で出てきたー.png](https://qiita-image-store.s3.amazonaws.com/0/237418/d23886c9-1bb1-ee6c-46e9-11c1d156b59c.png)


前回までで、話した言葉から検索ワードにあたるパラメータを取得できているので、
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=`）　おー！こちらでも出ました！
![一発で出たー.png](https://qiita-image-store.s3.amazonaws.com/0/237418/a0ef886a-704c-b9b9-8102-6142cde9f427.png)


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

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

~~~javascript:
 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 のみを登録しています。

~~~javascript: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してみて下さい。

~~~shell
firebase deploy --only functions
~~~

では、テストしてみます。
おー！表示して　って言ったページが本当に表示されるようになりました。
![アマゾンを表示してで出ました.png](https://qiita-image-store.s3.amazonaws.com/0/237418/919af366-563e-bc43-aee2-ae1c4919e36f.png)

DBは長いと後ろが見切れますが、カーソル当てて確認すると、ちゃんと検索ワードも登録されています。
![DBはこんな塩梅で.png](https://qiita-image-store.s3.amazonaws.com/0/237418/e850e29a-94cf-bd3d-5f16-e47fe73264ff.png)


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

---

　　　**次回の記事：[❻スクレイピングして検索結果のタイトルとURLを登録する](https://qiita.com/tedkuma/items/294b55074639441c00b2)**

　　　**以前の記事：[❶Dialogflowで簡単なチャットボットを作成](https://qiita.com/tedkuma/items/d892ec31c3cdaf35753b)**
　　　　　　　　　**[❷FirebaseのFunctionsでボットに返事をさせる(Dialogflow V2 API)](https://qiita.com/tedkuma/items/9ceb17936c714a205a74)**
　　　　　　　　　**[❸FirebaseのFunctions実行時 Databaseにデータを追加する](https://qiita.com/tedkuma/items/38326f509e6a9f595eac)**
　　　　　　　　　**[❹Databaseへのデータ追加をトリガーに特定のページへ遷移させる](https://qiita.com/tedkuma/items/f35d3c7cd02778c800b6)**