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

  • 16
    Like
  • 0
    Comment
More than 1 year has passed since last update.

参考

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

名前を入力して、アプリIDを作成ボタンを押します。
fb_web_app0_1.png

2.

すると、以下の表示になりますので、Site URL を入力してボタンを押します。
余談ですが、下の画像のぼやかしをするのに Windows10 のフォトでささっとできてビビりました。ビューワー機能しかないと思ってたので……。
fb_web_app1.png

3.

次のところでおもむろに Next Steps の4つのどれかを押しそうになりますが、よく分からないので文中にある「Skip to Developer Dashboard」のリンクを押して終了。
これでアプリが作成されました。
fb_web_app2.png

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

1.

アプリのページになるので、左のメニューのMessengerを押します。
fb_web_app3.png

2.

そして右側2段目にある「SetUp Webhooks」ボタンを押します。
fb_web_app10.png

3.

そうすると、以下の表示が出ます。
ここで 大きな落とし穴 があります。
コールバックURLが、今まさに動作しないといけません!
さらに、コールバックURLが、リクエスト内にある hub.challenge パラメータの値を返さなければいけません!
なぜなら、「確認して保存」ボタンを押した瞬間に確認リクエストがとんでくるからです。
その準備ができたら、画面にコールバックURLとトークンを入力し、「確認して保存」ボタンを押します。
fb_web_app11.png

4.

再度、左のメニューから Messengerを選んで、右上段の「Facebookページ」を選択すると、ページアクセストークンが発行されます。
fb_web_app20.png

5.

Facebookのここに以下のように書いてある。

  1. 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のほうが反応が速い気がするのは、日本というロケーションのせいだろうか。
  • やっぱり画像とかも試してみたいので、そのうちやるかも。
  • 使うのもなかなかだけど、API作る人はたぶんもっと大変。
  • この流行りのおかげで、人のコミュニケーションって確かにこんなんだなあ、と思いつつ、Request/Responseというよりは、Send/Receiveのほうがしっくりくるなあ、と思ったところ。