9
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

enebularAdvent Calendar 2016

Day 15

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

Posted at

※この記事は「enebular Advent Calendar 2016」12/15の分です。
初めて自分で「これ作ろう」と思い立って作ってみたものになります。

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

  • enebular
  • Google Cloud Platform
  • Google Custom Search Engine
  • Slack

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

ポケモン生活を快適にする #とは

ポケモン最新作サン・ムーンにはQRスキャンという機能があります。
:basketball:QRスキャンで、新たなポケモンと出会おう!
QRコードを3DSから撮影すると対応したポケモンが図鑑に登録されるという機能です:camera_with_flash:
いまいちしっくりこない方は、バーコードバトラーのQRコード版だと考えてくださればおっけーです。(バーコードバトラーの知名度わからないけど)

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

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

Slack WebHook URL取得

1.PNG とりあえず、functionの中のものをそのまま流す箱を作ります。 テストなのでFlowはシンプルなこんな感じに。 2.PNG functionの中身。 ボタン押すとslack botから「てすと」と送信されます。

SlackのWebhook URL取得手順
を参考にURLを発行します。

3.PNG channel設定などはWebHook URL発行の際に設定できるので、WebHookURLのとこのみの入力で大丈夫です。

先ほどのFlowのinjectノードのボタンを押して発火すると:candle:
4.PNG
きました:v:
なんか、無機質なのでSlackBot設定のページから設定します。

5.PNG はい、かわいい:relaxed: `:heart:`などをメッセージの中に入れれば絵文字も反映されるようです。

Google Custom Search EngineからJSONを受け取る

とりあえずGoogle Custom Searchで画像を取得してみる
google custom search engine(CSE)を使って、検索結果をjsonで取得する
こちらを参考に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
※追記ここまで

16.PNG ひとまず先ほどのURLをhttpのノードに入れて実行してみます。今回はQRコードが欲しいので、検索ワードは「QRコード」です。

debugから見たログ↓
6.PNG
ぎゃああああ

SlackBotから送られてきた文字列
7.PNG
(以下オブジェクト型式でかなりつづく)

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

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

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

enebularでつなげる、整える。

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を成型するために、
17.PNG
こんな感じに組んでみました。順番に説明していきます。

ループの実装

25.PNG ↑ 8の字を描いていていかにもループしていそうなところは、その通りループしています。:curly_loop:

最初の20.PNGでは変数の初期化をしています。

18.PNG

21.PNGで条件分岐しています。

iが10になるまで22.PNGに流れ、同時に23.PNGで変数の値を+1しています。

37.PNGの中身
38.PNG
以下略してますが、画像ごとにメッセージを変えたかったのでswich文使いました。
しかし、ここはenebularのswichを使うとfunctionを書かずに実装できますね。

23.PNGの中身
26.PNG

変数iが足され、10になると最後27.PNGに流れ、処理を終了します。「ループ後の処理」の中身はメッセージを書いているだけなので、割愛します。

ちなみに条件分岐している21.PNGの中身は以下になります。
19.PNG
左下の+ ruleを押すことで分岐先をさらに増やすことができます。

これで35.PNGの左側をポチっと押すと検索結果の画像10件を取ってくることができます。

検索ワードをちょっとだけランダムにしてみる

話戻って、、今回はポケモン生活を快適にするということで、記事を書いています。
きっかけとなった「QRスキャン及び島スキャン」は、同じQRコードを2日連続で使用することができません。(一日置けば大丈夫です。)
なので、10個のQRのセットを検索ワードを変えることで4つ用意することにしました。
先ほどの30.PNG(URLを渡す部分)にちょっと手を加えます。

29.PNG QRコードを使って遊ぶアーケード筐体などからこれらがベストワードでした:raising_hand:~~これもまたアイカツです~~ 「QRコード ポケモン」のように検索していて、「ポケモン」の部分がランダムで分岐する形です。

最初の20.PNGでは変数の初期化をしています。先ほどと一緒ですね。
31.PNGで、その変数をランダムにしているのですが、一つのfunctionで良さそうですね。
33.PNG
中身はこんな感じです。
スマートにmsg.i = Math.random() * 4 | 0;こう書いて、手前のノード消す方がよさそうです。

そこでランダムになった変数を使って32.PNGで分岐させます。

34.PNG

これで完成です。

35.PNGの左側をポチっと押すと、4つの検索ワードからランダムに10件QRコードをゲットしてきます。

test.gif
少し見にくいですが、こんな感じに動いています。

応用編?

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

それでは、現在推しているアイドルの画像を取ってきます:dancer_tone2:
36.PNG
検索文字列を渡す前に、検索用の配列を作って固定文字+ランダム文字の検索を行っています。
後半はloopではなく、ランダムに1つだけ取ってくるような設定をしているので、配列の個数*10通りの検索結果が期待できます。

35.PNGをポチッ:point_left:

15.PNG

Slackがあのちゃんだらけになる!!!
(ノ・ω・)ノオオオォォォ-!!!

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

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

##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を選択し、
39.PNG

出てきたウィンドウに貼り付ければ、完了です:bulb:
40.PNG

#次回予告?

そして、そして、、
先日、弊社で@tseigoさんによるWio-Nodeハンズオンが行われ、参加いたしました。
(開催概要:IoTLT番外編! WioNodeハンズオン at ウフル
(Wio-Nodeとenebularについてはこちら:enebularでデータを取りやすいWio Nodeへのシンプルな取得方法
せっかく、Wio-Nodeが手元にあるので、35.PNGの部分をセンサーにして、IoTチックにしてみたいと思います。
来週のAdventCalendarの記事でお披露目予定です!

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

9
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?