In this post we’re going to be leveraging Foursquare’s API to get venues near a given geo location and to connect to a user’s Foursquare account, so that we can pull in their realtime check-in feed.
This has been implemented on our live environment, so for a real live demo go to http://niteviva.com and sign in using your Foursquare account. Note that, for account verification and security reasons, you will be asked for your email address when you sign up. You will then be taken to the home page where your Foursquare check-in feed will be displayed on the top right-hand corner.
Foursquare’s API has various client libraries that we can use to start developing with the API. Here, foursquared has been chosen because Java is what we find easy to work with when using third-party APIs. You will need to be comfortable working with Java and Maven to complete the following steps, but even if Java isn’t your cup of tea, this post is still useful to those of you who are generally interested in getting started with Foursquare’s API. Case in point, some of what’s said in this post is based on a great blog post by Joe Siewert, which shows how to get started with Foursquare and PHP.
Step 1. Download and install the Foursquare client library
- Download it here or from foursquared
- Install the jar in your local Maven repository, e.g.:
- Include the following dependencies in your pom.xml:
<dependency> <groupId>com.joelapenna.foursquare</groupId> <artifactId>foursquare</artifactId> <version>2009111500</version> </dependency> <dependency> <groupId>xpp3</groupId> <artifactId>xpp3</artifactId> <version>1.1.4c</version> </dependency> <dependency> <groupId>oauth.signpost</groupId> <artifactId>signpost-core</artifactId> <version>1.1</version> </dependency> <dependency> <groupId>oauth.signpost</groupId> <artifactId>signpost-commonshttp4</artifactId> <version>1.1</version> </dependency>
mvn install:install-file -Dfile=~/Downloads/foursquarelib_2009111500.jar -DgeneratePom=true -DgroupId=com.joelapenna.foursquare -DartifactId=foursquare -Dversion=2009111500 -Dpackaging=jar
Step 2. Code!
Now you’re ready to start using the Foursquare API .. well, almost! First you need to write some code.
package myapp;
import java.util.ArrayList;
import java.util.List;
import com.joelapenna.foursquare.Foursquare;
import com.joelapenna.foursquare.FoursquareHttpApiV1;
import com.joelapenna.foursquare.Foursquare.Location;
import com.joelapenna.foursquare.types.Group;
import com.joelapenna.foursquare.types.Venue;
/**
* NoAuthFoursquareService uses Foursquare client to make non authenticated Foursquare calls.
*/
public class NoAuthFoursquareService {
/** The no auth foursquare. */
protected final Foursquare noAuthFoursquare;
/**
* Instantiates a new non authenticated foursquare service.
*/
public NoAuthFoursquareService() {
this.noAuthFoursquare = new Foursquare(new FoursquareHttpApiV1("api.foursquare.com", null, false));
noAuthFoursquare.setCredentials("", "");
}
/**
* Venues.
*
* @param latitude the latitude
* @param longitude the longitude
* @return the group
*/
public List<Venue> venues(String latitude, String longitude) throws Exception {
// Make Foursquare venues API call
Group<Group<Venue>> venues =
this.noAuthFoursquare.venues(new Location(latitude, longitude), "", 1, 10);
// Convert venues into list
List<Venue> venueList = new ArrayList<Venue>();
for(Group<Venue> venueGroup: venues) {
for(Venue venue: venueGroup) {
venueList.add(venue);
}
}
return venueList;
}
}
Step 3. Take it for a test spin
package myapp;
import static org.junit.Assert.assertEquals;
import java.util.List;
import org.junit.Test;
import com.joelapenna.foursquare.types.Venue;
/**
* Testing non authenticated Foursquare API calls
*/
public class NoAuthFoursquareTest {
/** The non authenticated foursquare service that's going to be tested. */
NoAuthFoursquareService noAuthFoursquareService = new NoAuthFoursquareService();
/**
* Test call to Foursquare venues API
*
* @throws Exception the exception
*/
@Test
public void venues() throws Exception {
List<Venue> venues = noAuthFoursquareService.venues("51.5517", "-0.158826");
assertEquals(10, venues.size());
for (Venue venue: venues) {
System.out.println(
venue.getName() + ", " + venue.getAddress() + ", " + venue.getCity()
+ " [lat:" + venue.getGeolat() + ", long:" + venue.getGeolong() + "]");
}
}
}
If all goes well, you should see some test output:
1st floor chocolate machine, Mediacom, Camden [lat:51.5517059, long:-0.1588255]
Camden rock, Camden, London [lat:51.5517059, long:-0.1588255]
Centro Cafe, Camden, London [lat:51.5517059, long:-0.1588255]
Muang thai, Camden, London [lat:51.5517059, long:-0.1588255]
Somerfield, Camden, London [lat:51.5517059, long:-0.1588255]
the ice wharf, Camden, London [lat:51.5517059, long:-0.1588255]
Palushi's barber, Southampton Road, Camden Town [lat:51.55153896107019, long:-0.15754222869873047]
Lord Weetch's Manor, 9a Parkhill Rd, Camden Town [lat:51.550125, long:-0.1585858]
The IDM, 1 Park Road, London [lat:51.5504938, long:-0.1601123]
The Lord Stanley, 51 camden park road, London [lat:51.5516975, long:-0.1605962]
Step 4. Realtime Geolocation Check-in Feeds
Here it get’s that little bit more tricky. We need the user to authorize our application so we can get access to their realtime check-ins. From now onwards, it helps to understand how OAuth works.
First, you need an application key and secret from Foursquare. Create a Foursquare test account and go to http://foursquare.com/oauth. Register a new consumer with the callback URL ‘http://localhost:8080/foursquare/oauth’, and then Foursquare will give you a unique consumer key and secret.
Now, some more code
package myapp;
import oauth.signpost.OAuthProvider;
import oauth.signpost.basic.DefaultOAuthProvider;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
import oauth.signpost.signature.SignatureMethod;
import java.util.List;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import com.joelapenna.foursquare.Foursquare;
import com.joelapenna.foursquare.FoursquareHttpApiV1;
import com.joelapenna.foursquare.http.AbstractHttpApi;
import com.joelapenna.foursquare.http.HttpApiWithOAuth;
import com.joelapenna.foursquare.parsers.CheckinParser;
import com.joelapenna.foursquare.parsers.GroupParser;
import com.joelapenna.foursquare.parsers.UserParser;
import com.joelapenna.foursquare.types.Checkin;
import com.joelapenna.foursquare.types.Group;
import com.joelapenna.foursquare.types.User;
/**
* FoursquareService uses Foursquare client to make authenticated Foursquare API calls.
*/
public class OAuthFoursquareService {
/** The Constant URL_API. */
private static final String URL_API = "http://api.foursquare.com/v1";
/** The Constant URL_API_USER. */
private static final String URL_API_USER = URL_API + "/user";
/** The Constant URL_API_HISTORY. */
private static final String URL_API_HISTORY = URL_API + "/history";
/** The http client. */
protected final DefaultHttpClient mHttpClient = AbstractHttpApi.createHttpClient();
/** The consumer key. */
protected final String consumerKey;
/** The consumer secret. */
protected final String consumerSecret;
/**
* Instantiates a new OAuth foursquare service.
*/
public OAuthFoursquareService(String consumerKey, String consumerSecret) {
this.consumerKey = consumerKey;
this.consumerSecret = consumerSecret;
}
/**
* New foursquare OAuth provider.
*
* @return the OAuth provider
*/
public OAuthProvider newOAuthProvider() {
OAuthProvider provider = new DefaultOAuthProvider(
new CommonsHttpOAuthConsumer(consumerKey, consumerSecret, SignatureMethod.HMAC_SHA1),
"http://foursquare.com/oauth/request_token",
"http://foursquare.com/oauth/access_token",
"http://foursquare.com/oauth/authorize");
return provider;
}
/**
* Gets the user.
*
* @param token the token
* @param secret the secret
* @return the user
*/
public User getUser(String token, String secret) throws Exception {
HttpApiWithOAuth mHttpApi = new HttpApiWithOAuth(mHttpClient, null);
mHttpApi.setOAuthConsumerCredentials(consumerKey, consumerSecret);
mHttpApi.setOAuthTokenWithSecret(token, secret);
HttpGet httpGet = mHttpApi.createHttpGet(URL_API_USER);
return (User) mHttpApi.doHttpRequest(httpGet, new UserParser());
}
/**
* Checkin History.
*
* @param token the token
* @param secret the secret
* @return the group
*/
@SuppressWarnings("unchecked")
public List<Checkin> history(String token, String secret) throws Exception {
HttpApiWithOAuth mHttpApi = new HttpApiWithOAuth(mHttpClient, null);
mHttpApi.setOAuthConsumerCredentials(consumerKey, consumerSecret);
mHttpApi.setOAuthTokenWithSecret(token, secret);
HttpGet httpGet = mHttpApi.createHttpGet(URL_API_HISTORY);
Group<Checkin> checkinGroup = (Group<Checkin>) mHttpApi.doHttpRequest(httpGet, new GroupParser(new CheckinParser()));
return checkinGroup.subList(0, checkinGroup.size());
}
/**
* New OAuth client.
*
* @param token the token
* @param secret the secret
* @return the foursquare
*/
protected Foursquare newOAuthClient(String token, String secret) {
Foursquare foursquareOAuthClient =
new Foursquare(new FoursquareHttpApiV1("api.foursquare.com", null, true));
foursquareOAuthClient.setOAuthConsumerCredentials(consumerKey, consumerSecret);
foursquareOAuthClient.setOAuthToken(token, secret);
return foursquareOAuthClient;
}
}
To start using the OAuthFoursquareService, you have to hook it up into the web layer. I’m not going to go in depth at this stage, but here’s a code example of how it can be done using a Spring MVC controller:
package myapp;
import oauth.signpost.OAuthProvider;
import com.joelapenna.foursquare.types.Checkin;
import com.joelapenna.foursquare.types.User;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;
/**
* FoursquareController handles oauth requests (authorize and oauth callback)
*/
@Controller
@RequestMapping("/foursquare")
public class FoursquareController {
/** The foursquare service. */
@Autowired
public OAuthFoursquareService foursquareService;
/** The Constant accessTokens that stores OAuth access tokens */
public static final Map<String, String[]> accessTokens = new ConcurrentHashMap<String, String[]>();
/**
* Authorize - redirects user to a foursquare authorization url
*
* @param returnUrl the return url
* @throws Exception the exception
*/
@RequestMapping(value = "/authorize", method = RequestMethod.GET)
public View authorize(HttpSession session) throws Exception {
// Get authorize url, save OAuthProvider into HTTP session (retrieved in oauth callback method)
OAuthProvider provider = foursquareService.newOAuthProvider();
String authorizeUrl = provider.retrieveRequestToken("http://localhost:8080/foursquare/oauth");
session.setAttribute("foursquare", provider);
return new RedirectView(authorizeUrl);
}
/**
* OAuth Callback.
*
* @param oauthToken the oauth token
* @throws Exception the exception
*/
@RequestMapping(value = "/oauth", method = RequestMethod.GET)
public View oauth(
HttpSession session, @RequestParam("oauth_token") String oauthToken) throws Exception {
// Get OAuthProvider from HTTP session (set in authorize method), and get access token and secret
OAuthProvider provider = (OAuthProvider) session.getAttribute("foursquare");
provider.retrieveAccessToken("http://localhost:8080/foursquare/oauth");
String token = provider.getConsumer().getToken();
String tokenSecret = provider.getConsumer().getTokenSecret();
// Get user info from foursquare API
User user = foursquareService.getUser(token, tokenSecret);
// NOTE: Put access token and secret in accessToken map, which is fine for this example but
// normally the access token and secret would be stored in a database!
accessTokens.put(user.getId(), new String[]{token, tokenSecret});
return RedirectView("http://localhost:8080/foursquare/checkins/" + user.getId());
}
/**
* Checkins.
*
* @param userId the user id
* @return the model and view
* @throws Exception the exception
*/
@RequestMapping(value = "/checkins/{id}", method = RequestMethod.GET)
public ModelAndView checkins(@PathVariable String id) throws Exception {
String[] accessToken = accessTokens.get(id);
if (null == accessToken)
throw new Exception("Foursquare user not yet authenticated [" + id + "]");
// Get user check-ins from foursquare API
List<Checkin> checkins = foursquareService.history(accessToken[0], accessToken[1]);
Map<String, List<Checkin>> model = new HashMap<String, List<Checkin>>();
model.put("checkins", checkins);
return new ModelAndView("checkins", model);
}
}
The above web flow works as follows:
- The user clicks on a HTML link that directs them to http://localhost:8080/foursquare/authorize
- The user is redirected to the Foursquare website, which asks the user to authorize our application so we can access their Foursquare realtime check-in feed
- The user is taken back to http://localhost:8080/foursquare/oauth, which accepts and stores the new access token for that user
- The user is finally redirected to http://localhost:8080/foursquare/checkins/{id}, which calls the Foursquare API to get the user’s realtime check-in feed
Hope this post has been useful in explaining how you can get started with Foursquare’s API.
If you have any questions or feedback, please leave a comment.
Don’t forget you can try out a real live demo at http://niteviva.com .. enjoy
Tags: Development, foursquare, NiteViva, tech
Do you know how of a widget for wordpress that allows you to see your latest check-ins for that venue in a scroll form displayed on your website?
You could maybe try this wordpress plugin – http://wordpress.org/extend/plugins/placewidget-f...