Real time Facebook notification from app engine

It’s hard  to find a good example for Facebook authentication on app engine using java.

I’ll try to do the following:

  1. Explain the general flow for achieving  Real time notification on app engine.
  2. Show some code snippets for implementing the above flow.

General Flow + Code

Step 1

Use the callback mechanism of Facebook to start the authentication process.
http://www.facebook.com/dialog/oauth?client_id=<client_id&gt; &display=touch&scope=offline_access,read_stream&redirect_uri=<callback_url>

I’m calling to this URL from a mobile app,therefore I use display=touch, in addition pay attention that I’m asking from the user to grant me offline access, I’m assuming that I’ll update the user long after the authentication token will expire.

Step 2

I’ve prepared a callback get method on my app engine. Facebook calls my callback url passing to it a code. The code means the user granted me permissions.

Map<String, String[]> parameters = req.getParameterMap();
if (parameters.containsKey("code")) {
...
facebookAuthCode = ... // Get 'code' value

Pay attention that the code is not the access token (which is the holly grail), the access token will allow us to act on behalf of the user.

You need to call another url with the code you extracted, the response will be the access token.

String facebookAuthUrl = String.format("https://graph.facebook.com/oauth/access_token?client_id=%s&redirect_uri=%s&client_secret=%s&code=%s",
							Constants.FACEBOOK_APP_CODE, reconstructedURL,
							Constants.FACEBOOK_APP_SECRET, facebookAuthCode);
URL localUrl = new URL(facebookAuthUrl);
URLConnection conn = localUrl.openConnection();
conn.setDoOutput(false);
BufferedReader rd = null;
try {
	// Get the response
	rd = new BufferedReader(
	new InputStreamReader(conn.getInputStream()));
...

The easiest way to build a valid callback url is to use the request object.

URL baseURL = new URL(req.getScheme(), req.getServerName(),req.getRequestURI());

Now we register for real time notification.

Step 3

We need to post our data to Facebook with the appropriate parameters. They should include:

  • object – To which object in the social graph we want to listen to.
  • fields – Special fields that make up the object.
  • callback_url – Call this URL with post. In our case it is baseURL we used above.
  • verify_token – A token that will be sent back during hub mode.
  • access_token – built from facebook_app_code|facebook_app_secret . You should get these two values from your Facebook account. Pay attention to ‘|’.
// Use String builder instead of just regular string.
String data = URLEncoder.encode("object", "UTF-8") + "="
				+ URLEncoder.encode("user", "UTF-8");
data += "&" + URLEncoder.encode("fields", "UTF-8") + "="
				+ URLEncoder.encode("home", "UTF-8");
// Send real time updates to this URL.
data += "&" + URLEncoder.encode("callback_url", "UTF-8") + "="
				+ URLEncoder.encode(reconstructedURL.toString(), "UTF-8");
// A token used to verify that it is actually me who is running the
// verification process.
data += "&" + URLEncoder.encode("verify_token", "UTF-8") + "="
				+ URLEncoder.encode(Constants.FACEBOOK_VERIFY_TOKEN, "UTF-8");
data += "&" + URLEncoder.encode("access_token", "UTF-8") + "="
				+ Constants.FACEBOOK_APP_CODE + "|"
				+ Constants.FACEBOOK_APP_SECRET;
// Subscribe by doing a post.
URL url = new URL(String.format(
				"https://graph.facebook.com/%s/subscriptions?access_token=%s",
				Constants.FACEBOOK_APP_CODE, accessToken));

HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());

wr.write(data);
wr.flush();
...
wr.close();</pre>

Almost done here the final stage is the hub mode.

Step 4

Facebook is using hub mode to do a final verification of the process. You will receive back a verification token that you sent during your registration process (step 3), you will have to make sure it is equal to what you sent and then response with a challenge string that Facebook sent.

String verifyToken = (String) parameters.get("hub.verify_token")[0];
if (verifyToken.equals(Constants.FACEBOOK_VERIFY_TOKEN)) {
	log.info("hub.mode test is valid");
	resp.setContentType("text/plain");
	resp.getWriter().print(req.getParameter("hub.challenge"));
}

That’s it you are done you are now registered.

Advertisements

4 Comments

Filed under Uncategorized

4 responses to “Real time Facebook notification from app engine

  1. marta

    Hi!
    Thanks for your tutorial!
    I need help 😦
    Have you used your localhost as url_callback?
    I mean, in my case i want to do it, giving as canvas url app facebook settings the same path put in my url_callback, but i get an error 403 HTTP.

    I think, facebook can not ‘see’ my url because i’m using localhost.
    Have you changed something in your proxy browser settings?

    Thank’s so much

    • Hi Marta,

      You are right, it’s because you are using localhost. Facebook doesn’t support it. Think about it, localhost is different on each machine therefore, facebook doesn’t know that it should call your machine.

      I never tried it, but you can use your ip address (the one given to you by your internet provider) as the call back url, something like http://132.54.32.10

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s