SinatraでLingr Botを作ってみる(1)

##概要

SinatraでLingrで何かをつぶやくと返答を投稿してくれるBotを作成したいと思います。とりあえず最初は簡単なものを、後々はスクレイピングでWebサイトから情報を引き出すBot（未定…まぁ、なんか役に立ちそうなbot）を作っていきます。

##Sinatraとは
最小限の労力でRubyのWebアプリケーションを作れるフレームワーク

[Sinatraチュートリアル](http://www.sinatrarb.com/intro-ja.html)

## Hi-botの作成
まずはLingrで"hi"と投稿することで、"Hi,(投稿者名)"と投稿してくれるBotを作成します。

###Lingr Bot作成にあたって
[Lingr Bot API](https://github.com/lingr/lingr/wiki/Lingr-Bot-API)を利用します。[Webhook](https://webhooks.pbworks.com/w/page/13385124/FrontPage)です。
>Webhook（Webコールバック、HTTPプッシュAPIなどと呼ばれる場合もあります）はあるアプリケーションから別のアプリケーションに対してリアルタイムな情報提供を実現するための仕組みです。
参照　[Webhookとは？](https://sendgrid.kke.co.jp/blog/?p=1851)

これを利用することで、何かしらのイベントをトリガーにしてHTTP POSTがおこります。今回だとRoomでの発言がトリガーになりますね。

####Lingrでの発言の内容
Lingrでの発言の情報はJSON形式でリクエストボディに埋め込まれてURLに送られます。
#####よく使われるパラメータ一覧

- events[配列]
  - message
      - nickname[発言者の名前]
      - text[発言内容、投稿した内容]
      - room[Room id]


###ディレクトリ構成
全てappディレクトリ下に置くものとします。

- 　Gemfile
- 　Gemfile.lock
- 　app.rb
- 　 Procfile


```ruby:app.rb
require 'sinatra'
require 'json'

post '/hi' do
  j = JSON.parse(request.body.read)                # request.bodyを読み込んでJSONをパース。hashに変換。
  j['events'].select{|e| e['message']}.map{|e|
    if e['message']['text'] == "hi" then           # 発言が"hi"の場合
      return "Hi, #{e["message"]["nickname"]}!"    # 発言者の名前がe["message"]["nickname"]の部分に入る
    else                                           # 発言が"hi"以外の場合
      return ""                                    # ""を返すようにしておけばLingrの方にPOSTはされない。
    end
  }
end
```


```Gemfile:Gemfile
# frozen_string_literal: true
# A sample Gemfile
source "https://rubygems.org"

gem "sinatra"
gem "json"
```

```Procfile:Procfile
web: bundle exec ruby app.rb -p $PORT  
```


bundle installをしてgemをインストールする。

###POSTしてみる
デプロイする前にきちんと動くかどうかを確認します。
そのためにはcurlコマンドを利用するのが良いと思います。
例として[Lingr Bot API](https://github.com/lingr/lingr/wiki/Lingr-Bot-API)のサイトに載っているJSONをPOSTしてみます。（textだけhiに変更してます。）
JSONファイルはsample.jsonとしてapp.rbと同じディレクトリに置きます。

```json:sample.json
{"status":"ok",
 "counter":208,
 "events":[
  {"event_id":208,
   "message":
    {"id":82,
     "room":"myroom",
     "public_session_id":"UBDH84",
     "icon_url":"http://example.com/myicon.png",
     "type":"user",
     "speaker_id":"kenn",
     "nickname":"Kenn Ejima",
     "text":"hi",
     "timestamp":"2011-02-12T08:13:51Z",
     "local_id":"pending-UBDH84-1"}}]}
```

ローカルでサーバを起動してアプリケーションを動かしつつ（$ foreman start）、以下のコマンドを打ちます。

```
$ curl -X POST -H "Content-Type: application/json" http://localhost:5000/hi -d @sample.json 
```

JSONファイル名の前には@をつける。
これで端末に"Hi,Kenn Ejima!"が返って来ればokですね。発言内容を変えて試したい時にはJSONファイルのtextの部分の内容を変えれば大丈夫です。hi以外の発言には返答しないように作っているので、textをyay!に変更してcurlコマンドを実行すると、何も返ってこないはずです。

###デプロイ
herokuとかにデプロイします。sample.jsonは必要ないのでgitignoreしておく。

###次にLingr側の設定
LingrでSettingsを開きます。
Developerのページのcreate a new botからBot idとCallback URLを設定します。(httpsだとエラー起きるのでhttpで設定)
Callback URLはデプロイしたアプリケーションのURLを設定します。
これでbotが作成されます。
続いて作ったbotをRoomへ導入します。

###作成したbotをLingrのRoomへ導入する
LingrのSettingsからbotの作成が可能です。
SettingsでRoomsタブを選択。そこからbotを導入したいRoomのmanageをクリックします。(owner権限を持っているRoomである必要があります。)
Botsタブを選択し、作成したbotのidを入力します。
これで、Roomへのbotの導入が完了しました。
あとは実際にhiと投稿してみてください。'Hi,(投稿者名)'の投稿が返って来れば成功です。

##まとめ
とりあえず簡単なbotはこれで作れました。次回からもう少し役に立ちそうなbotを作っていきたいと思います。

###参照一覧
- [Sinatraチュートリアル](http://www.sinatrarb.com/intro-ja.html)
- [Lingr Bot API](https://github.com/lingr/lingr/wiki/Lingr-Bot-API)
- [Webhook Wiki](https://webhooks.pbworks.com/w/page/13385124/FrontPage)
- [Webhookとは？](https://sendgrid.kke.co.jp/blog/?p=1851)