node-redにSlackをつなげてみる

## はじめに
前回、node-redの立ち上げをしてみました。いよいよ、開発工程に入れるわけです。今回はSlackを接続することで、どんなことができそうなのか想像する、最初の一歩にしたいと思います。

## Slackとは
社内コミュニケーションツール（メッセージングアプリ）として世界的な王様なわけですが、日本のコミュニケーションツールで言えばLINEなどが圧倒的であまり普段使いされていない印象かもしれません。グループでのコミュニケーションに特化しているのでサインアップの仕方やアプリ内での操作もコンシューマ市場発のツールと大きく印象が異なると思います。また早くからBotの解放がされていたのもあり、開発者にやさしく、かつユーザーにとって拡張性の高いものです。詳しくは（正確には）検索するなどしてください。

## Slackのサインアップ
アカウントやチームのない方は、こちらの記事を参考に作成してください。
http://qiita.com/dasisyouyu/items/4f227e1616417dd31673
![IMG_0143.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/dbb149ed-f74a-231c-548a-fc8c6380a533.png)


## Botの作成、有効化
目的は後述しますが、まず3種類のサービスを有効にします。慣れない単語が並ぶので迷子になるかも知れませんが、メニューから『Configure apps』『Manage apps』などを探して、この画面まで来ましょう。直接検索窓からでも次の章に進めます。
![IMG_0145.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/43440613-2a5c-7dc4-1fd3-2832a01e83a0.png)

### Bots
Botと双方向の対話をするときに使います。今回のケースではこれだけでも構いません。
![IMG_0162.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/32d2e007-b5b3-f247-51c4-7597eb778095.png)

"bots"を検索し、この画面にきます。
![IMG_0163.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/ac669cf2-cf44-138a-faad-5328329d1380.png)

Add Configurationすると下の画面が立ち上がります。
![IMG_0164.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/3101812c-a0ca-807d-5d0e-7283b2478931.png)

ここで、API Tokenと示された値が後ほど使われますので、メモ帳などにコピーしましょう。名前の通り鍵みたいなものですので、他人にはバレないように隠し持ってください。
![IMG_0165.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/67034298-6569-8789-3e4f-94ce8455ae96.png)

貼り付けができたらSave Integrationします。
![IMG_0146.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/14f0f8f7-47c7-68e7-8af9-e9e6dc38df10.png)


### Incoming WebHook
Botからチームへのメッセージを送るとき（主に定時連絡など）に使います。先ほど同様"webhook"で検索です。
![IMG_0146.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/6834dac1-1f71-41ae-a2da-9d14e15e1a7a.png)
![IMG_0147.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/f4ca8376-b725-86ab-fa35-c6bfbeba6cdb.png)

ページ中腹にある"Webhook URI"をAPI Token同様、大事にコピペし、最下部でSave Settingしてください。また、その上の窓で『Post to Channel』が『#general』になっていることを確認しておいてください。そのままでよいです。
![IMG_0156.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/9fbdf944-1d02-8d05-0e8e-9cd56ab6ed2e.png)

### Outgoing WebHook
チームからBotへのメッセージを送る（Botが特定単語を検知する）ときに使います。
![IMG_0149.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/8be1db35-52a4-0d9d-6a01-7f7d6022b06c.png)
![IMG_0150.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/03e0b91e-fccf-7560-6c25-0a2092ff0ad8.png)

あらかじめ設定した単語にヒットしたときだけBotが反応しますので、よく考えて単語を設定しましょう。『こんにちは』とか『〇〇して』などの自然言語よりも、『/set』など、人間同士のコミュニケーションでは使われない文字列でセットされることが多いと思います。なぜ？と思う方も、やってみると頷けると思います。まぁとりあえず『test』でいいですかね。
![IMG_0170.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/94bbcb82-5b2c-29bb-cb82-d084f7eded98.png)
Trigger Word(s)に入力してください。あと、URLに『https://(自分のサービス名).mybluemix.net/slack』と書いて（あとで使います）、Saveします。

## node-red への実装
node-red には標準で使えるノードと、自分で作る/読み込むノードがあります。便利なものが第三者からたくさん公開されていますので、積極的に使っていきましょう。
### slack node の読み込み
右上メニューから呼び出せる『パレットの管理』から、ノードを検索、追加します。『slack』と検索するとたくさん出ますね。
![IMG_0166.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/6c857649-6c04-4275-3771-bba156985c27.png)
![IMG_0167.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/d898284f-d8fb-1a6c-a26d-0504d97c6a1b.png)
![IMG_0168.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/d144623f-9ec2-d2f2-2167-b120ceacfd0c.png)
どれを選べば良いかわかりません（汁）。個人的にいくつか試してみたのですが、そもそも制作元がオススメしていないもの、しばらく使うと固まるもの、再起動すると読み込まれないもの、などがあり、今回は何とか動いた『node-red-contrib-slack』を採用することにします。メジャーバージョンの高いものが良さそうかということも、今回のケースではなさそうでした。

![IMG_0169.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/1a1e0534-8934-db87-4299-1b9cc3ce91f3.png)
『ノードの追加』を押すと読み込みが始まり、終わるとパレットに追加されています。物によっては再起動が必要になりますので、メッセージに従いましょう。
### slack nodeの配置
前項のslackホゲホゲが読み込まれると、左のパレットにアイコンが出ていますので（見つからなければ検索してみましょう）、ドラッグしてフローに配置します。『Slack Bot In』と『Slack Bot Out』を持ってきます。
![IMG_0171.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/05be046e-d84e-9340-95d3-fe86cf82d6ac.png)
名無しのノードになるようなので、ダブルクリックして『Slack In』『Slack Out』などとつけておくとよいです。
### slack nodeの設定
配置したふたつのノードを再度ダブルクリックして、先ほどBotsから抜き出したAPI Tokenをペーストして保存します。
![IMG_0172.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/75f6742d-ea16-ee56-b38f-fa6b4819bf1c.png)

### debug nodeの配置
このノードはずっとお世話になります。開くとペイロードだけか全部か設定できるようになっていますが、今回は気にしなくてよいです。デフォルトのペイロードだけのままにしておきましょう。
![IMG_0173.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/dfd133a8-0173-9b80-0f0b-5e7b7564f684.png)

### 接続と試験
配置済みのSlack InとSlack Out、Slack Inとdebugを繋ぎます。node-redではノードの左からinputされたものをノードが処理して、右にoutputするという約束があります。自動的にノード接続の配置も左から右に流れることになります。今回は不要ですが、上から下という方向も意識して接続すると、美しいフローになりますので覚えておいてください。
![IMG_0174.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/3eac301b-b44f-d6d3-2a05-a5fda2032412.png)

接続したら右上の『デプロイ』を押します。これが反映の行為であり、押されるまでは何も動きません。
![IMG_0175.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/3531e015-daaf-2d82-c487-33e04f45a02f.png)

さて、途中ではありますが開発されたプログラムが公開されたはずですので、slackクライアントから何か送ってみましょう。『テスト』。
![IMG_0176.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/64ecc32e-a75e-d7c2-7ca5-5d964f7098ab.png)

順調ですね、簡単ですね。node-redの画面に戻り、右にあるタブを選択して、何か表示されているか、確認してください。
![IMG_0177.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/479da319-b2e2-fea3-a517-aa6a065f6de7.png)

『テスト』と表示されていれば、試験は成功です。次に進みましょう。

### changeノードの配置
これも便利なノードでよく使います。
![IMG_0181.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/49068c58-07be-4259-26ba-cd7ce7162d05.png)
適当に配置して、こんな風に繋いでみました。
![IMG_0178.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/f347e39b-f54a-e0fe-653f-54262a16614c.png)

前項のdebugノードでチラ見しましたが、node-redでは『msg.hogehoge』という形（オブジェクト）でノード間の情報を渡します。代表格なものがmsg.payloadですね。もう一度debugの出力を確認すると、確かに『msg.payload』に『テスト』が格納されているのがわかります。先ほど入れたノード経由でslackクライアントに値を渡すときは『msg.payload』に格納することが定められているようですので、それをchangeノードで、まず定数の埋め込み（変更）を実装してみます。
changeノードを開き、1番下の窓に『てすと』と入れてやります。
![IMG_0179.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/75a7a546-76bb-1b29-d8bd-7836b5044574.png)
忘れずにデプロイしてから、試してみましょう。何を言われても『てすと』と応える残念な子に無事劣化しました。

### 接続と試験
slack inノード、changeノード、slack outノードを直列で繋ぎます。理解のため、それぞれoutput側にdebugノードも並列で接続しておきましょう。
もう一度slackクライアントから『テスト』と送ってみると、、『てすと』返ってきました！完了！！debugノードがたくさん反応しているはずですので、次項の解説で触れていきます。
### 解説
slack inノードは、クライアントから送られてきた『テスト』という値を『msg.payload』というオブジェクトに乗せ、outputします。changeノードはそれをinputとして処理（『てすと』と上書き）し、やはり『msg.payload』というオブジェクトに乗せて値をoutputします。クライアントは『てすと』という値を受け取り、表示させるわけです。今回は定数（固定値）を代入しましたが、当然変数も扱えます。ちょっとChangeノードを過信していたので、次回Functionノードが登場した際に触れていきます。

## Incoming Webhookを使う
前項までで目的は達成しましたが、ユーザーからのinputがなくても動作させたいときにIncoming Webhookが便利です。早速ですがパレットからinjectノードを配置します。
![IMG_0182.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/c5c99ea2-d829-346d-1d71-3bc50636de03.png)

Timestampなんて名前に変わっちゃいましたが、気にせず開いて、『日時』を『文字列』に変えてやってください。
![IMG_0183.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/f81d7563-d3de-0ed5-1c63-cdd207fcb0f9.png)

テキストは『おはよう』をセットし、 『完了』を押します。馬鹿みたいな名前に変わりましたね。
![IMG_0184.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/317d4e89-1b3e-4f3d-8f78-5a8786ecceca.png)

injectノードは便利で、左に見えるボタンを押してアクションすることができます。試しに押してみると、下図のようにDebugノードが反応し、『msg.payload』に『おはよう』と格納されたことが確認できました。
![IMG_0185.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/5901102b-8417-9fb8-e65c-d737541f27bb.png)

次に、『Slack』ノードを配置してください。
![IMG_0189.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/fadd2f12-3df9-9de4-2aec-0f2e4d970f84.png)
これを開いて、先ほどメモしたWebhook URIを仕込みます。ここで思い出したいのが、Incoming Webhookを設定した際に『Post to Channel』が『#general』だったことです。一度クライアント画面に戻って、#generalにBotを招待してあげましょう。
![IMG_0190.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/5e7d65c0-6e1f-f272-86ef-ef80efcd16ac.png)
無事招待できたら、もう一度node-redのinjectionボタンを押してみてください。
![IMG_0191.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/52a22912-a8a4-3307-f44a-2d7736b7719e.png)
アホの子が愚直に『てすと』なんて返していますね、今日も平和です。


## Outgoing Webhookを使う
乱暴でごめんなさい。http inノード、Changeノード、http requestノード、debugノードをこんな感じで繋いでください。
![IMG_0192.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/e7e38ea1-d16c-8108-fc1f-6e9cf7e2b619.png)

http inノードはメソッドを『POST』、URLを『/slack』とします。さっきOutgoing Webhookで設定したものですね。なおdebugノードはmsgオブジェクト全体としてください。
![IMG_0193.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/7fbb5a49-f89f-2223-6e51-5c3514774abc.png)
クライアントから、先ほど設定した『test』と送ってみてください。
![IMG_0194.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/ca03431e-fec4-3525-0ba8-895d3be69510.png)
いくつかdebugノードが検知し、ログが出ました。ログをマウスオーバーするとどのノードのメッセージか赤い破線で教えてくれますので、最初のノードががハッチされていることを確認し、ログを開いてください。先ほどは『msg.payload』に文字列が格納されていましたが、今回はその下の『text』に格納されていることがわかります。この場合、そのまま続けて『msg.payload.text』という位置（オブジェクト）ということになります。さて、クライアントに出力するために『http request』ノードを使うのですが、メソッドを『POST』、URLはIncoming Webhookの項でコピーしたWebhook URLを貼り付けてください。
![IMG_0195.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/e947ba1d-42d7-cf6a-71fc-0676282fca62.png)

これで、送信する準備はできたのですが、まだ値を入れるべきmsg.payload.textには受信時のテキストが入っています。これをChangeノードで置き換えてあげましょう。
![IMG_0196.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/24c0fa2c-5efa-d35c-5e3d-0e5ad9bca1cd.png)
名前はなんでもいいです。トリガーワードで受信して受信したという事実以外は不要なのでmsg.payloadごと削除しちゃいます。次にmsg.payload.textに『hello』と入力し、完了で閉じます。
![IMG_0197.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/7a546cfe-0891-8062-f670-77c12c711a83.png)
クライアントから『test』と送信したところ、何だか賑やかになりました。おバカBotが『test』にも『hello』にも反応しているからですね。ここで気をつけて欲しいのが、仕込む文字列次第で反応が止まず、無限ループしてしまいます。やってしまっても慌てず、ノードの接続を解除しデプロイするなど、追いついて対処してあげましょう。


##おわりに
slackの3機能であるBots、Incoming Webhook、Outgoing Webhookと、node-redで大活躍するhttp inノード、changeノード、http requestノード、debugノードに加え、Slackの3ノードを使ってみました。これら機能だけでも十分実用的なBotが作れることを想像いただけたかと思います。ちなみに上記でも触れましたが、導入したSlackのノードが不安定なので、十分に検証するか、標準のノードで対応することをおすすめします。

## 今後の計画
- [x] [まずはnode-redをBluemixで立ち上げます。無料枠で。](http://qiita.com/KURO-BLACK/items/77af2c98940320ca6ce9)
- [x] [Slackをただ繋げてみます。](http://qiita.com/KURO-BLACK/items/0cb3fac16c26876e5d00)
- [ ] [IBM Watson ConversationをSlackから叩いてみます。](https://qiita.com/KURO-BLACK/items/95a70d203d5fc90fd980)
- [ ] node-redでSlackとConversationを接続してみます。
- [ ] Google Calendarに予定を投げて秘書に会議を設定してもらいます。

## 参考リンク
http://qiita.com/friendtree16/items/154b75ff4669333fd530