Wednesday, August 12, 2015

Using Facebook's Graph API to Count Shares

Have you shared today's comic yet? Getting it shared at least 100 times on Facebook is the only way to unlock the action in the last frame. Well, it also has to be Wednesday. So share it 100 times today or wait until next week to try again.
Bombs don't look like this in real life.
This depiction is illogical.

The joke is that the frogs have discovered a logic bomb in a computer, and logic bombs only go off when their criteria are met. The criteria of this particular one include Facebook shares and the day of the week. Really it's designed to get me lots of attention on social media, but there is a joke in it.

Now to the good part...how does it work? The day-of-the-week part is easy, but checking the number of Facebook shares was slightly more involved. I used the Facebook Graph API.

There is a ton of stuff you can do with it, but for now I'm keeping it simple. I wanted to be able to check how many shares a given URL has. And you ask yourself, "Why doesn't he just look at that little number down below every comic?" Well, I'll tell you. That's a Facebook widget that functions by embedding an iframe in the page. I can't really check what it's doing from my own code. I had to write some server-side code to interface directly with Facebook.

Since share information is public, you can access it just by hitting a Facebook URI with any valid access token.

https://graph.facebook.com/v2.4/?access_token=<your-token>&id=<object-id>

The object id is just the URL that you want to check shares on. For me, it's something like http://amphibian.com/205. The tricky part is getting an access token. The easiest way to do it is to create a Facebook App and use the permanent access token associated with it. Sign up as a Facebook developer, and then create a new web app. After you have a web app set up, go to the Tools & Support menu and select Access Token Tool. You should then see a pair of tokens for your app, a User Token and an App Token. The App Token is the one you want because it never expires.

DO NOT share these tokens with anyone, or put them in client-side code! DO NOT! It will give anyone permission to perform actions as your application. I put the App Token in a server-side config file that is NOT committed to source control (at least not in a public repo).

Once you have both an access token and an object id (of something that's been shared at least once), hit the URL and you should get a JSON response.

Something like this:

{
  "og_object": {
    "id": "1128024717211703",
    "description": "Amphibian.com webcomic for Monday, 10 August 2015",
    "title": "Crowdfunding",
    "type": "website",
    "updated_time": "2015-08-10T08:18:03+0000",
    "url": "http://amphibian.com/205"
  },
  "share": {
    "comment_count": 0,
    "share_count": 12
  },
  "id": "http://amphibian.com/205"
}

I just parse that response and get the number of shares. I am doing this from a Node application, and just like when I used the Imgflip API to make memes, I use the convenient request module:

app.get("/shares/:id", function(req, res, next) {

    var comic = req.params.id;
    var token = "your-token-here";

    request({
        uri : "https://graph.facebook.com/v2.4/",
        qs : {
            access_token : token,
            id : "http://amphibian.com/" + comic
        }
    }, function(error, response, body) {

        if (!error && response.statusCode == 200) {

            var data = JSON.parse(body);

            res.setHeader("Content-Type", "application/json");
            res.send({
                id : data.id,
                shares : data.share.share_count
            });

        } else {
            next(error);
        }

    });

});

Again, I must stress that this code has to be done on the server side, since you don't want to give clients access to your App Token. When the client JavaScript has to check if it's ok to set off the cartoon bomb, I access a URL on my server that essentially proxies the request to Facebook. The code example above sets up a route /shares/:id that will give the share data for any comic to a client without exposing my App Token to the world.

Not too difficult. I just hope my plan is successful and the comic gets lots of shares. Trust me, it's worth it. Go on, check it out. It's also got a Zero Wing reference in there (which you can see before it's shared).

Amphibian.com comic for 12 August 2015