Code I/O

A topnotch WordPress.com site


3 Comments

SocialMedia : Facebook Real Time subscriptions …

There are couple of things required to work with Facebook realtime updates.  I had a tough time in understanding what they were trying to do, but then, after few reading and experimenting, it got easy; you can do it too … here are few steps that can be tried using a REST-Client plug-in (Chrome/IE/Firefox).

First: You need to ask Facebook for an access token.  Remember, this is NOT the same access token that you will use with Graph API.  However, one would have generated this using the OAuth get access token process.

https://graph.facebook.com/oauth/access_token?client_id=<CLIENT_ID>&client_secret=<CLIENT_SECRET>&type=client_cred

This will get you the access token in requests response.

access_token=<ACCESS_TOKEN_FROM_FACEBOOK>


You will use this access token in your requests to find out about your subscriptions, this is a http GET request

https://graph.facebook.com/<CLIENT_ID>/subscriptions?access_token=<OBTAINED_ACCESS_TOKEN>


This should generate a response such as this, which is a proof that your request was successfully generated.

{    "data": [] }

Once you find out that you’re able to make a contact, the next step is to ask Facebook to push interested objects to your REST server.  To do this, you need to make a request to Facebook with information about where Facebook must push.  This time, the same request will be sent as a POST with data fields filled up.

https://graph.facebook.com/<CLIENT_ID>/subscriptions?access_token=<OBTAINED_ACCESS_TOKEN>

The data fields that you must give to Facebook are as follows: [Mandatory]

object=user&fields=name,feed,friends&callback_url=http://<YOUR_PUBLIC_HOST>:<YOUR_PUBLIC_PORT>/facebook/realtime_callback&verify_token=SOME_RANDOM_TEXT

Here is a list of supported entities and its meaning

Entity                        Meaning
-----------------------------------------------------------------------------
object                        Objects that you're interested to subscribe
fields                        The fields which Facebook must send back when an update occurs
callback_url                  A publicly hosted service URL to which Facebook will push real-time updates
verify_token                  A random text that you'll send to Facebook, which will be returned back to you, this is to avoid spammers.

Here is the code for HTTP service which will handle notifications from Facebook.

enum Verb { GET, POST, PUT, DELETE };
final String verifiyToken = UUID.randomUUID().toString();
final String CALLBACK_CONTEXT = "/facebook/realtime_callback";
HttpServer server = null;
// create an instance of the lightweight HTTP server on port
try {
	server = HttpServer.create(new InetSocketAddress(PORT), 0);
} catch (IOException e) {
	System.out.println("IOException while launching HttpServer " + e.getMessage());
}
server.createContext(CALLBACK_CONTEXT, new HttpHandler() {

	public void handle(HttpExchange exchange) throws IOException {
		final String requestMethod = exchange.getRequestMethod();

		final String query = exchange.getRequestURI().getQuery();

		URLParams urlParams = new URLParams(query);

		OutputStream os = exchange.getResponseBody();
		Headers responseHeaders = exchange.getResponseHeaders();

		// List subscriptions
		if(requestMethod.compareToIgnoreCase(Verb.GET.name()) == 0){
			System.out.println("GET Request");

			String hubMode = urlParams.getParam("hub.mode");
			String hubVerifyToken= urlParams.getParam("hub.verify_token");

			if((hubMode.compareTo("subscribe")) == 0 && (hubVerifyToken.compareTo(verifiyToken) == 0)) {
				exchange.sendResponseHeaders(200, 0);
				responseHeaders.add("ContentType", "text/plan");

				String hubChallenge = urlParams.getParam("hub.challenge");

				if(hubChallenge != null) {
					os.write(hubChallenge.getBytes());
				}
			}
		}
		// Add/Modify subscription
		else if(requestMethod.compareToIgnoreCase(Verb.POST.name()) == 0){
			System.out.println("POST Request");

			// TODO: Read the stream
			InputStream is= exchange.getRequestBody();
			try {
				System.out.println("Response Received: " + streamToString(is));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		// Delete subscription
		else if(requestMethod.compareToIgnoreCase(Verb.DELETE.name()) == 0){
			System.out.println("DELETE Request");
		}

		os.close();
	}
});
// creates a default executor
server.setExecutor(null);
// start the server
System.out.println("Embeded Facebook Realtime callback services started!!");
server.start();

Here is the code which will convert a stream to string

public static String streamToString(InputStream is) {
	try
	{
		final char[] buffer = new char[4096];
		StringBuilder out = new StringBuilder();
		Reader in = new InputStreamReader(is, "UTF-8");
		int read;
		do
		{
			read = in.read(buffer, 0, buffer.length);
			if (read > 0)
			{
				out.append(buffer, 0, read);
			}
		} while (read >= 0);

		in.close();

		return out.toString();
	} catch (IOException ioe)
	{
		throw new IllegalStateException("Error while reading input stream", ioe);
	}
}

For more details about what Facebook will send you and how you must handle, refer to real time API docs.

https://developers.facebook.com/docs/reference/api/realtime/

Advertisements