kintoneで画像検索API使ってみた

## きっかけ
以前、kintoneでとある旅行の計画を立てていたのですが、
レコードに行きたい場所をどんどん登録したらどこがどう良いのかわからず混乱しました。
![2018-02-14_18h49_25.png](https://qiita-image-store.s3.amazonaws.com/0/153051/8da2513e-0ae5-62d4-68d5-04aac5a19b86.png)

→ 『地名』や『建物名』だけじゃどんな感じの場所なのかわからない！！
(1つずつ画像を検索してダウンロードして添付ファイルフィールドに貼り付けるのは圧倒的にめんどくさい)

結局、つどGoogle画像検索して雰囲気を確認するという。。( ´Д｀)=3
そこでカスタマイズしようと決心しました。
カスタマイズのソースコードは[Github](https://github.com/RyBB/kintoneCustomize/tree/master/GoogleCustomeSearch)にあります。※動けばいいや程度です。
## 画像検索API
画像検索ができるAPIはGoogleやMicrosoftなどが提供しているのですが、今回はGoogleの『Custom Search API』を使ってみます。
**Google Custom Search API**についてはいろいろと記事があったので参考にしました。

[Google Custom Search API を使ってみる](https://qiita.com/megu_ma/items/8cad39f61e35588e5476)
[Google Custom Search APIを使って画像収集](https://qiita.com/onlyzs/items/c56fb76ce43e45c12339)
[とりあえずGoogle Custom Searchで画像を取得してみる](https://qiita.com/usagi-f/items/ec4b83dd07ac35f47092)

## Google Custome Search APIの準備

Google Custom Search APIについてはそこまで難しい設定はなかったので割愛しますが、

- 検索エンジンID
- APIキー

が必要になるので用意しましょう。
で、実はこのGoogle Custom Search APIは、正確には
**『画像検索**』ではなく、**『カスタマイズされたGoogle検索』**API
なのです。(名前でおおよそ予想つきますね^^;)
なので、普通に利用すると画像以外のレスポンスも返ってくるのでちょっとめんどくさいです。

しかし、APIを叩くURLに
『 **&searchType=image** 』
を追記すれば画像のみの検索となります！さすがGoogleです！

という感じでCustom Search APIのURLは以下のようになります(ブラウザでこのURLを叩いたらレスポンスが確認できます)

https://www.googleapis.com/customsearch/v1?key={APIキー}&cx={検索エンジンID}&searchType=image&q={検索キーワード}

## kintone JSカスタマイズ
では、早速準備したCustom Search APIをkintone上で叩きましょう。 
kintone上で外部APIを叩く方法はcybozu developer networkの[コチラの記事](https://developer.cybozu.io/hc/ja/articles/202166320)が参考になります。

```javascript
// google検索のKey
const key = '{APIKey}';
const cx = '{SearchID}';
const keyword = '{keyword}'

// Custom Search APIを叩く処理
const getImage = keyword => {
        return new kintone.Promise(function(resolve, reject) {
            const url = 'https://www.googleapis.com/customsearch/v1?key=' + key
            + '&cx=' + cx + '&searchType=image&q=' + keyword;
            kintone.proxy(url, 'GET', {}, {}, function(body, status, headers) {
                const res = JSON.parse(body);
                const imageurl = res.items[0].link;
                resolve(imageurl);
            });
        });
    };
```

kintoneでAPIを叩くときはちゃんとPromiseを利用して同期処理にする必要があります。そうしないとレスポンスが返ってくる前に次の処理をして値が上手く受け渡せないです。
レスポンス(res)の中のitmesに検索結果の画像情報が複数格納されています。(今回はデモということで一番最初に検索したものitems[0]に固定しています)

### kintoneとの格闘
ここでちょっと躓いた点というか悩んだ点なのですが、
本当はAPIで取得した画像をデータとしてkintoneの添付ファイルフィールドに挿入したかったのですが、なかなかうまくいきませんでした。
API経由でkintoneにファイルをアップロードする方法もあるらしいのですが、、私は諦めました。
諦めてURLをimageタグで埋め込もう作戦に変更しました。(この記事もその方法を説明します)

## kintoneアプリの設定
アプリのフィールドはこんな感じで用意しました。

| フィールド種類 | フィールドコード | 
|:-----------|:------------|
| 文字列（一行） | Title |
| 文字列（一行） | URL |
| スペース | space |

フィールドはこれだけです。
Titleは{検索キーワード}となる文字を入力してもらうフィールドです。
URLは取得した画像URLを挿入するフィールドです。
spaceは今回のカスタマイズの鍵とも言える重要なフィールドです。

## プログラムの流れ
kintoneカスタマイズJSのメインの流れとしては、

**レコード追加/編集のsubmitイベント** (app.record.create.submit/app.record.edit.submit)
1. Titleフィールドの値を取得する
2. あらかじめ用意したAPIキー、検索エンジンIDとTitleを用いてCustom Search APIを叩く
3. レスポンス内のURLを取得する
4. URLをURLフィールドに挿入する

**レコード詳細/編集イベント** (app.record.detail.show/app.record.edit.show)
1. URLフィールドの値をimageタグを用いてspaceフィールドに挿入する

**レコード追加/編集イベント** (app.record.create.show/app.record.edit.show)
1. URLフィールドを編集不可にする

となります。
Custom Search API のレスポンスURLをフィールドに保存しておくことで、外部APIを叩くのはレコード追加/編集時のみで済みます。

## 完成イメージ
このプログラムを適用するとこういう感じになります。


![2018-02-15_18h48_54.png](https://qiita-image-store.s3.amazonaws.com/0/153051/60879a43-959c-88c8-8498-50f8d0a04ed6.png)
検索キーワードに検索したい文字を入力してレコード保存！

![2018-02-15_18h44_58.png](https://qiita-image-store.s3.amazonaws.com/0/153051/7da10357-0c93-3c90-de19-e6ea3c8be4f5.png)
すると、自動でURLフィールドに画像URL挿入＆下に配置してあるスペースフィールドに画像挿入！
ちゃんとサムネイル画像っぽく表示されました！

添付ファイルフィールドに挿入できればレコード一覧画面でも表示できますが、今回は断念しました。

## おわりに
この方法を利用すれば、いちいちGoogle検索とkintoneを行き来することなく旅行先のイメージが掴めます！
モックということでCustom Search APIのレスポンス部分など結構簡単にしていますが(items[0]の部分など)
もっときっちり作ったら結構使えるものになるのではないでしょうか。。

それでは！