Yesterday we announced significant improvements to Apps on Facebook to drive distribution and engagement to high quality games and apps. As a follow up to these new features, this post outlines how to get started with publishing scores and achievements in your app.
The Graph API for achievements and scores enable you to publish stories for user’s achievements, passing friends’ scores, or leaderboard movement to make game play more competitive, social and exciting. These stories can only be published by apps categorized as ‘Games’ and are only shown to users when playing a game. We intend to broaden the types of apps that can use these new APIs in the near future.
publish_actions
permissionIn order to start publishing scores and achievements, a user needs to grant your app the publish_actions permission. The example below shows how to ask for the publish_actions permission:
https://www.facebook.com/dialog/oauth? client_id=YOUR_APP_ID& redirect_uri=YOUR_CANVAS_PAGE& scope=publish_actions
The following PHP example demonstrates how to access the signed_request
parameter, app access token and prompt the user to authorize your app the publish_actions
permission:
<?php $app_id = 'YOUR_APP_ID'; $app_secret = 'YOUR_APP_SECRET'; $canvas_page_url = 'YOUR_CANVAS_PAGE_URL'; // Authenticate the user session_start(); if(isset($_REQUEST["code"])) { $code = $_REQUEST["code"]; } if(empty($code) && !isset($_REQUEST['error'])) { $_SESSION['state'] = md5(uniqid(rand(), TRUE)); //CSRF protection $dialog_url = 'https://www.facebook.com/dialog/oauth?' . 'client_id=' . $app_id . '&redirect_uri=' . urlencode($canvas_page_url) . '&state=' . $_SESSION['state'] . '&scope=publish_actions'; print('<script> top.location.href=\'' . $dialog_url . '\'</script>'); exit; } else if(isset($_REQUEST['error'])) { // The user did not authorize the app print($_REQUEST['error_description']); exit; }; // Get the User ID $signed_request = parse_signed_request($_POST['signed_request'], $app_secret); $uid = $signed_request['user_id']; echo 'Welcome User: ' . $uid; // Get an App Access Token $token_url = 'https://graph.facebook.com/oauth/access_token?' . 'client_id=' . $app_id . '&client_secret=' . $app_secret . '&grant_type=client_credentials'; $token_response = file_get_contents($token_url); $params = null; parse_str($token_response, $params); $app_access_token = $params['access_token']; 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, '-_', '+/')); } ?>
You can publish stories about a user’s score by issuing an HTTP POST
to /USER_ID/scores
and specifying a user’s score in the score parameter. An app access token (shown in the example above) is required to make this API call.
https://graph.facebook.com/USER_ID/scores? score=USER_SCORE&access_token=APP_ACCESS_TOKEN
Scores show up in the app ticker in various story types that help drive re-engagement back to your app:
You can define a set of achievements for your app using the game.achievement
Open Graph type.
Achievements get displayed in the app ticker as follows:
Start by defining achievements for your app. When a user clicks on an achievement in the app ticker, they will be sent to the Achievement URL you registered. The recommended user experience is that the landing page explains what the achievement is.
Below is a simple HTML code snippet that you can use to set up your achievement:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:og="http://ogp.me/ns#"> <head> <title>ACHIEVEMENT_TITLE <meta property="og:type" content="game.achievement"/> <meta property="og:url" content="URL_FOR_THIS_PAGE"/> <meta property="og:title" content="ACHIEVEMENT_TITLE"/> <meta property="og:description" content="ACHIEVEMENT_DESCRIPTON"/> <meta property="og:image" content="URL_FOR_ACHIEVEMENT_IMAGE"/> <meta property="game:points" content="POINTS_FOR_ACHIEVEMENT"/> <meta property="fb:app_id" content="YOUR_APP_ID"/> </head> <body> Promotional content for the Achievement. This is the landing page where a user will be directed after clicking on the achievement story. </body> </html>
Now that you have defined your achievements, you need to register these achievements with your app by issuing an HTTP POST
to /APP_ID/achievements
with an app access token. You also need to specify the achievement
parameter. You should also specify a display_order
parameter. The achievement parameter is the URL where you define the achievements in your app. The display_order
parameter indicates the order of this achievement as it shows up in the UI (low to high). For example, a display_order
of 100 will be displayed in the UI before 200.
https://graph.facebook.com/YOUR_APP_ID/achievements? achievement=YOUR_ACHIEVEMENT_URL& display_order=YOUR_ACHIEVEMENT_DISPLAY_ORDER& access_token=APP_ACCESS_TOKEN
Once you register achievements with your app, you can publish them. Publish achievements by issuing an HTTP POST
to /USER_ID/achievements
and specifying the achievement parameter and the app access token:
https://graph.facebook.com/USER_ID/achievements? achievement=YOUR_ACHIEVEMENT_URL&access_token=APP_ACCESS_TOKEN
The PHP example below builds upon the initial example that requests the publish_actions
permission and publishes user scores and achievements:
<?php $app_id = 'YOUR_APP_ID'; $app_secret = 'YOUR_APP_SECRET'; $canvas_page_url = 'YOUR_CANVAS_PAGE_URL'; // The Achievement URL $achievement = 'YOUR_ACHIEVEMENT_URL'; $achievement_display_order = 1; // The Score $score = 'USER_SCORE'; // Authenticate the user session_start(); if(isset($_REQUEST["code"])) { $code = $_REQUEST["code"]; } if(empty($code) && !isset($_REQUEST['error'])) { $_SESSION['state'] = md5(uniqid(rand(), TRUE)); //CSRF protection $dialog_url = 'https://www.facebook.com/dialog/oauth?' . 'client_id=' . $app_id . '&redirect_uri=' . urlencode($canvas_page_url) . '&state=' . $_SESSION['state'] . '&scope=publish_actions'; print('<script> top.location.href=\'' . $dialog_url . '\'</script>'); exit; } else if(isset($_REQUEST['error'])) { // The user did not authorize the app print($_REQUEST['error_description']); exit; }; // Get the User ID $signed_request = parse_signed_request($_POST['signed_request'], $app_secret); $uid = $signed_request['user_id']; // Get an App Access Token $token_url = 'https://graph.facebook.com/oauth/access_token?' . 'client_id=' . $app_id . '&client_secret=' . $app_secret . '&grant_type=client_credentials'; $token_response = file_get_contents($token_url); $params = null; parse_str($token_response, $params); $app_access_token = $params['access_token']; // Register an Achievement for the app print('Register Achievement:<br/>'); $achievement_registration_URL = 'https://graph.facebook.com/' . $app_id . '/achievements'; $achievement_registration_result=https_post($achievement_registration_URL, 'achievement=' . $achievement . '&display_order=' . $achievement_display_order . '&access_token=' . $app_access_token ); print('<br/><br/>'); // POST a user achievement print('Publish a User Achievement<br/>'); $achievement_URL = 'https://graph.facebook.com/' . $uid . '/achievements'; $achievement_result = https_post($achievement_URL, 'achievement=' . $achievement . '&access_token=' . $app_access_token ); print('<br/><br/>'); // POST a user score print('Publish a User Score<br/>'); $score_URL = 'https://graph.facebook.com/' . $uid . '/scores'; $score_result = https_post($score_URL, 'score=' . $score . '&access_token=' . $app_access_token ); print('<br/><br/>'); function https_post($uri, $postdata) { $ch = curl_init($uri); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata); $result = curl_exec($ch); curl_close($ch); return $result; } 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, '-_', '+/')); } ?>
For more information, please read the Graph API documentation for achievements and scores.
We look forward to your feedback and questions in the comments below.