6. Working with Service APIs

6.1 Introduction

After a user has granted your application access to their service provider profile, you'll be able to interact with that service provider to update or retrieve the user's data. Your application may, for example, post a Tweet on behalf of a user or review a user's list of contacts to see if any of them have also created connections to your application.

Each service provider exposes their data and functionality through an API. Spring Social provides Java-based access to those APIs via provider-specific templates, each implementing a provider operations interface.

Spring Social comes with six provider API templates/operations for the following service providers:

  • Twitter

  • Facebook

  • LinkedIn

  • TripIt

  • GitHub

  • Gowalla

6.2 Twitter

Twitter's social offering is rather simple: Enable users to post whatever they're thinking, 140 characters at a time.

Spring Social's TwitterTemplate (which implements TwitterOperations) offers several options for applications to integrate with Twitter.

Creating an instance of TwitterTemplate involves invoking its constructor, passing in the application's OAuth credentials and an access token/secret pair authorizing the application to act on a user's behalf. For example:

String apiKey = "..."; // The application's API/Consumer key
String apiSecret = "..."; // The application's API/Consumer secret
String accessToken = "..."; // The access token granted after OAuth authorization
String accessTokenSecret = "..."; // The access token secret granted after OAuth authorization
TwitterOperations twitter = new TwitterTemplate(apiKey, apiSecret, accessToken, accessTokenSecret);
		

In addition, TwitterTemplate has a default constructor that creates an instance without any OAuth credentials:

TwitterOperations twitter = new TwitterTemplate();
		

When constructed with the default constructor, TwitterTemplate will allow a few simple operations that do not require authorization, such as searching. Other operations, such as tweeting will fail with an AccountNotConnectedException being thrown.

If you are using Spring Social's service provider framework, as described in Chapter 2, Service Provider 'Connect' Framework, you can get an instance of TwitterOperations by calling the getServiceApi() method on one of the connections given by TwitterServiceProvider's getConnections() method. For instance:

TwitterOperations twitter = twitterProvider.getConnections(accountId).get(0).getServiceApi();
		

Here, TwitterServiceProvider is being asked for a TwitterOperations that was created using connection details established previously via the service provider's connect() method or through ConnectController.

Once you have TwitterOperations, you can perform a variety of operations against Twitter.

6.2.1 Retrieving a user's Twitter profile data

To get a user's Twitter profile, call the getUserProfile():

TwitterProfile profile = twitter.getUserProfile();
			

This returns a TwitterProfile object containing profile data for the authenticated user. This profile information includes the user's Twitter screen name, their name, location, description, and the date that they created their Twitter account. Also included is a URL to their profile image.

If you want to retrieve the user profile for a specific user other than the authenticated user, you can so do by passing the user's screen name as a parameter to getUserProfile():

TwitterProfile profile = twitter.getUserProfile("habuma");
			

If all you need is the screen name for the authenticating user, then call getProfileId():

String profileId = twitter.getProfileId();
			

6.2.2 Tweeting

To post a message to Twitter using TwitterTemplate the simplest thing to do is to pass the message to the updateStatus() method:

twitter.updateStatus("Spring Social is awesome!")
			

Optionally, you may also include metadata about the tweet, such as the location (latitude and longitude) you are tweeting from. For that, pass in a StatusDetails object, setting the location property:

StatusDetails statusDetails = new StatusDetails().setLocation(51.502f, -0.126f);
twitter.updateStatus("I'm tweeting from London!", statusDetails)
			

To have Twitter display the location in a map (on the Twitter web site) then you should also set the displayCoordinates property to true:

StatusDetails statusDetails = new StatusDetails().setLocation(51.502f, -0.126f).setDisplayCoordinates(true);
twitter.updateStatus("I'm tweeting from London!", statusDetails)
			

If you'd like to retweet another tweet (perhaps one found while searching or reading the Twitter timeline), call the retweet() method, passing in the ID of the tweet to be retweeted:

long tweetId = tweet.getId();
twitter.retweet(tweetId);
			

Note that Twitter disallows repeated tweets. Attempting to tweet or retweet the same message multiple times will result in a DuplicateTweetException being thrown.

6.2.3 Reading Twitter timelines

From a Twitter user's perspective, Twitter organizes tweets into four different timelines:

  • User - Includes tweets posted by the user.

  • Friends - Includes tweets from the user's timeline and the timeline of anyone that they follow, with the exception of any retweets.

  • Home - Includes tweets from the user's timeline and the timeline of anyone that they follow.

  • Public - Includes tweets from all Twitter users.

To be clear, the only difference between the home timeline and the friends timeline is that the friends timeline excludes retweets.

TwitterTemplate also supports reading of tweets from one of the available Twitter timelines. To retrieve the 20 most recent tweets from the public timeline, use the getPublicTimeline method:

List<Tweet> tweets = twitter.getPublicTimeline();
			

getHomeTimeline() retrieves the 20 most recent tweets from the user's home timeline:

List<Tweet> tweets = twitter.getHomeTimeline();
			

Similarly, getFriendsTimeline() retrieves the 20 most recent tweets from the user's friends timeline:

List<Tweet> tweets = twitter.getFriendsTimeline();
			

To get tweets from the authenticating user's own timeline, call the getUserTimeline() method:

List<Tweet> tweets = twitter.getUserTimeline();
			

If you'd like to retrieve the 20 most recent tweets from a specific user's timeline (not necessarily the authenticating user's timeline), pass the user's screen name in as a parameter to getUserTimeline():

List<Tweet> tweets = twitter.getUserTimeline("rclarkson");
			

In addition to the four Twitter timelines, you may also want to get a list of tweets mentioning the user. The getMentions() method returns the 20 most recent tweets that mention the authenticating user:

List<Tweet> tweets = twitter.getMentions();
			

6.2.4 Searching Twitter

TwitterTemplate enables you to search the public timeline for tweets containing some text through its search() method.

For example, to search for tweets containing "#spring":

SearchResults results = twitter.search("#spring");
			

The search() method will return a SearchResults object that includes a list of 50 most recent matching tweets as well as some metadata concerning the result set. The metadata includes the maximum tweet ID in the search results list as well as the ID of a tweet that precedes the resulting tweets. The sinceId and maxId properties effectively define the boundaries of the result set. Additionally, there's a boolean lastPage property that, if true, indicates that this result set is the page of results.

To gain better control over the paging of results, you may choose to pass in the page and results per page to search():

SearchResults results = twitter.search("#spring", 2, 10);
			

Here, we're asking for the 2nd page of results where the pages have 10 tweets per page.

Finally, if you'd like to confine the bounds of the search results to fit between two tweet IDs, you may pass in the since and maximum tweet ID values to search():

SearchResults results = twitter.search("#spring", 2, 10, 145962, 210112);
			

This ensures that the result set will not contain any tweets posted before the tweet whose ID is 146962 nor any tweets posted after the tweet whose ID is 210112.

6.2.5 Sending and receiving direct messages

In addition to posting tweets to the public timelines, Twitter also supports sending of private messages directly to a given user. TwitterTemplate's sendDirectMessage() method can be used to send a direct message to another user:

twitter.sendDirectMessage("kdonald", "You going to the Dolphins game?")
			

TwitterTemplate can also be used to read direct messages received by the authenticating user through its getDirectMessagesReceived() method:

List<DirectMessage> twitter.getDirectMessagesReceived();
			

getDirectMessagesReceived() will return the 20 most recently received direct messages.

6.3 Facebook

Spring Social's FacebookOperations and its implementation, FacebookTemplate provide the operations needed to interact with Facebook on behalf of a user. Creating an instance of FacebookTemplate is as simple as constructing it by passing in an authorized access token to the constructor:

String accessToken = "f8FX29g..."; // access token received from Facebook after OAuth authorization
FacebookOperations facebook = new FacebookTemplate(accessToken);
      

Or, if you are using the service provider framework described in Chapter 2, Service Provider 'Connect' Framework, you can get an instance of FacebookTemplate by calling the getServiceApi() method on one of the connections given by FacebookServiceProvider's getConnections() method:

FacebookOperations facebook = facebookProvider.getConnections(accountId).get(0).getServiceApi();
		

Here, FacebookServiceProvider is being asked to give back a FacebookOperations created using the connection details for the given account ID. The connection should have been created beforehand via the service provider's connect() method or using ConnectController.

With a FacebookOperations in hand, there are several ways you can use it to interact with Facebook on behalf of the user. These will be covered in the following sections.

6.3.1 Retrieving a user's profile data

You can retrieve a user's Facebook profile data using FacebookOperations' getUserProfile() method:

FacebookProfile profile = facebook.getUserProfile();
			

The FacebookProfile object will contain basic profile information about the authenticating user, including their first and last name, their email address, and their Facebook ID.

If all you need is the user's Facebook ID, you can call getProfileId() instead:

String profileId = facebook.getProfileId();
			

Or if you want the user's Facebook URL, you can call getProfileUrl():

String profileUrl = facebook.getProfileUrl();
			

6.3.2 Getting a user's Facebook friends

An essential feature of Facebook and other social networks is creating a network of friends or contacts. You can access the user's list of Facebook friends by calling the getFriendIds() method:

List<String> friendIds = facebook.getFriendIds();
			

This returns a list of Facebook IDs belonging to the current user's list of friends. This is just a list of String IDs, so to retrieve an individual user's profile data, you can turn around and call the getUserProfile(), passing in one of those IDs to retrieve the profile data for an individual user:

FacebookProfile firstFriend = facebook.getUserProfile(friendIds.get(0));
			

6.3.3 Posting to a user's wall

To post a message to the user's Facebook wall, call the updateStatus() method, passing in the message to be posted:

facebook.updateStatus("I'm trying out Spring Social!");
			

If you'd like to attach a link to the status message, you can do so by passing in a FacebookLink object along with the message:

FacebookLink link = new FacebookLink("http://www.springsource.org/spring-social", 
        "Spring Social", 
        "The Spring Social Project", 
        "Spring Social is an extension to Spring to enable applications to connect with service providers.");
facebook.updateStatus("I'm trying out Spring Social!", link);
			

When constructing the FacebookLink object, the first parameter is the link's URL, the second parameter is the name of the link, the third parameter is a caption, and the fourth is a description of the link.

6.3.4 Publishing to Facebook

Facebook's Graph API allows authenticated users to publish data to several of its object types. FacebookOperations enables arbitrary publication via the Graph API with its publish() method.

For example, in the previous section you saw how to post a message to the user's Facebook wall using updateStatus(). Alternatively you could have accomplished the same thing using publish() like this:

MultiValueMap<String, String> data = new LinkedMultiValueMap<String, String>();
data.set("message", message);
publish("me", "feed", data);
			

The first argument to the publish() method is the object to publish to--in this case "me" indicates the authenticated user. The second argument is the connection associated with the object--"feed" indicates that it is the user's Facebook wall. Finally, the third argument is a MultiValueMap containing data to be published. In this case, it only contains a "message" to be posted to the user's wall.

You can read more about what graph API objects and connections Facebook supports for publishing at http://developers.facebook.com/docs/api#editing

6.4 LinkedIn

LinkedIn is a social networking site geared toward professionals. It enables its users to maintain and correspond with a network of contacts they have are professionally linked to.

Spring Social offers integration with LinkedIn via LinkedInOperations and its implementation, LinkedInTemplate.

To create an instance of LinkedInTemplate, you may pass in your application's OAuth 1 credentials, along with an access token/secret pair to the constructor:

String apiKey = "..."; // The application's API/Consumer key
String apiSecret = "..."; // The application's API/Consumer secret
String accessToken = "..."; // The access token granted after OAuth authorization
String accessTokenSecret = "..."; // The access token secret granted after OAuth authorization
LinkedInOperations linkedin = new LinkedInTemplate(apiKey, apiSecret, accessToken, accessTokenSecret);
		

If you're using the service provider framework described in Chapter 2, Service Provider 'Connect' Framework, you can get an instance of LinkedInTemplate by calling the getServiceApi() method on one of the connections given by LinkedInServiceProvider's getConnections() method. For example:

LinkedInOperations linkedin = linkedinProvider.getConnections(accountId).get(0).getServiceApi();
		

In this case, the getServiceOperations() is asked to return a LinkedInOperations instance created using connection details established using the service provider's connect() method or via ConnectController.

Once you have a LinkedInOperations you can use it to interact with LinkedIn on behalf of the user who the access token was granted for.

6.4.1 Retrieving a user's LinkedIn profile data

To retrieve the authenticated user's profile data, call the getUserProfile() method:

LinkedInProfile profile = linkedin.getUserProfile();
			

The data returned in the LinkedInProfile includes the user's LinkedIn ID, first and last names, their "headline", the industry they're in, and URLs for the public and standard profile pages.

If it's only the user's LinkedIn ID you need, then you can get that by calling the getProfileId() method:

String profileId = linkedin.getProfileId();
			

Or if you only need a URL for the user's public profile page, call getProfileUrl():

String profileUrl = linkedin.getProfileUrl();
			

6.4.2 Getting a user's LinkedIn connections

To retrieve a list of LinkedIn users to whom the user is connected, call the getConnections() method:

List<LinkedInProfile> connections = linkedin.getConnections();
			

This will return a list of LinkedInProfile objects for the user's 1st-degree network (those LinkedIn users to whom the user is directly linked--not their extended network).

6.5 TripIt

TripIt is a social network that links together travelers. By connecting with other travelers, you can keep in touch with contacts when your travel plans coincide. Also, aside from its social aspects, TripIt is a rather useful service for managing one's travel information.

Using Spring Social's TripItOperations and its implementation, TripItTemplate, you can develop applications that integrate a user's travel information and network.

To create an instance of TripItTemplate, pass in your application's OAuth 1 credentials along with a user's access token/secret pair to the constructor:

String apiKey = "..."; // The application's API/Consumer key
String apiSecret = "..."; // The application's API/Consumer secret
String accessToken = "..."; // The access token granted after OAuth authorization
String accessTokenSecret = "..."; // The access token secret granted after OAuth authorization
TripItOperations tripit = new TripItTemplate(apiKey, apiSecret, accessToken, accessTokenSecret);
		

If you're using Spring Social's service provider framework (as described in Chapter 2, Service Provider 'Connect' Framework), you can get a TripItOperations by calling the getServiceApi() method on one of the connections given by TripItServiceProvider's getConnections() method:

TripItOperations tripit = tripitProvider.getConnections(accountId).get(0).getServiceApi();
		

In this case, TripItServiceProvider is being asked to give a TripItOperations constructed using connection data established beforehand using the service provider's connect() method or via ConnectController.

In either event, once you have a TripItOperations, you can use it to retrieve a user's profile and travel data from TripIt.

6.5.1 Retrieving a user's TripIt profile data

TripItOperations' getUserProfile() method is useful for retrieving the authenticated user's TripIt profile data. For example:

TripItProfile userProfile = tripit.getUserProfile();
			

getUserProfile() returns a TripItProfile object that carries details about the user from TripIt. This includes the user's screen name, their display name, their home city, and their company.

If all you need is the user's TripIt screen name, you can get that by calling getProfileId():

String profileId = tripit.getProfileId();
			

Or if you only need a URL to the user's TripIt profile page, then call getProfileUrl():

String profileUrl = tripit.getProfileUrl();
			

6.5.2 Getting a user's upcoming trips

If the user has any upcoming trips planned, your application can access the trip information by calling getUpcomingTrips():

List<Trip> trips = tripit.getUpcomingTrips();
			

This returns a list of Trip objects containing details about each trip, such as the start and end dates for the trip, the primary location, and the trip's display name.

6.6 GitHub

Although many developers think of GitHub as Git-based source code hosting, the tagline in GitHub's logo clearly states that GitHub is about "social coding". GitHub is a social network that links developers together and with the projects they follow and/or contribute to.

Spring Social's GitHubOperations and its implementation, GitHubTemplate, offer integration with GitHub's social platform.

To obtain an instance of GitHubTemplate, you can instantiate it by passing an authorized access token to its constructor:

String accessToken = "f8FX29g..."; // access token received from GitHub after OAuth authorization
GitHubOperations github = new GitHubTemplate(accessToken);
		

If you are using the service provider framework described in Chapter 2, Service Provider 'Connect' Framework, you can get an instance of GitHubTemplate by calling the getServiceApi() method on one of the connections given by GitHubServiceProvider's getConnections() method:

GitHubOperations github = githubProvider.getConnections(accountId).get(0).getServiceApi();
		

Here, GitHubServiceProvider is being asked for a GitHubOperations that was created using the connection details for the given account ID. The connection should have been created beforehand via the service provider's connect() method or using ConnectController.

With a GitHubOperations in hand, there are a handful of operations it provides to interact with GitHub on behalf of the user. These will be covered in the following sections.

6.6.1 Retrieving a GitHub user's profile

To get the currently authenticated user's GitHub profile data, call GitHubOperations's getUserProfile() method:

GitHubUserProfile profile = github.getUserProfile();
			

The GitHubUserProfile returned from getUserProfile() includes several useful pieces of information about the user, including their...

  • Name

  • Username (ie, login name)

  • Company

  • Email address

  • Location

  • Blog URL

  • Date they joined GitHub

If all you need is the user's GitHub username, you can get that by calling the getProfileId() method:

String username = github.getProfileId();
			

And if you need a URL to the user's GitHub profile page, you can use the getProfileUrl() method:

String profileUrl = github.getProfileUrl();
			

6.7 Gowalla

Gowalla is a location-based social network where users may check in to various locations they visit and earn pins and stamps for having checked in a locations that achieve some goal (for example, a "Lucha Libre" pin may be earned by having checked into 10 different Mexican food restaurants).

Spring Social supports interaction with Gowalla through the GowallaOperations interface and its implementation, GowallaTemplate.

To obtain an instance of GowallaTemplate, you can instantiate it by passing an authorized access token to its constructor:

String accessToken = "f8FX29g..."; // access token received from Gowalla after OAuth authorization
GowallaOperations gowalla = new GowallaTemplate(accessToken);
		

If you are using the service provider framework described in Chapter 2, Service Provider 'Connect' Framework, you can get an instance of GowallaTemplate by calling the getServiceApi() method on one of the connections given by GowallaServiceProvider's getConnections() method:

GowallaOperations gowalla = gowallaProvider.getConnections(accountId).get(0).getServiceApi();
		

Here, GowallaServiceProvider is being asked for a GowallaOperations that was created using the connection details for the given account ID. The connection should have been created beforehand via the service provider's connect() method or using ConnectController.

With a GowallaOperations in hand, there are a handful of operations it provides to interact with Gowalla on behalf of the user. These will be covered in the following sections.

6.7.1 Retrieving a user's profile data

You can retrieve a user's Gowalla profile using the getUserProfile() method:

GowallaProfile profile = gowalla.getUserProfile();
			

This will return the Gowalla profile data for the authenticated user. If you want to retrieve profile data for another user, you can pass the user's profile ID into getUserProfile():

GowallaProfile profile = gowalla.getUserProfile("habuma");
			

The GowallaProfile object contains basic information about the Gowalla user such as their first and last names, their hometown, and the number of pins and stamps that they have earned.

If all you want is the authenticated user's profile ID, you can get that by calling the getProfileId():

String profileId = gowalla.getProfileId();
			

Or if you want the URL to the user's profile page at Gowalla, use the getProfileUrl() method:

String profileUrl = gowalla.getProfileUrl();
			

6.7.2 Getting a user's checkins

GowallaOperations also allows you to learn about the user's favorite checkin spots. The getTopCheckins() method will provide a list of the top 10 places that the user has visited:

List<Checkin> topCheckins = gowalla.getTopCheckins();
			

Each member of the returns list is a Checkin object that includes the name of the location as well as the number of times that the user has checked in at that location.