【ハンズオン】Bluemix上のNode-RedでSlack bot を作ろう

*この記事はBluemixユーザー会の初心者向けハンズオンのテキストとして作成されたものです。
そのため時折それに関連するコメントが見られる可能性があります。
(2017年5月1日)　https://bmxug.connpass.com/event/53190/　
（2017年6月14日） https://bmxug.connpass.com/event/57149/　

# ゴール
PaaSであるBluemix上にNode-Red（フローエディタ）を構築し、構築したNode-Red上でAPIを作成し、Slackから作成したAPIを使う。

※Paas:Platform as a Serviceの略、プログラム実行に必要な環境を提供してくれる。
サーバーの構築は使いたい環境をweb上からぽちぽちするだけで、ユーザーはソースコードのみを用意すればよい。
※Node-Red:Node.jsをビジュアルプログラミングするためのツール
参考:https://nodered.jp/
※API:アプリケーションプログラミングインタフェースの略。
アプリケーションの機能を使うために外部に公開されているインターフェース

# やること
- Slackを用意する
  - 自分で用意する(今回は割愛)
  - Slackのチームに参加する
- Slack botの準備をする
  1. Slack botが反応するためのキーワードを設定する
  2. Slackにコメントを書き込むためのAPIを準備する
- Blumix上の環境を構築
  - Bluemixアカウントを作成(https://console.ng.bluemix.net/registration/)
  - Node-Redの環境を構築
  - API作成

# 1.Slackを用意する
 Slackは自分で作る以外はチームに参加済みのメンバーから招待してもらう必要があります。
 あらかじめSlackに登録済みである場合は、Sign-inしましょう。https://slack.com/

## 招待後の登録手順
### 1-1. 招待されるとメールが届きます。Join Nowをクリックしてください。
 ![スクリーンショット 2017-04-08 22.50.12.png](https://qiita-image-store.s3.amazonaws.com/0/92989/bc6f7abf-ffc5-bb31-0bb6-0a90cf11782b.png)

###1-2.次に名前の登録画面に遷移するので、firstNameに名、lastNameに姓、userNameにニックネームを入れます。
　　　　　※userNameはコメントした時に表示される名前で、その他はユーザー詳細画面に表示されます。
　　　　　※本名ばれたくない人は本名でなくても大丈夫です。
![スクリーンショット 2017-04-08 22.50.39.png](https://qiita-image-store.s3.amazonaws.com/0/92989/82b967ac-b36b-046e-76fe-36e581ec0dea.png)
###1-3.パスワードを入力します。
![スクリーンショット 2017-04-08 22.52.31.png](https://qiita-image-store.s3.amazonaws.com/0/92989/1cb14c03-9e86-0ebe-b0f4-94f8898a4491.png)
###1-4.最後にI Agreeをクリックして設定完了です。
※勝手にSlackの画面にリダイレクトされますが表示がうまくいかない方はリロードしてみてください。
![スクリーンショット 2017-04-08 22.52.59.png](https://qiita-image-store.s3.amazonaws.com/0/92989/2a57b387-9016-0a8f-76a5-837c80939246.png)



# 2.Bluemix上に開発環境を準備する
IBM Bluemixアカウントを取得してログインしてください。
https://console.ng.bluemix.net/registration/
アカウント取得方法：http://ibm.biz/freeguide 

## Bluemix上にNode-Redの環境を構築する
###2-1.IBM Bluemixのリージョンや作業スペースを確認する
右上の人型アイコンの左横の文字をクリックすると図のようなメニューが出てきます。地域を「米国南部」に設定してください。組織やスペースは埋まっていると思います。埋まっていなければ任意に新しいものを作りましょう。
スペースは「開発環境」の頭をとって「dev」とすることが多いです。
![リージョン.png](https://qiita-image-store.s3.amazonaws.com/0/141025/74a3d84f-9b43-b15a-bbd2-471ce33e9f13.png)

###2-2.カタログ → Node-RED Starterをクリック
右上の「カタログ」から今回使いたいサービス「Node-RED Starter」を探します。
検索バーから探すか、左のメニューから「アプリ」→「ボイラープレート」と選択してください。
見つかったらクリックして次に進みます。
![スクリーンショット 2017-04-08 23.24.31.png](https://qiita-image-store.s3.amazonaws.com/0/92989/f09f96ac-9fbe-b3af-c483-23451aa20fa4.png)

###2-3.名前に任意の名前をつけて作成をクリック。
※すでに存在する名前だと作れないので、なるべく他の人とかぶらないような名前をつけましょう。
　（名前＋今日の日付だと被りにくいです）
※ここでつけた名前は後でSlackの設定をするのに使います。メモっておきましょう。
![アプリ名.png](https://qiita-image-store.s3.amazonaws.com/0/141025/38d847d6-068f-9fb8-6731-2489c4fa59d1.png)

###2-4.作成したNode-Redにアクセスしてみましょう。
作成したアプリケーションの詳細が載っているページの「概要」のアプリ名の横の「Visit App URL」あるいは「ダッシュボード」の「CloudFoundryアプリ」一覧の「経路」の欄のアプリ名をクリックします。
![NodeREDへ.png](https://qiita-image-store.s3.amazonaws.com/0/141025/af547536-5870-2366-f35c-936942a22132.png)

###2-5.以下の画面が出たら環境構築完了です！
「Go-to your Node-RED flow Editor」を押して先に進みます。
Node-REDを開こうとするとセキュリティ設定を求められますので、以下のURLを参考に設定しましょう。
http://qiita.com/ymunemasa/items/5ae9629670df40eebe04
※アプリ起動に多少時間がかかるかもしれません。そんな時はアプリの状態が「実行中」になっているか確認しましょう。「停止」の場合アプリを「再始動」してみましょう。
![Node-RED.png](https://qiita-image-store.s3.amazonaws.com/0/141025/01130087-eb53-d3b7-3826-4f88be6a5e81.png)

# 3.Node-RedでAPIを作る(その1)
まずSlackからどんなリクエストが来ているかをNode-Red上から見るだけのAPIを作成します。
###3-1.httpリクエストを受けるノードとリクエストの中身を見るためにdebugノードを配置します。
「入力」から「http」、「出力」から「debug」を選んで配置します。
置いた瞬間に「debug」の名前が変わりますが、その状態で問題ありません。
httpの右側の突起からdebugの左側の突起に向かってクリックした状態を保ちながら線を引きます。
![スクリーンショット 2017-04-09 13.02.09.png](https://qiita-image-store.s3.amazonaws.com/0/92989/dc05ca05-5b3a-4784-16d3-f6e64c4eff7b.png)

###3-2.配置したノードをダブルクリックして、ノードの編集画面を開き設定をする
httpリクエストを受けるノードの設定を行うために、httpをダブルクリックします。
この後用いるSlackのOutgoing WebHooksはPOSTという方法でリクエスト（命令）を届けますので、各欄を以下のように設定します。できたら「完了」をクリックします。
- Method:POST
- URL:任意（ここでは/slackという名前にしています。）　
　　　　＊後でここで設定したURLに向かってリクエストが来るように設定します。
![スクリーンショット 2017-04-09 13.02.23.png](https://qiita-image-store.s3.amazonaws.com/0/92989/28496fe2-d43c-b0be-94ba-070d70e52a2b.png)

###3-3.リクエストされた内容を確認するためにdebugノードの設定を行う
今度は「debug」をダブルクリックします。
　（実際にはmsg.payloadという名称に変わっていると思います）
各欄が以下のように設定されていることを確認して「完了」をクリックします。
- Outputーmsg.payload
- to-debug tab
両方のノードの設定が終わったら右上の「デプロイ」をクリックします。
右側の「デプロイ」の下のdebugのウィンドウにエラーが出なければ問題ありませんので次に進みましょう。
![スクリーンショット 2017-04-09 13.03.02.png](https://qiita-image-store.s3.amazonaws.com/0/92989/105bcc42-65a7-9051-4384-8cf0c5a3cf37.png)


#4.APIを使うための設定をSlackに行う
## 作ったAPIを呼ぶ部分を設定する
###4-1. Slackにアプリケーションを追加するために、アプリケーション追加画面を開く
Slackのチーム名をクリックし、メニューが出てきたら「AppS＆Integrations」をクリックします。
![Integration.png](https://qiita-image-store.s3.amazonaws.com/0/141025/09794ea5-6531-12cf-e39b-3f904cfba2a3.png)

###4-2.検索窓に　「out going」と入力し追加したいアプリケーションを検索する
いろいろなサービスがありますが、今回使いたいのは「Outgoing Webhooks」というものです。検索バーに名称を入力し選択してください。
![スクリーンショット 2017-04-08 23.43.06.png](https://qiita-image-store.s3.amazonaws.com/0/92989/16edaa5a-bd3d-7f9a-09da-24781d66ea94.png)

###4-3.Outgoing WebHooksの画面が出たら「Add Configuration」をクリックする
![スクリーンショット 2017-04-08 23.43.20.png](https://qiita-image-store.s3.amazonaws.com/0/92989/657a9595-f581-c161-1553-7ce538f14801.png)

###4-4.Outgoing WebHooksの画面に遷移したら一番下の「Add Outgoing WebHooks integration」をクリックする
![スクリーンショット 2017-04-08 23.43.33.png](https://qiita-image-store.s3.amazonaws.com/0/92989/adc83157-2b14-83ba-4215-a9ada017d2d5.png)
![スクリーンショット 2017-04-08 23.43.44.png](https://qiita-image-store.s3.amazonaws.com/0/92989/2c7e1a78-0c1b-70e1-de51-286737a61017.png)

###4-5.必要な項目を入力する。
Outgoing Webhooksは、Slack上の指定されたキーワードに反応して、指定された先にその特定のキーワードが入力されたということをを知らせにいくというものです。
以下の項目から、「どこ」の「どんな」言葉に反応するかを設定しましょう。
- channel:どのチャンネルの発言を拾うか？
- Trigger Word(s):どんな言葉をトリガーとするか？
※チーム内で同じ言葉でかぶってしまうとどっちも呼ばれてしまうので、なるべくかぶらない言葉にしましょう。
- URL(s):自分で作ったAPIのURL
※http://(userAppName).mybluemix.net/(httpノードの"URL") 
　*userAppName: 2-3でBluemixからNode-REDを立ち上げる際につけたアプリ名 
　*httpノードの"URL":3-2で設定したもの。
　　　→このテキストでは「slack」と設定していました。
![スクリーンショット 2017-04-08 23.47.20.png](https://qiita-image-store.s3.amazonaws.com/0/92989/eb62e719-9b07-14d9-6974-cbd420004c90.png)
設定が終わったら、Save Settingsをクリックします。

### ここで一旦確認
Slack内のOutgoing webhookで設定した部屋から「設定したtrigger word(s)」を打った時にNode-Redのdebugウィンドウにリクエスト内容がちゃんと入ってくるか確認してみましょう。
(内容は個々で違います)
![debug.png](https://qiita-image-store.s3.amazonaws.com/0/141025/c83107c2-4996-7074-18e5-6b364b5168b7.png)


# 5.Slackでリクエストを受ける設定をする
###5-1.検索ウィンドウに「incoming」と入力にして「Incoming WebHooks」を選択します。
Slackに打ち込んだ内容に「Outgoing Webhooks」が反応。
それを「Bluemix」が受けて処理をする。というところまで来ました。
今度は処理をした内容を「Incoming Webhooks」を使ってSlack上に出力します。
検索ウィンドウから「Incoming Webhooks」を検索して選択しましょう。
![スクリーンショット 2017-04-09 22.05.03.png](https://qiita-image-store.s3.amazonaws.com/0/92989/521f0a54-3b13-f0d8-141f-1ddfb391ef7b.png)

###5-2.Incoming WebHooksの画面が出たら「Add Configuration」をクリックする
![スクリーンショット 2017-04-09 22.05.36.png](https://qiita-image-store.s3.amazonaws.com/0/92989/a69ba014-3e74-cad6-5096-85faede7f3ed.png)

###5-3.リクエストを受けた際にメッセージを表示するチャンネルを選びます。
出力したいチャンネルを選んでAdd Incoming Webhooks Integrationをクリックして詳細な設定画面に進みます。
![スクリーンショット 2017-04-09 22.06.08.png](https://qiita-image-store.s3.amazonaws.com/0/92989/368d0947-a68b-7af5-3229-3a5f5c00cf20.png)
![スクリーンショット 2017-04-09 22.06.31.png](https://qiita-image-store.s3.amazonaws.com/0/92989/1fec22b3-4c98-6e2f-569f-3049e7e0dd43.png)
![スクリーンショット 2017-04-09 22.06.45.png](https://qiita-image-store.s3.amazonaws.com/0/92989/9947f36e-c202-968b-72ec-e5c1ae376745.png)

###5-4.次のステップでNode-Red上でURLを使うのでメモっておいてください。
Webhook URLは後で「Bluemixで処理した内容をここに送ってください」という命令を出すときに使います。どこかにメモしておくか、この画面を出しっぱなしにしていつでもコピペできるようにしておきましょう。
設定が終わったらSave Settingsをクリックします。
![スクリーンショット 2017-04-09 22.07.22.png](https://qiita-image-store.s3.amazonaws.com/0/92989/6ce254c2-f680-77dd-ea60-7ea1f0451563.png)

![スクリーンショット 2017-04-09 22.08.00.png](https://qiita-image-store.s3.amazonaws.com/0/92989/35c8fce8-9aec-32e3-b1e2-349d8c82c361.png)


# 6.Node-RedでAPIを作る(その2)
ここでは先ほど作ったhttpリクエストをトリガーに今度はSlack側にリクエストを投げてみましょう。
###6-1.まずは返却値を作成するためにfunctionノードをキャンパスにおきましょう。
Node-REDの画面に戻ります。
「機能」からfunctionノードを選び配置します。httpノードの右側の突起とfunctionノードの左側の突起を結びます。(httpノードからは2つの線が伸びている状態になります)
ここに、Slackから得たキーワードを元に具体的にどのような処理をして欲しいのかを記入します。
※いろんな処理をしたい時はfunctionノードの中身に処理を書いたり、別のノードに置き換えたりします。
![スクリーンショット 2017-04-09 21.08.03.png](https://qiita-image-store.s3.amazonaws.com/0/92989/cf1e0dd2-c729-d459-9239-fee5e1f3cb40.png)

###6-2.今回はSlackに固定値でメッセージを返すようにします。
```ruby:functionノードに記入するコード
msg.payload={
 username:"sample",
 text:"テスト",
}
return msg;
```
上記は「(キーワードを受けたら)"sample"さんが"テスト"と出力します。」という意味です。
" "の部分を変えることでいろんなパターンの反応を生み出すことができます。
- username:発言するアカウント名
- text:発言する言葉　  
※注意：トリガーワードと同じ言葉を設定すると無限ループに入ってしまうので気をつけましょう。
　→例えば"test"というキーワードに対して"test"という返答をするという形にしてしまった場合、またその返答である"test"に対して"test"と返答しようとするので無限ループを引き起こしてしまいます。
SlackAPIのほかパラメータは[こちら](https://api.slack.com/methods/chat.postMessage)を参考にしてください。
![スクリーンショット 2017-04-09 21.11.15.png](https://qiita-image-store.s3.amazonaws.com/0/92989/27391fbd-7ddf-10f0-6111-8fc376306c1f.png)

###6-3.Slackにリクエストを送るためにhttp requestノードをキャンパスに配置します。
Node-REDの「機能」から「http request」を選択し、functionノードの右側に配置します。
![スクリーンショット 2017-04-09 21.07.38.png](https://qiita-image-store.s3.amazonaws.com/0/92989/4b5fd769-0dcb-c60b-538a-d9cbbaf4552a.png)

###6-4.SlackのIncoming WebHooksで設定したURLを転記する。
"POST"という方法を使って、"URL"に向かって結果を出力します。という設定をします。
設定ができたらNode-REDのデプロイをクリックします。
Method:POST
URL:5-4でIncoming WebHooksで設定したURL
![スクリーンショット 2017-04-09 21.17.05.png](https://qiita-image-store.s3.amazonaws.com/0/92989/9540e343-f71c-8727-bdf6-7ee0b9ddf0fb.png)

完成系
![スクリーンショット 2017-04-23 12.25.50.png](https://qiita-image-store.s3.amazonaws.com/0/92989/b14d4f6e-569b-727d-9061-e4bd451a254d.png)


## 動作確認
Slackから「設定したtrigger word(s)　任意の言葉」を打って先に設定したNode-Redのdebugウィンドウからリクエスト内容を確認してみましょう。
Slack上にNode-Red上で設定したtextの内容が表示されたら成功です。

例えば、「テスト」というキーワードを打ったときに「sample」さんかは「test」という言葉を返すという設定にしたときは以下のようになります。
![Output.png](https://qiita-image-store.s3.amazonaws.com/0/141025/cef515b6-1889-2162-ee30-1525e31243f9.png)

工夫次第で色々遊べます。
![help.png](https://qiita-image-store.s3.amazonaws.com/0/141025/f620d68c-71ef-753a-ba6f-e0ecacff2c4c.png)

# おまけ
固定値だけだとつまらないので、おうむ返しするAPIに修正してみましょう。
Node-Red上のfunctionノードの中身を以下のように書き換えてみましょう。
以下の例は、「sampleさんが7文字目までを切り取ってそれ以降の内容を返す」という意味になっています。数字の部分は自分のトリガーワードの文字数に合わせて変えましょう。
（ITの世界は"0"を1文字目として数えるので”7”は8文字目という意味になります）

```ruby:おうむ返しAPI
msg.payload = {
 username: "sample",
 text: msg.payload.text.substr(7),
}
return msg;
```

【注意】
※botを反応させるためのトリガーワードの文字数と同じ数を上の数字の部分に入れましょう。
　　※.substr()はjavaScriptの関数で文字列を切り取る関数です。
※トリガーワードと同じ言葉を返す設定にすると無限ループに入ってしまうので気をつけましょう。
![スクリーンショット 2017-04-09 21.08.39.png](https://qiita-image-store.s3.amazonaws.com/0/92989/71749a70-87af-b27c-bcba-d4be5e412d48.png)

【応用例】

```ruby:おうむ返し応用例
msg.payload = {
 username: "Bluemix",
 text: "'"+msg.payload.text.substr(5)+"?'"+" わかった、すぐやるね",
}
return msg;
```

![おねがい.png](https://qiita-image-store.s3.amazonaws.com/0/141025/c7c4d10b-024e-b4b9-94dc-beb56306a03c.png)



早く終わってしまった方は以下を参考にWatson APIと繋げてみてください。
http://qiita.com/tsota/items/560d1b6f9c6a27aec412

以上です。
少しでも誰かの役に立てたら幸いです。