enebularを使ってポケモン生活を快適にする（GoogleCloudPlatform使ってみた）

※この記事は「[enebular Advent Calendar 2016](http://qiita.com/advent-calendar/2016/enebular)」12/15の分です。
初めて自分で「これ作ろう」と思い立って作ってみたものになります。

**※構築過程を書きますが、説明が至らなかったり、間違った言葉を使っているところがありそうなので、どんどん突っ込んでくださると幸いです。**
#レシピ
- enebular
- Google Cloud Platform
- Google Custom Search Engine
- Slack

これらを使って**「Google検索から画像を検索して、Slack Botから流す。」**というのを実装してみます。
記事の下の方にGoogleとSlackの設定を除いたコードを貼り付けています！:ok_hand:

## ポケモン生活を快適にする #とは
[ポケモン最新作サン・ムーン](http://www.pokemon.co.jp/ex/sun_moon/)にはQRスキャンという機能があります。
:basketball:「[QRスキャンで、新たなポケモンと出会おう！](http://www.pokemon.co.jp/ex/sun_moon/collect/160602_02.html)」
QRコードを3DSから撮影すると対応したポケモンが図鑑に登録されるという機能です:camera_with_flash:
いまいちしっくりこない方は、[バーコードバトラー](https://ja.wikipedia.org/wiki/%E3%83%90%E3%83%BC%E3%82%B3%E3%83%BC%E3%83%89%E3%83%90%E3%83%88%E3%83%A9%E3%83%BC)のQRコード版だと考えてくださればおっけーです。（バーコードバトラーの知名度わからないけど）

いつでもQRスキャンできるわけではなく、スタミナのようなものがあり、時間で回復します。
10個スキャンするとポイントが溜まり珍しいポケモンに出会うことができるのですが、、**毎回QRコードを用意するのがめんどくさい！**

なので、**ボタン一つでQRコードを投げてくれるSlack Botを作りました**:v:

# Slack WebHook URL取得
<img width="369" alt="1.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/98ac6952-9adc-be52-a826-f0768f5ea3a1.png">
とりあえず、functionの中のものをそのまま流す箱を作ります。
テストなのでFlowはシンプルなこんな感じに。

<img width="303" alt="2.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/d7733ef9-4329-0ae2-3582-a2f568719fa8.png">
functionの中身。
ボタン押すとslack botから「てすと」と送信されます。

[SlackのWebhook URL取得手順
](http://qiita.com/vmmhypervisor/items/18c99624a84df8b31008)を参考にURLを発行します。

<img width="284" alt="3.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/fcd76625-e971-0f62-b30c-efa5841596b4.png">
channel設定などはWebHook URL発行の際に設定できるので、WebHookURLのとこのみの入力で大丈夫です。

先ほどのFlowのinjectノードのボタンを押して発火すると:candle:
<img width="474" alt="4.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/193b4ac7-37da-56f1-9955-93e048d09864.png">
きました:v:
なんか、無機質なのでSlackBot設定のページから設定します。


<img width="477" alt="5.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/f6253f17-7d61-fef0-914a-65da6426b378.png">
はい、かわいい:relaxed:
`:heart:`などをメッセージの中に入れれば絵文字も反映されるようです。

# Google Custom Search EngineからJSONを受け取る
[とりあえずGoogle Custom Searchで画像を取得してみる
](http://qiita.com/usagi-f/items/ec4b83dd07ac35f47092)[google custom search engine(CSE)を使って、検索結果をjsonで取得する](http://ryutamaki.hatenablog.com/entry/2014/01/18/171640)
こちらを参考にJSONを発行してみます。
Google Cloud PlatformやGoogle Custom Search Engineの設定などについては上記リンクからご覧ください。
これらから取得できるAPIを使用して話を進めていきます。


検索エンジンの権限を持ったAPIを発行して、それをカスタムサーチエンジンで使います。
`https://www.googleapis.com/customsearch/v1?key={API_KEY}&cx={CUSTOM SEARCH ENGINE ID}&q={SEARCH_WORDS}`
うまく日本圏内の結果が出ませんでしたが、検索ワードをうまく渡せてなかったようです。

`https://www.googleapis.com/customsearch/v1?key={API_KEY}&cx={CUSTOM SEARCH ENGINE ID}&q={SEARCH_WORDS}&ie=UTF-8`
~~`ie=UTF-8`のパラメータを追加することで、日本語がしっかり検索に反映されたようです。（多分）~~
※追記：
**少し検証を繰り返すとうまくいっていないことを確認しました。**
（普通に検索バーから出した結果と比べると、QRコードがちがう。）
検索ワードを日本語直打ちのものをUTF-8に変換してから、SEARCH_WORDSのところに渡してあげることで解消されましたが、もっといい方法ないでしょうか・・・。
例）QRコード→QR%E3%82%B3%E3%83%BC%E3%83%89
※追記ここまで


<img width="442" alt="16.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/d79dbe09-f388-8d7f-6322-fcacc7908c75.png">
ひとまず先ほどのURLをhttpのノードに入れて実行してみます。今回はQRコードが欲しいので、検索ワードは「QRコード」です。

debugから見たログ↓
<img width="527" alt="6.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/0ec4057d-41b7-0211-cae6-22134dcbee2a.png">
ぎゃああああ

SlackBotから送られてきた文字列
<img width="447" alt="7.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/c1d62ef8-8334-ecf5-b0c5-24b56a3f5f54.png">
（以下オブジェクト型式でかなりつづく）

JSONは来ましたが、まだ生なので調理する必要があります。
**enebularの本領発揮です。**

その前に、QRコードのみ引っ張りたいので、検索オプションを追加しました。
```tbs=ic:gray```を先ほどのURLパラメータに追加して、白黒の画像のみ検索結果に表示するようになりました。

私は検索結果のURLから```tbs=ic:gray```や```ie=UTF-8```のパラメータをひっぱってきましたが、リファレンスに一覧がありましたので紹介しておきます。:point_up:
[https://developers.google.com/custom-search/json-api/v1/reference/cse/list](https://developers.google.com/custom-search/json-api/v1/reference/cse/list)



# enebularでつなげる、整える。
JSONの中を見てみます。

```json
{
~~~略~~~
"items":[{
  "kind": "customsearch#result",
  "title": "QR garchomp And ...",
  "htmlTitle": "\u003cb\hoge.html",
  "link": "http://www.garchomp.hoge/QR.png", //ここ画像
  "displayLink": "www.garchomp.hoge",
  "snippet": "strong dragon",
  "htmlSnippet": "\u003cb\hoge\hoge",
  "mime": "image/png",
  "fileFormat": "Image Document",
  "image": {
   "contextLink": "http://www.garchomp.hoge/",
   "height": 175,
   "width": 175,
   "byteSize": 411,
   "thumbnailLink": "https://garchomp.img?q=tbn:ANxxxxxxxxxxxxxxxxxxxxxxxRGQ",
   "thumbnailHeight": 100,
   "thumbnailWidth": 100
  }},{
  "kind": "customsearch#result",
  "title": "QR Dragonite And ..."
~~~略~~~
```
（中身はダミーです）
配列やオブジェクトで検索結果が並んでいて、`link`のあとに画像URLがあることを拡張子を見て確認しました。
`msg.payload`にjsonオブジェクトが入ってくるので、`msg.payload = "msg.payload.items[i].link;`こんな感じに書けば、画像だけ取って来れますね。

そしたら、これをどうにかして10個抜き取ってしまえば良さそうです。

## 10個抜き取るFlow
とりあえず、受け取ったjsonを成型するために、
<img width="583" alt="17.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/d89e6f68-3711-a406-276e-718f9e3b7c55.png">
こんな感じに組んでみました。順番に説明していきます。

### ループの実装
<img width="183" alt="25.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/ba9ae35e-e7d1-b2cc-f6bd-ae734430cfca.png">
↑ 8の字を描いていていかにもループしていそうなところは、その通りループしています。:curly_loop:

最初の<img width="64" alt="20.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/d9c4bb35-df06-e01e-9402-188fa267a230.png">では変数の初期化をしています。

<img width="283" alt="18.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/354b9022-c849-5b4e-28ae-d649785ef091.png">

<img width="64" alt="21.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/2c500ef0-3d4d-458c-0e10-502a7c8f0358.png">で条件分岐しています。

iが10になるまで<img width="184" alt="22.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/925c8dd9-8936-5d7b-d885-0d8d0463a30d.png">に流れ、同時に<img width="56" alt="23.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/98d3761d-ee98-c5e2-7c92-99d26ce4f246.png">で変数の値を+1しています。

↓<img width="94" alt="37.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/a1a1bda6-0170-07d3-c1dd-6049f623ad81.png">の中身
<img width="302" alt="38.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/27b1c92b-611c-6435-f356-4acd33e382de.png">
`以下略`してますが、画像ごとにメッセージを変えたかったのでswich文使いました。
しかし、ここはenebularのswichを使うとfunctionを書かずに実装できますね。

↓<img width="56" alt="23.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/98d3761d-ee98-c5e2-7c92-99d26ce4f246.png">の中身
<img width="251" alt="26.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/cf4bcb94-09e5-6e0a-fe9b-02c7606f2f75.png">


変数iが足され、10になると最後<img width="155" alt="27.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/7065d7a4-5423-0966-260c-bc5cc8ad723d.png">に流れ、処理を終了します。「ループ後の処理」の中身はメッセージを書いているだけなので、割愛します。

ちなみに条件分岐している<img width="64" alt="21.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/2c500ef0-3d4d-458c-0e10-502a7c8f0358.png">の中身は以下になります。
<img width="279" alt="19.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/7743cc1f-900b-d973-b3d0-01dc44e951db.png">
左下の`+ rule`を押すことで分岐先をさらに増やすことができます。

これで<img width="77" alt="35.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/e74ac8a9-cada-41c1-240b-a432d169011f.png">の左側をポチっと押すと検索結果の画像10件を取ってくることができます。

### 検索ワードをちょっとだけランダムにしてみる
話戻って、、今回は**ポケモン生活を快適にする**ということで、記事を書いています。
きっかけとなった[「QRスキャン及び島スキャン」](http://www.pokemon.co.jp/ex/sun_moon/collect/160602_02.html)は、同じQRコードを2日連続で使用することができません。（一日置けば大丈夫です。）
なので、10個のQRのセットを検索ワードを変えることで4つ用意することにしました。
先ほどの<img width="75" alt="30.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/fcea0bd0-200f-44fa-f2c1-7d8a40fd8060.png">（URLを渡す部分）にちょっと手を加えます。

<img width="434" alt="29.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/fa6c6701-3af4-16ba-9d2e-20d45e6bc95c.png">
QRコードを使って遊ぶアーケード筐体などからこれらがベストワードでした:raising_hand:~~これもまたアイカツです~~
「QRコード　ポケモン」のように検索していて、「ポケモン」の部分がランダムで分岐する形です。


最初の<img width="64" alt="20.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/d9c4bb35-df06-e01e-9402-188fa267a230.png">では変数の初期化をしています。先ほどと一緒ですね。
<img width="97" alt="31.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/264d3665-6a17-2e84-cf38-ef1ce9bc12bd.png">で、その変数をランダムにしているのですが、一つのfunctionで良さそうですね。
<img width="237" alt="33.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/b7b49991-21c2-005a-be5f-6a53d9234806.png">
中身はこんな感じです。
スマートに`msg.i = Math.random() * 4 | 0;`こう書いて、手前のノード消す方がよさそうです。

そこでランダムになった変数を使って<img width="57" alt="32.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/ed60b9ea-cfa3-9cce-1f8f-efd2747745d9.png">で分岐させます。

<img width="241" alt="34.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/8519ad07-2412-5340-1bf2-61944624fae6.png">

これで完成です。


<img width="77" alt="35.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/e74ac8a9-cada-41c1-240b-a432d169011f.png">の左側をポチっと押すと、4つの検索ワードからランダムに10件QRコードをゲットしてきます。

![test.gif](https://qiita-image-store.s3.amazonaws.com/0/132212/da0d9fc3-9078-2ec3-17dc-65075e587d60.gif)
少し見にくいですが、こんな感じに動いています。

# 応用編？
検索のワードを変えれば・・・、そう、QRコード以外も検索できますね。
応用編として、flow変数などを使って、もう少しランダムに検索結果を取るようにしてみます。

それでは、現在推しているアイドルの画像を取ってきます:dancer_tone2:
<img width="386" alt="36.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/db2d194d-158c-475b-c748-682be02d600a.png">
検索文字列を渡す前に、検索用の配列を作って`固定文字+ランダム文字`の検索を行っています。
後半はloopではなく、ランダムに1つだけ取ってくるような設定をしているので、配列の個数*10通りの検索結果が期待できます。

<img width="77" alt="35.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/96688c90-345b-31af-079f-43dba65a01af.png">をポチッ:point_left:

↓

<img width="248" alt="15.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/0e33249c-bb39-d0d8-2eaf-8a3452cb421c.png">

Slackが[あのちゃん](http://ylmlm.net/)だらけになる！！！
(ノ・ω・)ノオオオォォォ-！！！

上のFlowでは「あのちゃん　[配列内の文字列から１つ]」のように検索しています。

応用編、以上になります。

##Flowの共有
ポケモン生活より、ランダムに画像取ってくる方が需要があるのは確実なので、ソース↓
（※設定箇所が空欄で抜けていますので、Google周りやSlack周りを設定すれば好きな画像が飛んでくるぞ！:airplane:）

```
[{"id":"54acff66.965d","type":"slack","z":"55626b8c.8b2f54","name":"","channelURL":"","username":"","emojiIcon":"","channel":"","x":701.5,"y":264.2222900390625,"wires":[]},{"id":"38284b91.517734","type":"template","z":"55626b8c.8b2f54","name":"+検索文字列","field":"payload","fieldType":"flow","format":"json","syntax":"mustache","template":"{\"word\":[\"dummy1\",\"dummy2\",\"dummy3\",\"日本語入力のものはUTF-8に書き換えてから配列に入れる\"]}\n","x":237,"y":97,"wires":[["d4be1101.91aed"]]},{"id":"8ac7a5ca.af98f8","type":"inject","z":"55626b8c.8b2f54","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":82,"y":97,"wires":[["38284b91.517734"]]},{"id":"d4be1101.91aed","type":"change","z":"55626b8c.8b2f54","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":290,"y":147,"wires":[["7253dfcd.e7c16"]]},{"id":"7253dfcd.e7c16","type":"json","z":"55626b8c.8b2f54","name":"","x":440,"y":145,"wires":[["bff0f422.3cafe8"]]},{"id":"bff0f422.3cafe8","type":"function","z":"55626b8c.8b2f54","name":"url","func":"var word = msg.payload.word[Math.random() * msg.payload.word.length | 0];\nmsg.url = `https://www.googleapis.com/customsearch/v1?key=[API_KEY]&cx=[CUSTOM SEARCH ENGINE ID]&searchType=image&q=[固定文字列]+${word}&lr=lang_ja&ie=UTF-8`;\n//[]←を書き換える\nreturn msg;","outputs":1,"noerr":0,"x":260,"y":203,"wires":[["ed9536bd.0bb548"]]},{"id":"ed9536bd.0bb548","type":"http request","z":"55626b8c.8b2f54","name":"","method":"GET","ret":"txt","url":"","x":463,"y":206,"wires":[["de50fee7.7f952"]]},{"id":"de50fee7.7f952","type":"json","z":"55626b8c.8b2f54","name":"","x":602,"y":207,"wires":[["acbfa189.93e27"]]},{"id":"acbfa189.93e27","type":"function","z":"55626b8c.8b2f54","name":"jsonから画像だけ","func":"var r = Math.random() * 10 | 0;\nmsg.payload = msg.payload.items[r].link;\n\nreturn msg;","outputs":"1","noerr":0,"x":541,"y":264,"wires":[["54acff66.965d"]]},{"id":"89b95091.3b1cc","type":"comment","z":"55626b8c.8b2f54","name":"検索ワードの配列","info":"","x":415,"y":93,"wires":[]},{"id":"a09d8c89.fcd7e","type":"comment","z":"55626b8c.8b2f54","name":"配列からランダムに検索ワードを追加する","info":"","x":229,"y":244,"wires":[]},{"id":"adbedf56.fa137","type":"comment","z":"55626b8c.8b2f54","name":"▼③WebhookURLをいれる","info":"","x":795,"y":225,"wires":[]},{"id":"ecfd563f.f33dc8","type":"comment","z":"55626b8c.8b2f54","name":"▲②CSE情報及びAPI情報をいれる","info":"固定検索文字列もここで入れる","x":293,"y":281,"wires":[]},{"id":"9500950f.f97c48","type":"comment","z":"55626b8c.8b2f54","name":"▼①ランダム検索ワードを入れる","info":"","x":317,"y":58,"wires":[]}]
```

importは、右上のメニューバーからClipboardを選択し、
<img width="290" alt="39.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/447d338e-eb5a-637c-2acb-271883f3072e.png">

出てきたウィンドウに貼り付ければ、完了です:bulb:
<img width="252" alt="40.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/49118cb9-43be-e62e-d8c9-9cb1562c4055.png">

#次回予告？

そして、そして、、
先日、弊社で@tseigoさんによるWio-Nodeハンズオンが行われ、参加いたしました。
（開催概要：[IoTLT番外編！ WioNodeハンズオン at ウフル](https://iotlt.connpass.com/event/45392/)）
（Wio-Nodeとenebularについてはこちら：[enebularでデータを取りやすいWio Nodeへのシンプルな取得方法](http://www.1ft-seabass.jp/memo/2016/12/03/enebular-wio-node-simple-flow/)）
せっかく、Wio-Nodeが手元にあるので、<img width="77" alt="35.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/132212/4d0a1a28-588f-fa6c-1cc3-38f5c9fc3476.png">の部分をセンサーにして、IoTチックにしてみたいと思います。
来週のAdventCalendarの記事でお披露目予定です！

flow変数を別件でごりごり使ったので、こちらの記事でflow変数やglobal変数について解説できればと思います。