Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No POST from facebook using real-time updates in Rails, Heroku and Koala

This question is an expanded version of Facebook Real-time updated does not call our servers, that seems to be dead. Also, Realtime updates internal server error on Heroku using Koala is not helpful because I'm subscribing from the heroku console as pjaspers suggested.

I have an app (ruby 1.9.2p290 and Rails 3.1.3) that connects to facebook to get data from the current user. Everything is working ok with the koala gem (v1.2.1), but I'm polling the fb servers every time the users logs in. I would like to use facebook real-time updates, and I have read the following:

  • Koala manual on fb realtime updates: https://github.com/arsduo/koala/wiki/Realtime-Updates
  • Facebook page on realtime: https://developers.facebook.com/docs/reference/api/realtime/

I have set up the system in test mode and deployed to heroku successfully. I can subscribe to the user object and I get the GET request to my server, but no POST with updated information is ever received from facebook. If I issue a POST to my server manually everything works.

More information: routes.rb

  get '/realtime' => 'realtime#verify'
  post '/realtime' => 'realtime#change'

generating

      realtime GET  /realtime(.:format) {:controller=>"realtime", :action=>"verify"}
               POST /realtime(.:format) {:controller=>"realtime", :action=>"change"}

The controller (mock version, only to test if it's working):

class RealtimeController < ApplicationController
  def verify
    render :text => params["hub.challenge"]
  end

  def change
    puts params.inspect
    render :nothing => true
  end
end

The subscription from the heroku console:

irb(main):004:0> @updates = Koala::Facebook::RealtimeUpdates.new(:app_id => ENV['FACEBOOK_APP_ID'], :secret => ENV['FACEBOOK_APP_SECRET'])
=> #<Koala::Facebook::RealtimeUpdates:0x00000004f5bca8 @app_id="XXXXXXX", @app_access_token="XXXXXXX", @secret="XXXXXXX", @graph_api=#<Koala::Facebook::API:0x00000004a8d7a8 @access_token="XXXXXXX">>

irb(main):005:0> @updates.list_subscriptions
=> [{"object"=>"user", "callback_url"=>"http://blah-blah-0000.herokuapp.com/realtime", "fields"=>["education", "email", "friends", "name", "website", "work"], "active"=>true}]

I don't know what to do next...

  • Maybe I am not triggering the correct changing events?
  • How do I see the list of users of my app? (right now it's a test app and the only user would be me)
  • Anyone with this kind of issue?
  • Is something wrong in the code?
  • Is facebook down? Is it the end of Internet?

Thank you for the help :)

like image 782
fuzzyalej Avatar asked Dec 02 '11 12:12

fuzzyalej


2 Answers

You need to respond to the GET request with a challenge response. I have the same route for both POST and GET requests and use the following code:

route:

match "facebook/subscription", :controller => :facebook, :action => :subscription, :as => 'facebook_subscription', :via => [:get,:post]

controller:

  def realtime_request?(request)
    ((request.method == "GET" && params['hub.mode'].present?) || 
       (request.method == "POST" && request.headers['X-Hub-Signature'].present?))
  end

  def subscription
    if(realtime_request?(request))
      case request.method
      when "GET"
        challenge = Koala::Facebook::RealtimeUpdates.meet_challenge(params,'SOME_TOKEN_HERE')
        if(challenge)
          render :text => challenge
        else
          render :text => 'Failed to authorize facebook challenge request'
        end
      when "POST"
        case params['object']
        # Do logic here...
        render :text => 'Thanks for the update.'
      end
    end
  end

That should get you going with things... Note that to make a subscription I am using this:

@access_token ||= Koala::Facebook::OAuth.new(FACEBOOK_API_KEY,FACEBOOK_API_SECRET).get_app_access_token
@realtime = Koala::Facebook::RealtimeUpdates.new(:app_id => FACEBOOK_API_KEY, :app_access_token => @access_token)
@realtime.subscribe('user', 'first_name,uid,etc...', facebook_subscription_url,'SOME_TOKEN_HERE')

I think the key is that you properly respond to the GET request from Facebook. They use this to verify that they are contacting the correct server prior to sending confidential info about their users.

Also -- its been a while since I've looked at this, but if I remember correctly, I seem to recall having issues with anything besides default protocol port specifications within the callback URL. Ex: http://www.something.com:8080/subscription did not work -- it had to be http://www.something.com/subscription

like image 113
ejlevin1 Avatar answered Oct 20 '22 21:10

ejlevin1


Not sure if this might be the case with you, but make sure that you have permissions to access the object -user, permissions, page- properties (location, email, etc.)

In my case, I was trying to get notifications for changes on the location property without my app requiring the user_location permission. For the user object, look at the Fields section in this page https://developers.facebook.com/docs/reference/api/user/

like image 25
Ytsejammer Avatar answered Oct 20 '22 20:10

Ytsejammer