How to get the ID of Facebook Page loading application as a page tab

April 14, 2013    facebook facebook app dev facebook applications

Sometimes you might be required to build a Facebook Application which might go live on several different Facebook page tabs. Often as a subset of being installed in several locations you may find you want to make subtle tweaks to the Application itself. Many Facebook app developers will hard code some of the URLS which they use for redirection in their code base, this is not good practise and tends to lead to these such problems. With the following example you will be able to install the same Application across many different Facebook Pages with the ability to record and adapt the Facebook page currently loading the application by the page ID.

I've had to consider this problem at length for work this weekend and found that there was really not much decent documentation on it (least not anything particularly coherent). Needless to say I did still manage to find some documentation and with a bit of googling pieced together how to do this.

Facebooks documentation states the following:

When a user navigates to the Facebook Page, they will see your Page Tab added in the next available tab position. Broadly, a Page Tab is loaded in exactly the same way as a Canvas Page. When a user selects your Page Tab, you will received the signed_request parameter with one additional parameter, page. This parameter contains a JSON object with an id (the page id of the current page), admin (if the user is a admin of the page), and liked (if the user has liked the page). As with a Canvas Page, you will not receive all the user information accessible to your app in the signed_request until the user authorizes your app.

One way to achieve this using the Facebook SDK would be to grab the signedRequest using the Official PHP SDK. Here's an example:

// PATH TO FB-PHP-SDK
require '../../src/facebook.php';

$facebook = new Facebook(array(
  'appId'  => 'APP_ID',
  'secret' => 'APP_SECRET',
  'cookie' => true,
));
$signed_request = $facebook->getSignedRequest();
if( $page = $signed_request['page'] ) {
    echo $page['id'];
}

I also learned that Facebook via the signed_request method would make user_id, other basic information (such as age) a locale and a country so that you can serve age related or locale related content. Right on the money for me who needs to serve content in different languages using it :)

Or you could roll your own and grab it without the Facebook SDK like so:


if(!empty($_REQUEST["signed_request"])) {
    $app_secret = "APP_SECRET";
    $data = parse_signed_request($_REQUEST["signed_request"], $app_secret);

    if (isset($data["page"])) {
        echo $data["page"]["id"];
    } else {
        echo "Not in a page";
    }
}

function parse_signed_request($signed_request, $secret) {
    list($encoded_sig, $payload) = explode('.', $signed_request, 2); 

    // decode the data
    $sig = base64_url_decode($encoded_sig);
    $data = json_decode(base64_url_decode($payload), true);

    if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
        error_log('Unknown algorithm. Expected HMAC-SHA256');
        return null;
    }

    // check sig
    $expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
    if ($sig !== $expected_sig) {
        error_log('Bad Signed JSON signature!');
        return null;
    }

    return $data;
}

function base64_url_decode($input) {
    return base64_decode(strtr($input, '-_', '+/'));
}

Both of these methods will return the page ID of the Facebook Page loading your application. You could then save to session and store against the user when they authenticate or all manner of other quirky things and start tailoring your App for each page if needs be.


blog comments powered by Disqus