Foursquare live updates with the Push API using rails

Recently, I have been working extensively with the Foursquare API, also contributing to the open source foursquare2 gem.

While working on these features, I got a sneak peak preview to the new push API through Foursquare. Until I got that, I needed to pull checkins for each user, which was a slow and unefficient process.

Facebook had this feature for a while that for every checkin a user has, the application (he authorized) get a push notification to a callback URL – this is highly effective and more streamlined process.
So, Foursquare added it and like I said, I was happy to get a sneak peak to it.

Since it has no documentation yet, adding it to the application was not as smooth as I am used to, so I thought I would post the code for it on my blog, so you will have it easier then me :-)

Foursquare posts the json for the checkin to your controller with no parameter, so you need to use the post body in order to read it.

Here’s the controller code:

class FsRealtimeController < ApplicationController
  protect_from_forgery :except => 'post'

  def post
    posted_json = request.body.read

    if posted_json.blank?
      render :nothing => true
      return
    end

    parsed_json = JSON.parse(posted_json.to_s)

   # Do whatever you want with the parsed json

    render :nothing => true
  end
end

The typical json will look something like this:

{
"checkin": {
"createdAt": 1298129668,
"id": "4d5fe304d7206ea8e90aeef1",
"shout": "#4sqhackathon",
"timeZone": "America/New_York",
"type": "checkin",
"venue": {
"categories": [
{
"icon": "http://foursquare.com/img/categories/building/default.png",
"id": "4bf58dd8d48988d125941735",
"name": "Tech Startup",
"parents": [
"Home / Work / Other",
"Corporate / Office"
],
"primary": true
}
],
"contact": {
"twitter": "gnrlassembly"
},
"id": "4c5c076c7735c9b6af0e8b72",
"location": {
"address": "902 Broadway, 4th Floor",
"city": "New York",
"crossStreet": "btw 20th and 21st",
"lat": 40.739197437761383,
"lng": -73.989760279655457,
"postalCode": "10010",
"state": "NY"
},
"name": "General Assembly",
"stats": {
"checkinsCount": 1357,
"usersCount": 557
},
"todos": {
"count": 0
},
"verified": false
}
},
"user": {
"firstName": "Neil",
"gender": "male",
"homeCity": "New York, NY",
"id": "2097",
"lastName": "Sanchala",
"photo": "http://playfoursquare.s3.amazonaws.com/userpix_thumbs/0QYGOJMDGLTJOOQG.jpg",
"relationship": "self"
}
}

You can find some more details here (json from the link).

SSL verification issue with the Foursquare2 gem [Solved]

I’ve been implementing a Foursquare API into a website using the foursqaure2 gem.

While working on development, everything went smooth, tests passed and it was really cool to work with. However, once I deployed staging and production I immediately encountered the well known SSL issues.

SSLv3 read server certificate B: certificate verify failed

The solution actually wasn’t that trivial, I monkeypatched the gem so you can pass an SSL hash and refer to the ca_file.

This has solved the problem.
Notice the @ssl param, this is the important thing here.

def initialize(options={})
      @client_id = options[:client_id]
      @client_secret = options[:client_secret]
      @oauth_token = options[:oauth_token]
      @ssl = options[:ssl].nil? ? Hash.new : options[:ssl]
    end

    # Sets up the connection to be used for all requests based on options passed during initialization.
    def connection
      params = {}
      params[:client_id] = @client_id if @client_id
      params[:client_secret] = @client_secret if @client_secret
      params[:oauth_token] = @oauth_token if @oauth_token
      @connection ||= Faraday::Connection.new(:url => api_url, :ssl => @ssl, :params => params, :headers => default_headers) do |builder|
        builder.adapter Faraday.default_adapter
        builder.use Faraday::Response::Mashify
        builder.use Faraday::Response::ParseJson
      end
    end

    def ssl
      @ssl
    end

This is how you pass the hash

    client = Foursquare2::Client.new(:oauth_token => self.fs_oauth_token, :ssl => { :verify => OpenSSL::SSL::VERIFY_PEER, :ca_file => "path_to_your_pem_file" })

If you are running on Amazon or any other cloud solution and you don’t know where your SSL certification is located, there’s a tip in this post on how you can find it.

Like a good Ruby on rails and open source developer, I issued a pull request to the original gem’s developer and this fix will be in the next version of the gem, you can find it here

If you are having issues with SSL, just pay attention to what version of the gem you are running and make sure you are running a version with this fix.