うちのいぬ Tech Blog

Tech Blog of Uchinoinu/My dog

うちのいぬ - うみちゃんと話せるbotを作りました 2 - Facebook bot を Heroku と Rails を使って作ってみた

前回、概要と昨日までの成果物を書きました↓

http://satomi.hatenablog.jp/entry/2016/06/25/213801satomi.hatenablog.jp

今回はFacebook botをどう作ったか書きます。

環境

Heroku Ralis 4.2 Ruby 2.2

Uchinoinu - MyDogはbotだけじゃなくウェブサービスも用意しているので、Railsを使っています。

botだけならsinatraであったり、そもそもWAFを使わなくっても大丈夫だと思います。

また、Rubyでなくても、JavaScriptでもJavaでもScalaでもGoでもなんでも大丈夫です。

ただ、JavaScriptが一番サポートが多いイメージで、PHPだとノウハウがネット上に溢れている感じがします。

成果物

f:id:susanne:20160615085808p:plainf:id:susanne:20160625213354p:plain

まだまだオウム返しなままです。

(来たメッセージに対してどう返信するかという部分は別ドメインなので、別に作ります)

作り方

これを読めばOK

developers.facebook.com

ここに基本的に全部書いてあります。

この通りにやれば、問題なくつくれます。

Railsであれば

1. Facebook Developerサイトから新しくアプリを作成

f:id:susanne:20160626094409p:plain

関係ないですけど、↓のやり方って好きです

f:id:susanne:20160626094549p:plain

2. Product Setup で Messengerを選択

f:id:susanne:20160626094634p:plain

f:id:susanne:20160626094852p:plain

3. Messengerアプリの管理画面

f:id:susanne:20160626094922p:plain

4. Webhook として CallbackとかTokenを設定

f:id:susanne:20160626095018p:plain

CallbackはいわゆるFacebookからのアクセスを捌くURLです。

Controllerを作ってRoutingをふっておきます。

Tokenは自由に設定します。

例えば

URL: /api/v1/facebook/callback TOKEN: hogehoge

def callback
   if params["hub.verify_token"] == "hogehoge"
      render json: params["hub.challenge"]
   else
      render json: "Error, wrong validation token"
   end
end

↑のコードは審査用のコードです。

Facebookの審査?アクセスチェック?を経て、

大丈夫なら↓の様な表示がでます。

f:id:susanne:20160626095349p:plain

5. Access Tokenを発行

f:id:susanne:20160626100026p:plain

Messenger botFacebook Pageに紐づくので、

既存のページか新規ページを作成して、紐付けます。

botではこのページとのやりとりになります。

6. Curlテスト

$ curl -ik -X POST "https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=YOUR_TOKEN"

f:id:susanne:20160626100323p:plain

7. Facebook Messengerアプリからテスト

Facebook Messengerアプリの「友達やグループを検索」から、アプリorページを検索します。

友だちに追加して、チャットしてみます。

Callback URLにRequestが来くることを確認します。

このとき、アプリから自分のbotアプリorページが見つかるのは、結構嬉しかったです(´∀`)

8. メッセージを返すコードを書きます。

基本的に何を書けばいいかは公式ドキュメントやネット上のリソースを見れば大丈夫だと思います。

1つ面倒くさいのは、自分からのメッセージ(botからのメッセージ)も、相手からのメッセージもすべて、このURIにリクエストが来ます。

自分(bot)からのメッセージはスルーする様な制御しないと

自分(bot)のメッセージが繰り返される無限ループに陥り、ヤバいbot化します。

f:id:susanne:20160626101640p:plain

例↓

      class FacebookController < ApplicationController
        def callback
          message = params["entry"][0]["messaging"][0]

          if message.include?("message")
            sender = message["sender"]["id"]
            text = message["message"]["text"]

            # 自分からのメッセージなのかどうかチェック
            if sender != "hogehoge"
              # 相手からのメッセージ

              endpoint_uri = make_endpoint_uri

              response_content_json = make_response_content_json(sender, text)

              respond_to_msg(response_content_json, endpoint_uri)

            else
              # 自分からのメッセージ
              p 'msg from bot '
            end
          else
            p 'msg from bot(not include message)'
          end

          render :nothing => true

        end

        def make_endpoint_uri
          'https://graph.facebook.com/v2.6/me/messages?access_token=' + ENV['FACEBOOK_BOT_TOKEN']
        end

        def make_response_content_json(sender, text)
          response_text = make_response_text(text)
          request_content = {
              recipient: {id:sender},
              message: {text: response_text}
          }
          request_content.to_json
        end

        def make_response_text(text)
          # 来たtextを分析したり、
          # 返却するtextを作成したりします
          # とりあえずtextを返す
          text
        end

        def respond_to_msg(response_content_json, endpoint_uri)
          RestClient.post(endpoint_uri, response_content_json, {
              'Content-Type' => 'application/json; charset=UTF-8'
          }){ |response, request, result, &block|
          }
        end
      end

ここまでで、Facebook botの型がだいたい出来ます。

botをリッチにしていくのは、また別の話になります。

続きますー◎