SlackとGASを使って画像取得BOTを作った話。

突然ですけど、皆さんSlack使ってますか? いいですよね。Slack。洒落てますよね。

今日は義憤に駆られて、SlackとGoogleAppScriptを使って画像取得用のBotを作ったので、その話をしたいなと思います。 欲しい画像をつぶやくと、Google先生から画像を検索してくれてSlackに貼り付けてくれます。

背景

画像レスの応酬が流行していた。 人よりも面白く、小気味よく、洒落ている画像を探そうと必死になっている感じが、非常にうすら寂しく、また気恥ずかしいものであったので、こっそりslackに投げかけたら画像を持ってきてくれる、そんな女性が必要であった。

完成品

画像取得BOT「chikako」

f:id:steroid66:20170515165039g:plain

つくりかた

今回は、GAS(Google App Script)を使って作りました。サーバーレス超便利。 GASについては、こちらの記事の説明が詳しかったです。

tonari-it.com

下準備

まずは、script.google.comにアクセス。新しいプロジェクトを作ります。

f:id:jmty_tech:20170515142120p:plain

次に、Slack連携用の便利なライブラリを入れます。その名もSlackApp。 リソース→ライブラリを選択して、この画面を表示します。

f:id:jmty_tech:20170515143046p:plain

ライブラリ追加のテキストフォームに以下のLibraryKeyを入力後、追加ボタンを押します。 M3W5Ut3Q39AaIwLquryEPMwV62A3znfOO

するとこうなるはず。 f:id:jmty_tech:20170515142649p:plain

次に、Slack側の設定をします。 まずAPI Tokenを取得します。以下のサイトのAuthenticationから取得できます。

api.slack.com

トークンを取得後は再びGASの画面に戻ります。 ファイル→プロジェクトのプロパティ→スクリプトのプロパティからSLUCK_ACCESS_TOKENプロパティの値に取得したトークンを貼り付けて保存します。

f:id:jmty_tech:20170515143620p:plain

最後にSlack側のWebHookを設定します。これでSlackに投稿したものをGASで受け取って諸々の処理ができるようになります。 今回設定するのはSlack側からの発信Hookなので、Outgoing WebHooksです。

f:id:jmty_tech:20170515144454p:plain

これですね。 設定項目は、次みたいな感じ。

f:id:jmty_tech:20170515144637p:plain

どこのチャンネルからの投稿かをChannelで設定して、GASアプリケーションの公開URL(後ほど設定)をURL(s)に入力すればとりあえずは動きます。

以上で下準備おしまい。実際にコードを書いていきましょう。

コーディング

GASはjavascriptで動きます。

function doPost(e) {
  var token = PropertiesService.getScriptProperties().getProperty("SLACK_ACCESS_TOKEN");
  var bot_name = "chikako";
  var bot_icon = "http://d1d7kfcb5oumx0.cloudfront.net/articles/images/567e361c4cc4ed91ee0001af/slide_PC190194.JPG"
  var channelId = "#chikako"
  var message = getGoogleCustomSearchImage(e.parameter.text);
  var slackApp = SlackApp.create(token);
  
  slackApp.postMessage(channelId, message, {username: bot_name, icon_url: bot_icon});
}

このdoPostメソッドが、Slackからのリクエストを受けて走るメソッドです。 tokenは先ほど下準備で保存したSLACK_ACCESS_TOKENのことです。 これで、channelIdで設定したチャンネルに、bot_nameで設定したbotとして、messageをPostできます。

今回は、このmessageを、getGoogleCustomSearchImageというメソッドで検索した画像のURLにします。(Slackは画像URLを貼ると、画像を表示してくれます。)

function getGoogleCustomSearchImage(keyword){
  var API_KEY = "AIzaSyB6hOUmDt3HeiGgd5oeBywz0CNpGv-3tJ4"
  var CSE_ID = "017523893900893021997:fzxbxcm7sus"
  var uri = "https://www.googleapis.com/customsearch/v1?key=" + API_KEY + "&cx=" + CSE_ID + "&q=" + keyword + "&searchType=image"
  
  var response = UrlFetchApp.fetch(uri);
  var json = JSON.parse(response);
  var random_params = Math.floor(Math.random() * json["items"].length);
  
  var result = json["items"][random_params]["link"]
  return result
}

getGoogleCustomSearchImageメソッドではGoogleCustomSearchEngineを利用して、画像を検索しています。

この記事を参考に、API_KEYやCSE_IDを取得 ryutamaki.hatenablog.com

あとは、Slackからパラメーターとして受け取った文言を検索文字として、クエリ付きのuriを作ります。(searchType=imageとすることで画像検索ができます。)

json形式で取得できたら、毎回同じ結果が出るのを防ぐために乱数を作って(random_params)、取得した結果をシャッフルして、該当画像のURLを返しています。

どうですか。出来ましたか。出来たら公開しましょう。

公開

公開→ウェブアプリケーションとして導入を選択します。 以下のような画面が出てくると思います。 f:id:jmty_tech:20170515152537p:plain

ここで注意点が二つ。 GASではコードの中身を変えた場合、プロジェクトバージョンをいちいち更新しないと変更が反映されません。 なので、このバージョン数値の更新を忘れないこと。 もう一つはアプリケーションにアクセスできるユーザーを「全員(匿名ユーザーを含む)」に設定すること。これを忘れて、悲しい時間を過ごしました。 f:id:jmty_tech:20170515152935p:plain

以上がchikako作成の流れでした。 皆さんも心のスキマを埋めるべく、可愛いbotを作ってみてはいかがでしょうか。乾いた日常がほんの少し潤いますよ。 それでは、 f:id:steroid66:20170515163805p:plain 御機嫌よう。