今更ながらFacebook「Messenger Platform（Beta）」を使ったEchoサーバをRails4で書いてみる

# 参考
- [Facebook　アプリID取得方法](http://biz.comlog.jp/manual2/20098.html)
- http://qiita.com/betchi/items/539f5e32cd9a9c8d2db4
- http://qiita.com/pochi-sato/items/f3f5598e36c1fa92d840
- https://developers.facebook.com/docs/messenger-platform/quickstart
- http://qiita.com/fuji_syan/items/85723cb5e53ec6dc9e95

# 1. SSLで通信できるウェブサーバを用意します
コールバックURLはSecureじゃないと怒られますので。
SSL証明書がない場合、ご用意ください。参考までにCSRの作り方です→http://qiita.com/kskomori/items/ba84ae0bb6a3b5bf6305

# 2. フェイスブックページを作ります
フェイスブックページが必要らしいので、あらかじめ作っておきましょう。

# 3. フェイスブックアプリを作ります
### 1.
Androidアプリとか大変なので、ウェブサイト用アプリ（って呼び方でいいのかな？　よくわかってない）を作成します。
こちらから作成します → https://developers.facebook.com/quickstarts/
※ 開発者登録をしていない場合、開発者登録のボタンがでますので押します。

では、ウェブサイト用アプリを作成します。下の www を押します。
![fb_web_app0.png](https://qiita-image-store.s3.amazonaws.com/0/18321/0f61abc1-b674-29d1-61a2-ae2303a26c82.png)


名前を入力して、アプリIDを作成ボタンを押します。
![fb_web_app0_1.png](https://qiita-image-store.s3.amazonaws.com/0/18321/1ef8d535-4ade-1684-61cc-a0c52b205bb8.png)

### 2. 
すると、以下の表示になりますので、Site URL を入力してボタンを押します。
余談ですが、下の画像のぼやかしをするのに Windows10 のフォトでささっとできてビビりました。ビューワー機能しかないと思ってたので……。
![fb_web_app1.png](https://qiita-image-store.s3.amazonaws.com/0/18321/3a7cb06e-b523-dcfa-1b36-fc9d31645255.png)

### 3. 
次のところでおもむろに Next Steps の4つのどれかを押しそうになりますが、よく分からないので文中にある「Skip to Developer Dashboard」のリンクを押して終了。
これでアプリが作成されました。
![fb_web_app2.png](https://qiita-image-store.s3.amazonaws.com/0/18321/947122c4-5192-6bd9-bef3-421ce0cd6136.png)


# 4. アプリの設定～ページアクセストークン発行

### 1.
アプリのページになるので、左のメニューのMessengerを押します。
![fb_web_app3.png](https://qiita-image-store.s3.amazonaws.com/0/18321/d0e901e9-d71b-5d15-ae46-2a22bd58010f.png)

### 2.
そして右側2段目にある「SetUp Webhooks」ボタンを押します。
![fb_web_app10.png](https://qiita-image-store.s3.amazonaws.com/0/18321/15122fb9-8cb5-9753-c985-5c4f6407d6f3.png)

### 3.
そうすると、以下の表示が出ます。
ここで **大きな落とし穴** があります。
コールバックURLが、**今まさに動作しないといけません！**
さらに、コールバックURLが、**リクエスト内にある hub.challenge パラメータの値を返さなければいけません！**
なぜなら、「確認して保存」ボタンを押した瞬間に確認リクエストがとんでくるからです。
その準備ができたら、画面にコールバックURLとトークンを入力し、「確認して保存」ボタンを押します。
![fb_web_app11.png](https://qiita-image-store.s3.amazonaws.com/0/18321/0d447de5-3191-e104-391c-546e7db2cade.png)

### 4.
再度、左のメニューから Messengerを選んで、右上段の「Facebookページ」を選択すると、ページアクセストークンが発行されます。
![fb_web_app20.png](https://qiita-image-store.s3.amazonaws.com/0/18321/f159fe61-e882-8cc9-3d5a-e31fd4687f2c.png)

### 5.
[Facebookのここに](https://developers.facebook.com/docs/messenger-platform/quickstart#next-steps)以下のように書いてある。
> 4. Subscribe the App to the Page

> Using the Page Access Token generated in the previous step, make the following call. This will subscribe your app to get updates for this specific Page.

果たしてよくわからない。
たぶん、フェイスブックページの更新がアプリで取れる、ってことかな？
よくわからないい。ので、ひとまずコマンド打っておきます。
```$ curl -ik -X POST "https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=ここはページアクセストークンをいれる
```

# 5. いよいよRailsでEchoしてみる
### 環境
Rails:4.2.0
Ruby:2.1.3p242（with rbenv）
gem:faraday

### コード（コントローラ）
```
class FbBotController < ApplicationController

  protect_from_forgery except: :callback

  FB_WEBHOOK_VERIFY_TOKEN="WebHook登録時に入力したトークン"
  FB_PAGE_ACCESS_TOKEN="フェイスブックページのページアクセストークン"

  # WebHooks登録時コールバックURL
  def subscribe
    if params["hub.mode".to_sym] != "subscribe"
      render text: "Error. wrong mode" and return
    end

    if params["hub.verify_token".to_sym] != FB_WEBHOOK_VERIFY_TOKEN
      render text: "Error. wrong verify_token" and return
    end

    render text: params["hub.challenge".to_sym]
  end

  # コールバックURL
  def callback
    messaging = params[:entry][0][:messaging]

    messaging.each do |event|
      # post_text() で送ったものもコールバックされるので判別してる
      # if event.include?(:delivery) でもいいかもしれないがどうだろう
      unless event.include?(:message)
        logger.info("NO MESSAGE(maybe from BOT):sender=#{event[:sender][:id]}")
        next
      end

      from = event[:sender][:id]
      to   = event[:recipient][:id]
      msg  = event[:message][:text]

      post_text(from, msg)
    end

    render text: ''
  end


private

  def post_text(to, text)
    msg = {
      recipient: { id: to },
      message:   { text: text },
    }

    conn = Faraday.new(url: 'https://graph.facebook.com') do |builder|
      builder.request :url_encoded
      builder.response :logger
      builder.adapter Faraday.default_adapter
    end

    endpoint = '/v2.6/me/messages?access_token=' << FB_PAGE_ACCESS_TOKEN
    res = conn.post endpoint do |req|
      req.headers['Content-type'] = 'application/json; charset=UTF-8'

      req.body = msg.to_json
    end
  end

end
```

### 注意
1. コールバックURLが HTTPステータス200を返さないと、延々とリトライしてくる
2. BOTが送ったメッセージもコールバックURLに流れてくるから気をつけて


# 6. 所感
- [前にやったLINE BOTのほう](http://qiita.com/kskomori/items/6718babf55a283fe267e)が反応が速い気がするのは、日本というロケーションのせいだろうか。
- やっぱり画像とかも試してみたいので、そのうちやるかも。
- 使うのもなかなかだけど、API作る人はたぶんもっと大変。
- この流行りのおかげで、人のコミュニケーションって確かにこんなんだなあ、と思いつつ、Request/Responseというよりは、Send/Receiveのほうがしっくりくるなあ、と思ったところ。