【Node.js】Custome Search APIを使って何か作ってみる

初投稿です。※初投稿っぽい前置きや自己紹介は割愛します笑
プライベートでもモノづくりをしたい！ホームランを打つには素振りが必要！ということで始めてみました。

#目的（テキトー）　　
REST APIを使ってデータが連携されて何かしらのインサイトを得るということにすごく価値を感じています。
データの宝庫であるGoogle様から必要なデータを拾う処理ってなんか作れないかなあっていうのが今回の目的です。

#使っているもの
Node.js
Custome Search API

#Custome Search APIって?
Custome Search APIはGCP上でGoogleが提供しているGoogle検索のAPIです。
これを使うにも何かと手順があります。※気が向いた時にこちらも軽くまとめるかも
参考になる情報は数多くありますので、自分が参考にさせていただいたものを抜粋して貼っておきます。
[Custom Search APIを使ってGoogle検索結果を取得する](https://qiita.com/zak_y/items/42ca0f1ea14f7046108c)
[Google Custom Search API を使ってみる](https://qiita.com/megu_ma/items/8cad39f61e35588e5476)

#ここからが作ったものについて
APIに必要なパラメータは大前提にURL、あとは検索エンジンID、APIキー、検索ワードが必要です。
詳細なAPIの情報は<b>[公式のページ](https://developers.google.com/custom-search/)</b>を参照してください。
簡単に三つのパラメータを説明すると、
####検索エンジンID
ユーザーが作成したカスタム検索エンジンのユニークIDのこと。Custome Search APIの利用にはこのカスタム検索エンジンの作成が必要です。
####APIキー
APIコール時のユーザー認証に必要な情報です。
本来は漏洩等による不正利用を防ぐため、API呼び出すアプリケーションの制限（IPアドレスやドメインなどで設定可能）や呼び出せるAPIの制限といった制限をかけるべきです。今回は遊びなので特に制限は設定していません。※生成したAPIキーは削除済み
####検索ワード
そのまんま。ググる時同様の検索したいワードです。今回はラーメン界に名を轟かす「中華蕎麦とみた」さんを検索ワードに。
###クエリパラメータの外出し
さっきのパラメータはメインのソースコードにベタ書いても遊びとしては良かったのですが、あまりにも工夫がないなと思い、設定ファイルに外出ししました。node-configというモジュールを使い、下記のように<b>default.json</b>というJSONファイルを作成し、そこに各パラメータを記述しています。

```json:default.json
{
    "url":"https://www.googleapis.com/customsearch/v1",
    "key":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "cx":"000000000000000000000:xxxxxxxxxxx",
    "q":"中華蕎麦とみた"
}
```
ちなみに、node-configは下記のコマンドでインストールします。
`npm install --save-dev config`

###requestモジュールを使ったhttp通信
Node.jsのhttp標準モジュール(http/httpsモジュール)でもいいのですが、せっかくなのでより楽に処理を実現できるrequestモジュールを今回は使用しました。optionとして引数にURLやhttpメソッドを渡します。また、<b>json:true</b>とすることでレスポンスのJSONをパースしてくれます。
下記のコマンドでインストールします。
`npm install request --save`
このモジュールを使いながら処理を書いて、実行したらこんなエラーが。
`path contains unescaped characters`
どうやら原因は検索ワードの2バイト。初歩的なミスですね。URLエンコードが必要ですので、javascriptでは<b>encodeURIComponent</b>を使います。
###コード完成！
そんなこんなで完成したコードがこちら。

```javascript:getGoogleResult.js
var req = require('request');
var conf = require('config');
var options = {
    url: conf.url + "?key=" + conf.key + "&cx=" + conf.cx + "&q=" + encodeURIComponent(conf.q),//設定ファイルから各パラメータを取得し、URLを生成している
    method: 'GET',//GETでリクエスト
    json: true//これでJSONをパースしてくれる
}
req(options, function (error, response, body) {
    if (error) {
        console.log('Error: ' + error.message);
        return;
    }
    var items  = body.items;
    for (var i in items) {
        var itemLink = items[i].displayLink;
        var strLink= String(itemLink);
        var itemTitle = items[i].title;
        var strTitle = String(itemTitle);
        if(strLink.indexOf('tabelog.com') != -1 ){
            console.log(conf.q + "の食べログは\nURL:" + strLink + "です。\n" + "タイトル：" + strTitle)
        }
    }
})
```
ざっくり言うと、コールバック関数の中でerrorがあれば、ログに出して終了、errorが無ければ、bodyからitemリスト（Custome Search APIの検索結果リスト）からURLに「tabelog.com」が含まれるものを判定してログ出力！って感じです。
注意点としては、ループでitemsから取得できるもの（コード中のiのこと）はインデックスなので、ループの中ではこのインデックスを使ってリストの要素を取り出す必要があります。

###いざ、実行！
```terminal
node getGoogleResult.js
```
結果は、

```
中華蕎麦とみたの食べログは
URL:tabelog.comです。
タイトル：中華蕎麦 とみ田 - 松戸/ラーメン [食べログ]
中華蕎麦とみたの食べログは
URL:tabelog.comです。
タイトル：日本の中華そば富田 - 成田空港/ラーメン [食べログ]
```
富田さんの食べログサイトが取れました。（ほんとは松戸本店だけのつもりだった・・・）
あと、displayLinkだとどちらもtabelog.comになっちゃいますね。普通のlinkにしなければいけなかった・・・
まあ、なんとなく遊べたので満足です。これをなんらか使い勝っていい感じに発展させたら面白そうだけど、それは気が向いたらやります。笑
#終わりに
何かしら自分が面白いと思ったことを発信できたら、それ自体が面白そうだなと思って投稿してみました。
どれだけ役立つ情報発信ができるか分からないし、そもそもそんなマメに投稿するかも怪しいけど、また何か思いついたら自分の備忘録も兼ねて書きます。