Collected

Home

Create collection

Browse collections

Join Collected


Username


Password


Forgot your password?


api

A collection of:

A collection of ellensundh   

By:

ellensundh   

Visits:

8,166   

View:

 
1 favorites | Add to favorites |

iOS and Android: Single Sign-On Best Practices


Facebook Developer Blog 26 Jan 2012, 12:45 pm CET

Over a year ago, we introduced Single Sign-On (SSO) for Android and iOS. Today, more than 350 million active users currently access Facebook through their mobile devices. Users logged into the Facebook for iOS or Facebook for Android app can use the “Login with Facebook” button and, in one-click through a permissions dialog, login to your app. This saves users from typing in an e-mail address and password for apps that require registered users. Since the launch of SSO, developers implementing it in their apps have enjoyed increased user registrations and access to the Graph API to build in-app social experiences.

SSO Product Update

We have made significant stability and performance improvements in SSO as well as making it a core part of enabling Social Mobile App Discovery that we announced last October. In addition, we created a simpler authentication flow for users who have already authenticated your app. If a user has previously given your app the requested permissions, SSO will immediately pass an OAuth 2 access token back to your app. For example, if you already have a connected Facebook user on your website or canvas app, users will be able to login faster into your mobile native apps.

Pro-tip 1: Include Facebook Login at User Registration

Apps will often only use SSO and Facebook Login when asking the user to enable Facebook features in the app. You should also include Facebook Login anywhere you prompt the user to Register for your app, often times when users launch your app for the first time. Users can enjoy a simplified registration process, and you can request the same information, such as e-mail address, that you would normally collect manually from the user.

Pro-tip 2: Store the user’s session in your app

After your user authenticates for the first time, you should immediately store the authentication result locally. This way, you can keep the user logged-in to your app without having the user re-authenticate each time. Here are some Android and iOS Code samples that demonstrate how you can easily do this in your app:

iOS Example: In the fbDidLogin delegate method, when the user has logged in via SSO, save the session:

- (void)fbDidLogin {
  NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
  [defaults setObject:[facebook accessToken] forKey:@"FBAccessTokenKey"];
  [defaults setObject:[facebook expirationDate] forKey:@"FBExpirationDateKey"];
  [defaults synchronize];
}

Then, when your app starts in the future, set the accessToken and expirationDate in your Facebook object if they exists:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:@"FBAccessTokenKey"]
  && [defaults objectForKey:@"FBExpirationDateKey"]) {
  facebook.accessToken = [defaults objectForKey:@"FBAccessTokenKey"];
  facebook.expirationDate = [defaults objectForKey:@"FBExpirationDateKey"];
}

Android Example: When the user has logged in via SSO, save the session:

Editor editor = context.getSharedPreferences("facebook-session", 
                                             Context.MODE_PRIVATE).edit();
editor.putString("access_token", session.getAccessToken());
editor.putLong("expires_in", session.getAccessExpires());

When you app starts, in onCreate, restore the session if it exists:

SharedPreferences savedSession = context.getSharedPreferences
                                 ("facebook-session",Context.MODE_PRIVATE);
session.setAccessToken(savedSession.getString("access_token", null));
session.setAccessExpires(savedSession.getLong("expires_in", 0));

Pro-tip 3: Request only the permissions your app needs

We have streamlined the SSO permissions dialog, along with all permission dialogs in our recently announced Improved Auth Dialog. You should only request the permissions you need to get the user registered and using your app’s social features.

As part of our ongoing efforts to improve privacy protections for Facebook users, we've deprecated the 'offline_access' permission. Instead, you now have the option to extend the expiration of existing, valid access tokens for a limited amount of time without requiring the user to login again. Learn more about upgrading access tokens. Also, many apps incorrectly ask for 'publish_stream' when using our Feed Dialog. Your app only needs 'publish_stream' if it will be publishing to the user’s feed programmatically with the Graph API.

Pro-tip 4: Complete all iOS and Android Fields in your App Settings

Be sure to fill out every field related to your app in your app settings in the Native iOS App and the Native Android App fields. You can access these app settings for your app here. On iOS, If these fields are not configured, we will not be able to drive traffic to your app or the iOS App Store. In addition, we use the iOS Bundle ID to streamline authentication for users who have already authenticated your app.

In the coming weeks, we will be posting additional best practices for leveraging the Facebook Platform in iOS and Android Apps. Implementing SSO is the first step to taking advantage of improved distribution and engagement with the Facebook Platform in these environments.

Get started with our step-by-step documentation and sample code available in the iOS Getting Started and Android Getting Started guides.

Platform Updates: Operation Developer Love


Facebook Developer Blog 25 Jan 2012, 7:20 pm CET

This week we announced how to implement flashHideCallback to support "wmode=window". We are also announcing the following changes:

Getting SubscribedTo and Subscribers via Graph API

We are now providing the ability of reading a user's subscribers and subscribees list via the Graph API. To access this information, your app is required to have the user_subscriptions permission for the user, and friends_subscriptions permission for their friends' info. Refer to the documentation for SubscribedTo and Subscribers for more details.

To access a user's subscribers list, issue an HTTP GET request to the subscribers connection like the following:

https://graph.facebook.com/USER_ID/subscribers?access_token=...

Similarly, to access a user's subscribees list, issue an HTTP GET request to the subscribedto connection.

https://graph.facebook.com/USER_ID/subscribedto?access_token=...

The following PHP example demonstrates how to read the subscribed-to list:

<?php
  $app_id = 'YOUR_APP_ID';
  $app_secret = 'YOUR_APP_SECRET';
  $my_url = 'YOUR_URL';

  $code = $_REQUEST["code"];

  if (!$code) {
    // user_subscriptions and  friend_subscriptions permissions 
    // are required
    $dialog_url = "http://www.facebook.com/dialog/oauth?client_id="
     . $app_id . "&redirect_uri=" . urlencode($my_url)
     . "&scope=user_subscriptions";
    echo('<script>top.location.href="' . $dialog_url . '";</script>');
  } else {
    $token_url = "https://graph.facebook.com/oauth/access_token?client_id="
     . $app_id . "&redirect_uri=" . urlencode($my_url)
     . "&client_secret=" . $app_secret
     . "&code=" . $code;
    $access_token = file_get_contents($token_url);

    // Get request for the subcribed-to list
    $subscribedto_url =
      "https://graph.facebook.com/me/subscribedto?"
     . "access_token=".$access_token;
    $subscribedto_resp_obj =
      json_decode(file_get_contents($subscribedto_url), true);

    // Parse the return value and get the array of people subscribed to.
    // This is in returned in the data[] array
    $subscribedto = $subscribedto_resp_obj['data'];

    print_r($subscribedto);
  }
?>

Improved Search Results on the Developer Site

We improved search results on the Dev Site. Search now includes Technical Q&A from Stack Overflow and Bugs. You can also filter your results to only show the type of information you are looking for (e.g., blog posts, documentation, API reference, technical Q&A, bugs).

manage_notifications Permission Now Required for Managing a User's Notifications.

As announced on the blog on July 29, 2011 and on the Roadmap, to read or manage a user's notifications we now require the manage_notifications permission. The "Require manage_notifications" migration has now been removed per our 90-day breaking change policy. For more information, see the User object documentation.

Upcoming Breaking Changes on February 1st 2012

  • Removing FeatureLoader JavaScript SDK. As part of the OAuth2 migration, we announced that the FeatureLoader SDK is no longer supported as of October 1st, 2011. On February 1st 2012, we will remove FeatureLoader. Please ensure that your app is using the JS SDK.
  • Removing canvas_name Field from Application Object We will be deprecating the canvas_name field in favor of namespace field on the application object on February 1st 2012.
  • Removing App Profile Pages We will be deleting all App Profile Pages and redirecting all traffic directly to the App on February 1st 2012. For more information, please refer to the blog post.
  • Removing REST support for Ads API We will be removing REST support for the Ads API on February 1st 2012. All Ads API developer must move their applications to use the Graph API.
  • Improved Auth Dialog On February 1st 2012, all apps will be enabled for the improved dialog, but those that haven’t fully configured their dialog can disable the setting in the Developer App until February 15, at which time it will be turned on for all apps.

New Breaking Changes

  • Pages Insights Metrics Deprecations. We are in the process of deprecating some old Page Insights. We announced this in a number of forums, but failed to outline this change in our Platform Roadmap per our breaking change policy. Our apologies. You can find a full list of the Insights to be deprecated from the Insights documentation. These Insights will be completely removed from API on Feb 15th 2012. Please make all necessary updates as soon as possible so that you can transition smoothly.

  • Throwing an Exception for Invalid filter_key. We will throw an exception if you try to query the stream FQL table with an invalid filter key. Currently if you call stream.get with an invalid filter_key value, the query silently fails, and with this change we will be throwing an exception. Refer to FQL stream documentation for details on using a filter_key. This change will take effect on May 1st 2012.

Please refer to the Platform Roadmap for more info.

Bug Activity from 1/18/12 to 1/24/12

Watch History Comes to the API


YouTube API Blog 24 Jan 2012, 10:50 pm CET

There’s a new entry in the growing list of video feeds supported by the YouTube Data API: the watch history feed. This feed allows authenticated API users to retrieve their own YouTube viewing histories—retrieving the watch history of any other user is not allowed. The information in this new feed corresponds to the viewing history exposed on the YouTube website. The feed could enable interesting new functionality in your applications. If your site displays a list of recommended videos for an authenticated user to watch, you might consider excluding those videos that have been already viewed, for instance. Or you might want to include a video that you discover the user has been watching over and over again. Knowing the sorts of videos that a user watches makes it easier for your application to algorithmically suggest other videos that might interest your users. As with any functionality related to the YouTube API, the best place to ask questions about the new watch history feed is the YouTube API developer forum. Cheers, —Jeff Posnick, YouTube API Team

How-To: Implementing hideFlashCallback to support "wmode=window"


Facebook Developer Blog 23 Jan 2012, 4:30 pm CET

One of the Pro-Tips we mentioned late last year in our Games Tutorial to Developers creating Flash based Apps was to use wmode=opaque whenever possible. Setting wmode to any value other than "opaque" or "transparent" prevents any HTML content from being displayed at a higher z index than the Flash object. This results in Dialogs, Notifications and Ticker Flyouts being displayed under the Flash object and creates a pretty poor user experience on Canvas.

As a result when Canvas Apps set wmode to "window" or "direct" Facebook automatically hides the Flash object when any Dialogs, Notifications or Ticker Flyouts are opened. To help improve the user experience we have recently introduced a new parameter for FB.init in the JavaScript SDK called hideFlashCallback . This allows developers to specify their own behavior for the auto hiding of Flash objects with wmode=window or direct, so long as the custom behavior completes in 200ms or less. After 200ms we will hide the Flash Object automatically regardless.

This How-To will walk you through the process of creating a temporary dynamic screenshot of your Flash App and replacing the Flash Object with this image within 200ms. This allows Dialogs to display correctly and creates a more pleasing user experience.

The How-To is divided into the following sections:

  1. Creating a Dynamic Screenshot in Flash
  2. Enabling ActionScript to JavaScript Communication
  3. Using a Data URI
  4. Setting up the hideFlashCallback Functionality
  5. Source Code for the Example App

Developers are expected to be familiar with JavaScript and ActionScript 3.0 in order to continue.  

Creating a Dynamic Screenshot in Flash

The first step will be to implement a method within your Flash App that creates a dynamic screenshot of the Stage object, compresses this into a JPEG format and then Base64 encodes this string. Fortunately there are public libraries available that will take care of most of these steps. For this example we will use: http://www.blooddy.by/en/crypto/ or feel free to use any lib that you prefer.

Next we will create the ActionScript exportScreenshot method that will return our screenshot data string, ready for use.

ActionScript

import by.blooddy.crypto.Base64;
import by.blooddy.crypto.image.JPEGEncoder;

...

private function exportScreenshot():String {
  var scale:Number = 0.25;
  var result:String = null;
  var blurFilter:BlurFilter = new BlurFilter(3, 3, BitmapFilterQuality.HIGH);

  var bData:BitmapData = new BitmapData(stage.stageWidth * scale,
    stage.stageHeight * scale,false,0x0);
  var matrix:Matrix = new Matrix();
  matrix.scale(scale, scale);

  bData.draw(stage, matrix);
  bData.applyFilter(bData, bData.rect, new Point(0, 0), blurFilter);

  var jpgBytes:ByteArray = JPEGEncoder.encode(bData,80);
  if (jpgBytes) {
    var screenshotBase64:String = Base64.encode(jpgBytes);
    if (screenshotBase64) {
      result = screenshotBase64;
    }
  }

  return result;
}

Walking through the code line by line you will notice that we are scaling the image to 25% of the full Stage dimensions. This is to reduce the size of our screenshot image and increase overall performance. Next we apply a BlurFilter to smooth out the jagged edges that result. Finally we encode our Bitmap as a JPEG, base64 encode it and then return the string.  

Enabling ActionScript to JavaScript Communication

Now that we have a method in our Flash App that can create a dynamic screenshot image we will need to support JavaScript communication from within the Flash Object. This will allow us to create a screenshot dynamically through a JavaScript call.

To do this we will need to import the ExternalInterface class in our Flash App and register a callback method.

ActionScript

import flash.external.ExternalInterface

...

ExternalInterface.addCallback('exportScreenshot', exportScreenshot);

The code registers a callback method called exportScreenshot in JavaScript allowing us to call our ActionScript method of the same name from JavaScript directly.  

Using a Data URI

Next we will create a image HTML element that will contain our dynamic screenshot and replace the Flash Object temporarily. To implement this we will use a Data URI allowing us to define the image data inline without having to make any requests back to a web server, increasing our performance.

Note: This is only available in modern browsers, Internet Explorer 8 and above. For IE7 and below you will have to fallback to a static image and cannot use the method described in this How-To.

In the HTML below we define a div HTML element that will contain our Flash content and directly underneath, a div HTML element that contains our img element that will hold our screenshot image. Finally we set both of these elements to have absolute position within a relative positioned parent. This allows us to place the img element beneath our Flash Object.

HTML

<div id="allContent" style="position:relative;">
  <div id="flashContent" style="position:absolute">
    <div id="flashHolder"></div>
  </div>
<div id="imageContent" style="position:absolute; top: -10000px;">
  <img id="screenshotObject"
    src="blank.gif"
    style="margin: 0 auto; display:block;" />
</div>

After we call the exportScreenshot method from JavaScript to get our dynamic screenshot, we set the dimensions of our img element to match the Flash Object, move the Flash Object out of the display area and put the screenshot image in it's place.

JavaScript

// Call the Flash Actionscript method to create the dynamic screenshot
var screenshotData =
  document.getElementById('flashObject').exportScreenshot();

// Set the screenshot image data as a base64 encoded data URI
// in the img src attribute
document.getElementById('screenshotObject').src = 'data:image/jpeg;base64,'
  + screenshotData;

// Set the screenshot img dimensions to match the Flash object tag.
document.getElementById('screenshotObject').width = flashObject.width;
document.getElementById('screenshotObject').height = flashObject.height;
  
// Move the Flash object off the screen and put the screenshot in it's place
document.getElementById('flashContent').style.top = '-10000px';
document.getElementById('imageContent').style.top = '';

 

Setting up the hideFlashCallback Functionality

The last step is putting all of this code together and executing it based on the hideFlashCallback callback. To do this, we wrap our JavaScript code (above) into a function called displayFlashScreenshot and create a new method hideFlashScreenshot which will do the reverse: hide our screenshot and then display our Flash Object again. Basically, when a Dialog is opened we want to execute displayFlashScreenshot to display our screenshot and when the Dialog is closed we want to execute hideFlashScreenshot to display our Flash content.

Next we create a new method onFlashHide to handle the open/close state and assign it to the hideFlashCallback parameter in FB.init. In onFlashHide we check the info.state property and then call the corresponding JavaScript method.

JavaScript

function displayFlashScreenshot() {
  // Call the Flash Actionscript method to create the dynamic screenshot data
  var screenshotData =
    document.getElementById('flashObject').exportScreenshot();

  // Set the screenshot image data as a base64 encoded data URI
  // in the img src attribute
  document.getElementById('screenshotObject').src = 'data:image/jpeg;base64,'
    + screenshotData;

  // Set the screenshot img dimensions to match the Flash object tag.
  document.getElementById('screenshotObject').width = flashObject.width;
  document.getElementById('screenshotObject').height = flashObject.height;
        
  // Move the Flash object off the screen and place the screenshot img
  document.getElementById('flashContent').style.top = '-10000px';
  document.getElementById('imageContent').style.top = '';
}

function hideFlashScreenshot() {
  // Move the screenshot img off the screen and place the Flash object
  document.getElementById('flashContent').style.top = '';
  document.getElementById('imageContent').style.top = '-10000px';
}

function onFlashHide(info) {
  if(info.state == 'opened') {
    displayFlashScreenshot();
  } else {
    hideFlashScreenshot();
  }
}

FB.init({
  appId  : 'APP_ID',
  hideFlashCallback : onFlashHide
});

For more information on the hideFlashCallback parameter see the JavaScript SDK Docs.  

Full Source Code for the Example App

Download the source code for the Example App which includes the HTML, JavaScript and ActionScript code referenced in the examples above.

Fab Friday: A view from the street


Google Geo Developers Blog 20 Jan 2012, 8:08 pm CET

It’s Fab Friday again! This is getting fun, I like doing this. This week’s theme is Street View. First up, Andres Ferrate from Maps Developer Relations (or MDR as some of us are calling it these days) produced this screencast on incorporating Street View and Custom Panoramas into your app. Check it out:

Next up, we have Historypin. Historypin is a site that lets you upload and view historic photos in Google Maps. Better, you can actually view them on top of current Street View imagery. Here’s a screenshot from Florence, Italy:

Finally, there’s the fabulous gta4.net fan site that uses the Google Maps API Custom Street View Panorama API to render Liberty City entirely in Street View. Let me be clear, not the Liberty City of Florida, but the fictitious city in the video game Grand Theft Auto IV. Lots of fan hours went into doing screen capture, let me tell you.

Posted by Mano Marks, Maps Developer Relations team

Platform Updates: Operation Developer Love


Facebook Developer Blog 20 Jan 2012, 4:00 pm CET

This week, we launched the improved auth dialog and over 60 new Open Graph apps.

Approving Open Graph Actions

We are now approving Open Graph Actions. If you are new to the Open Graph, please review the Tutorial on how to use the Open Graph to integrate your app with Facebook. Please review and check your Actions against the required criteria prior to submission.

Writing Questions via Graph API

We recently announced the ability to read questions via the Graph API. We are now adding the option to write them. To create a question for the current user, issue an HTTP POST to the questions connection like this:

  curl -F 'access_token=...' 
       -F 'question=What is your favorite color?' 
       https://graph.facebook.com/me/questions

Here's a PHP example that shows the optional parameters: options and allow_new_options -- and how to post a question as a Page using its access token:

<?php
  $question = 'What are you doing this weekend?';
  $options = json_encode(array('Hiking','Watching a movie','Hacking'));

  $page_id = 'YOUR_PAGE_ID';
  $app_id = 'YOUR_APP_ID';
  $app_secret = 'YOUR_APP_SECRET';
  $my_url = 'YOUR_URL';

  $code = $_REQUEST["code"];

  echo '<html><body>';

  if (!$code) {
    // manage_pages permissions is required for accounts the user
    // has access to, and posting to the Page
    $dialog_url = "http://www.facebook.com/dialog/oauth?client_id="
     . $app_id . "&redirect_uri=" . urlencode($my_url)
     . "&scope=manage_pages";
    echo('<script>top.location.href="' . $dialog_url . '";</script>');
  } else {
    $token_url = "https://graph.facebook.com/oauth/access_token?client_id="
     . $app_id . "&redirect_uri=" . urlencode($my_url)
     . "&client_secret=" . $app_secret
     . "&code=" . $code;
    $access_token = file_get_contents($token_url);
    $accounts_url = 
         "https://graph.facebook.com/me/accounts?" . $access_token;
    $response = file_get_contents($accounts_url);

    // Parse the return value and get the array of accounts - this is
    // returned in the data[] array.
    $resp_obj = json_decode($response,true);
    $accounts = $resp_obj['data'];

    // Find the access token for the Page
    $page_access_token = '';
    foreach($accounts as $account) {
         if($account['id'] == $page_id) {
           $page_access_token = 'access_token=' . $account['access_token'];
           break;
         }
    }

    // Post the question to the Page
    $post_question_url = 
        "https://graph.facebook.com/" . $page_id . '/questions' .
    "?question=" . urlencode($question) .
    '&options=' . urlencode($options) .
    '&allow_new_options=false' .
    "&method=post&" . $page_access_token;

    echo file_get_contents ($post_question_url);
  }
  echo '</body></html>';
?>

Questions may be removed by issuing an HTTP DELETE to their id. More information is available in the Question documentation, User documentation, and Page documentation.

Subscribe to the Developer and HTML5 blog

We recently built an Email Settings dashboard that lets you easily manage your subscriptions to the Developer and HTML5 blog. To access your email settings, click on the arrow on the top right and select "Email Settings."

Improved Search typeahead on the Dev Site

We want to help you more quickly access the information you need on the Developer Site. The search typeahead now includes Bugs along with Apps and Documentation.

Policy Training Videos

We added two policy training videos to help new developers better understand our Platform Policies and Promotion Guidelines.

Upcoming Breaking Changes

  • Removing FeatureLoader JavaScript SDK. As part of the OAuth2 migration, we announced that the FeatureLoader SDK is no longer supported as of October 1st, 2011. On 2/1/2012, we will remove FeatureLoader. Please ensure that your app is using the JS SDK.
  • Removing canvas_name Field from Application Object We will be deprecating the canvas_name field in favor of namespace field on the application object on 2/1/2012.
  • Removing App Profile Pages We will be deleting all App Profile Pages and redirecting all traffic directly to the App on 2/1/2012. For more information, please refer to the blog post.
  • Removing REST support for Ads API We will be removing REST support for the Ads API. All Ads API developer must move their applications to use the Graph API.
  • Improved Auth Dialog On February 1, 2012, all apps will be enabled for the improved dialog, but those that haven’t fully configured their dialog can disable the setting in the Developer App until February 15, at which time it will be turned on for all apps.

Please refer to the Platform Roadmap for more info.

Bug Activity from 1/11/12 to 1/17/12

Introducing pyKML - a Python library for manipulating KML


Google Geo Developers Blog 18 Jan 2012, 8:45 pm CET

Author Photo pyKML is an open source Python library for generating, parsing, and modifying KML, the geo-spatial data language used by Google Earth, Google Maps and a number of other GIS platforms. I was motivated to create pyKML because I frequently need to visualize large, and often complex, environmental datasets. While the KML language has a wide range of options for styling, annotating and interacting with geo-spatial and temporal data, most programs that generate KML don’t take full advantage of these rich features. I created the pyKML library to address this problem by providing easy, programmatic access to all KML elements. pyKML facilitates working with large and complex KML documents by leveraging the use of basic programming constructs (looping, branching, etc.). In this regard pyKML is similar to libkml, Google’s open source C++ library, but takes advantage of the highly readable syntax of the Python programming language and the processing capabilities of the popular lxml Python library. As a simple example, check out this Python script that loops through a text string (“Hello World!”) and uses pyKML to create a series of KML Placemarks. You can download the resulting KML document, and below is a screenshot of how it looks in Google Earth. This is just a teaser of what pyKML can do. For more complex examples, check out the pyKML documentation and the project’s Google Code site that includes sample code for: generating KML from CSV data, creating KML Tours, and visualizing ephermeris data for Stonehenge (e.g., orientation of the sun on different dates). pyKML can even be used to create “slides" for presentations! To get started, browse the project’s documentation, install the library, try it out, and let us know what you think! Posted by Tyler Erickson, Senior Research Scientist / Engineer, MTRI

Open Graph now available


Facebook Developer Blog 18 Jan 2012, 6:00 pm CET

At f8, we announced Timeline and the Open Graph - the next generation of the platform which enables people to tell their stories through the apps they use. The Open Graph has already had a significant impact on music, news, and video, but this was just the beginning. Starting today, developers can build apps that let people add anything they love to their Timelines - whether it is eating, traveling, shopping, running or taking pictures.

As a part of the this launch, more than 60 apps are going live today - including Pinterest, Rotten Tomatoes / Flixster, Foodspotting, Gogobot, and more. These are great examples of how the Open Graph brings experiences to Facebook. The developers took things that users already enjoy and made it easy for users to express them on their timeline.

If you are new to Open Graph, please check out the tutorial on how to use the Open Graph to integrate your app with Facebook. If you've already submitted Open Graph actions, we are starting to approve actions that meet our guidelines today, and hope to have all actions previously submitted approved within the next month.

The apps launching today are just starting to demonstrate the types of self-expression that are possible with the Open Graph. There are many more stories to tell and great apps to tell them. Get started today!

Launching the Improved Auth Dialog


Facebook Developer Blog 18 Jan 2012, 12:00 pm CET

Over the past few months, we’ve been testing and iterating on the new Auth Dialog to incorporate feedback from users, developers and other third parties. By introducing new ways for people learn about an app and giving them more control over their data, we believe this update will benefit both users and developers. Today, we’re making the improved version available and announcing the migration plan for developers.

More Control & Clarity for Users Similar to the inline privacy controls people have when they post content, we are introducing a new, inline privacy setting that allows a user to control who can see their app activity on Facebook. With this setting, people can share their app activity with as large or small an audience as they'd like.

We have added headline and description areas, so developers can help people can learn about their apps before installing them. There is also a new area of the dialog to let people know when they're installing a Timeline app, which will share their activity in the app on Facebook. As we've previously described, we encourage developers to carefully consider their users' expectations and whether they should build separate in-app privacy controls.

Optional Permissions It’s important for people to understand how permissions like 'publish_stream' and 'create_events' are used, so we’re moving extended permissions to a second screen, so they’re easier to review, and we’re making them optional for users. With this change, we’re also providing a new area that lets developers explain why they are requesting the optional permissions.

As part of our ongoing efforts to improve privacy protections for Facebook users, we are also deprecating the 'offline_access' permission. Instead, we are providing developers a method to reset the expiration time for valid, existing access tokens when a user interacts with their app.

There are no changes required for most apps, but developers utilizing the 'offline_access' permission will have until May 1, 2012 to update their apps. Learn more about upgrading access tokens.

Authenticated Referrals Along with the new dialog, we are making Authenticated Referrals available to developers. If you're building a social app, where all of your users are Facebook users, this new product will streamline the authentication process. By enabling the feature, the permissions dialog will be displayed inline when people click any link to your app on Facebook, enabling you to personalize people's experiences the moment they arrive at your app.

Implementation & Required Steps The new Auth Dialog is starting to rolling out today for web, mobile and desktop apps. You can start using it in your app by enabling the “Enhanced Auth Dialog” setting in the Developer App. When you upgrade to the new dialog, be sure to also provide a compelling, headline and description via the Developer App and verify that your apps don’t break if users deny optional permissions (see tutorial).

On February 1, 2012, all apps will be enabled for the improved dialog, but those that haven’t fully configured their dialog can disable the setting in the Developer App until February 15, at which time it will be turned on for all apps.

We appreciate the feedback we’ve received during the development of the new dialog over the past few months. If you have any questions or any additional thoughts, please post them to the comments below.

Fab Friday: Feel the Heat


Google Geo Developers Blog 13 Jan 2012, 8:15 pm CET

Author Photo

We’ve been talking a lot recently around the Maps Developer Relations Team about heat maps. Heat maps use colors to represent the intensity of occurrence or certain values. Heat maps are a popular way to represent data. People often ask me how to create them themselves. So the other day when I ran across heatmap.js, with it's nifty Google Maps API Heatmap Overlay, I thought it would be perfect to share with you. Heatmap.js uses HTML5 Canvas to render the heatmap on top of the map. Apparently, it’s in early release, so feel free to help the developer, Patrick Weid out with some patches. Here's what it looks like:

On another note, we recently announced that several college campuses are now available in Google Street View, in areas outside roads. That data is now available to you in the Google Maps API. Here’s the Quad at Stanford:

Finally, if any of you are going to be at Strata, Chris Broadfoot and I will be presenting a workshop there March 1st called Beautiful Vectors. Check it out or just find us and say hi.

Posted by Mano Marks, Maps Developer Relations team

Platform Updates: Operation Developer Love


Facebook Developer Blog 11 Jan 2012, 6:15 pm CET

This week, we published a How-To on using ETags with the Graph API, announced increased ticket availability for our upcoming Mobile Hack and launched the following changes:

Improved Comments Box for Mobile

We've updated the Comments Box to optimize the experience for mobile visitors and more closely resemble the mobile Facebook experience.

The social plugin automatically displays the new view based on user agent, but developers can choose to show the classic web view by specifying mobile="false".

Graph API Now Supports Filters for the Home connection

A new parameter filter is now supported by the Graph API Home connection. The Home connection is used to retrieve a user's newsfeed, which can now be filtered via the filter parameter. Supported values are listed in the user's stream_filter table. For more information check out the docs.

Infinite Scrolling for the Apps and Games Dashboard

The Apps and Games Dashboard has been updated to support infinite scrolling for the "Friends Using", "Recommended Games", "Recommended Apps" and "Newest" category tabs. After selecting a tab, users can now continually scroll the list of content to get additional recommendations for great Games and Apps they might be interested in.

Breaking Change: User Support Email is Now Required for Apps

Today we're announcing that the User Support Email field in the Developer App will be required for all apps on April 1st 2012. By setting a support URL and email address developers can utilize both their own help center from their site as well as receive email disputes from the Facebook dispute flow.

The User Support Email field can be updated in the Developer App under Settings > Advanced > Contact Info.

Breaking Changes effective this week

  • Request 2.0 Migration: This will be set to enabled on 1/15/2012 for all apps after which only Requests created via the Dialog API or the Graph API will affect the Bookmark Counter. This completes our migration to Request 2.0 from FBML Requests which have become unsupported as of 1/1/2012.
  • Requests 2.0 Efficient: The Request 2.0 Efficient migration will be enabled for all apps over the next few days. Please make sure to update your apps now to respect the updated request ID format to avoid any disruption of service. On 1/15/2012 this setting will be set to enabled for all apps. For more information please see the Requests docs.

Breaking Changes effective on February 1, 2012

  • Removing canvas_name Field from Application Object We will be deprecating the canvas_name field in favor of namespace field on the application object on 2/1/2012.
  • Removing App Profile Pages We will be deleting all App Profile Pages and redirecting all traffic directly to the App on 2/1/2012. For more information, please refer to the blog post.

Bug activity between 1/3 and 1/10

  • 268 bugs were reported
  • 63 bugs were reproducible and accepted (after duplicates removed)
  • 35 bugs were by design
  • 25 bugs were fixed
  • 116 bugs were duplicate, invalid, or need more information

Reported bugs fixed between 1/3 and 1/10

Activity on facebook.stackoverflow.com this week

  • 141 questions asked
  • 59 answered, 42% answered rate
  • 99 replied, 70% reply rate

Additional tickets now available for Mobile Hack in New York and Boston


Facebook Developer Blog 10 Jan 2012, 3:30 pm CET

A few weeks ago we announced Mobile Hacks coming to New York and Boston.

Already, many East Coast developers have signed up to attend. We are now releasing additional tickets for these events:

New York on January 18th at the New York Sentry Centers, 730 3rd Ave, New York: Sign up

Boston on January 20th at Le Méridien Cambridge-MIT, 20 Sidney Street, Cambridge: Sign up

At these all-day events you will learn about building social mobile apps and then hack on your own apps. We will cover iOS, Android, and mobile web (HTML5) app development.

Planned Agenda:

  • 11:00am - Registration Open + Lunch
  • 12:15pm - Facebook Platform on Mobile: Intro
  • 12:30pm - Web Apps (HTML5) development
  • 1:15pm - Native App development (IOS, Android)
  • 2:00pm - Break
  • 2:30pm - Native Distribution for Web Apps: Phone Gap
  • 3:00pm - Partner presentation
  • 3:30pm - Q&A
  • 4:30pm - Hack + Dinner
  • 9:00pm - App Presentation & Awards
  • 10:00pm - Event Close [In Boston Hack will go on until 11pm]

Attendance cost is $25 (free for students at the Boston event) and registration is first-come, first-serve. Awards will be given to the best apps presented at the event.

How-To: Optimize the Graph API data fetch using ETags


Facebook Developer Blog 9 Jan 2012, 11:10 am CET

Imagine if you could only get data from an API when things have changed or there is new data? Well, you do not have to imagine anymore, the Facebook Graph API now supports HTTP ETags. ETags support on the Facebook Platform can help you reduce bandwidth consumption and client-side overhead by suppressing output when making Graph API calls. In addition, clients (especially mobile devices on slow connections) can increase performance and reduce data usage when calling the Graph API with ETags.

This is how it works:

  1. When you make a Graph API call, the response header includes ETag with a value that is the hash of the data returned in the API call. Pull this ETag value and use in Step-2.
  2. Next time you make the same API call, include the If-None-Match request header with ETag value pulled from step-1 for this API call.
  3. If the data hasn’t changed, the response status code would be 304 – Not Modified and no data is returned.
  4. If the data has changed since last pull, the data is returned as usual with a new ETag. Pull the new ETag value and use for subsequent calls.

Note: While ETags help reduce the data traffic, the If-None-Match GET will still count against the throttling limits for your app and must not be performed at a frequent rate. We recommend only do it for data that doesn’t change frequently like user’s friends, likes, photo albums, photos etc. Do not use it for news feed, messages etc.

The ETag is calculated using the entire response from the API call including its formatting. Developers should be aware that the formatting of API response output may be impacted by the user agent string. Therefore, calls originating from the same client should keep the user agent consistent between calls.

Example:

Install Firebug and Modify Headers add-ons on Firefox.

Fetching user’s friends: https://graph.facebook.com/me/friends?access_token=<token> returns friends data in JSON output and ETag in the response header. You can quickly test by visiting the Graph API Doc and clicking on the Friends sample link that auto generates access token for the session user and makes this API call.

Next create the If-None-Match request header in the Modify Header add-on tool with the ETag value pulled from the Firebug. Make sure the header is enabled (green lit).

Now call the friend Graph API again - https://graph.facebook.com/me/friends?access_token=<token>. Note that the API returns no data and the status code is ‘304- Not Modified’:

PHP Code Example:

The php code demonstrates ETags while fetching user’s friends. The code pulls the ETag from the response header and then call the same API again while passing the ETag value in the If-None-Match request header. Notice that the response for the second call is 304 – Not Modified.

  <?php

    $app_id = 'YOUR_APP_ID';
    $app_secret = 'YOUR_APP_SECRET';
    $my_url = 'YOUR_REDIRECT_URL';

    $code = $_REQUEST["code"];

    echo '<html><body>';

    // Auth the app using the server side OAuth 2.0
    if(!$code) {
        // get permission from the user to publish to their page.
        $dialog_url = "http://www.facebook.com/dialog/oauth?client_id="
         . $app_id . "&redirect_uri=" . urlencode($my_url);
        echo('<script>top.location.href="' . $dialog_url . '";</script>');
    } else {
        // get access token for the user
        $token_url = "https://graph.facebook.com/oauth/access_token?"
         . "client_id=" . $app_id 
         . "&redirect_uri=" . urlencode($my_url)
         . "&client_secret=" . $app_secret
         . "&code=" . $code;
        $access_token = file_get_contents($token_url);

        // get user's friends now we have the access token
        $friend_url = 'https://graph.facebook.com/me/friends?' . 
                    $access_token;

        // initialize curl if not yet initialized
        if (!$ch) {
          $ch = curl_init();
        }

        /*
         * Disable the 'Expect: 100-continue' behaviour. This causes CURL
         * to wait for 2 seconds if the server does not support this 
         * header.
         */
        curl_setopt($ch, CURLOPT_HTTPHEADER, 'Expect:');
        // set the URL to Graph API URL
        curl_setopt($ch, CURLOPT_URL, $friend_url);
        // we want header in the output
        curl_setopt($ch, CURLOPT_HEADER, true);
        // but do not display the curl output
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        // execute the curl and get the info
        $response = curl_exec($ch);
        $info = curl_getinfo($ch);
        
        // extract the http code, header and body
        $http_code = $info['http_code'];
        $headers = substr($response, 0, $info['header_size']);
        $body = substr($response, -$info['download_content_length']);
        
        // convert header string into an associate array and extract the ETag
        $headers_arr = http_parse_headers($headers);
        $etag = $headers_arr['Etag'];

        echo '<a href="' . $friend_url . '"/>' . $friend_url . 
                '</a/> <br /><br />';
        echo 'HTTP Code: ' . $http_code . '<br />';
        echo 'ETag: ' . $etag . '<br /><br />';

        /*
         * Execute the same API curl call while passing the
         * ETag value in If-None-Match request header
         */
        echo 'Executing the same API call with request header <br/> 
                <b/>If-None-Match: '. $etag . '</b/> 
                returns : <br/><br/>';
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('If-None-Match: ' . 
                    $etag));
        $result = curl_exec($ch);
        $http_code = curl_getinfo( $ch, CURLINFO_HTTP_CODE );

        echo 'HTTP Code: ' . $http_code . '<br />';

        curl_close($ch);

    }
    echo '</body> </html>';

    /*
     * Function to convert header string into associative array
     * Source - http://php.net/manual/en/function.http-parse-headers.php
     */
     
     function http_parse_headers( $header )
     {
        $retVal = array();
        $fields = explode("rn", preg_replace('/x0Dx0A[x09x20]+/', 
                    ' ', $header));
        foreach( $fields as $field ) {
            if( preg_match('/([^:]+): (.+)/m', $field, $match) ) {
                $match[1] = preg_replace('/(?<=^|[x09x20x2D])./e', 
                        'strtoupper("")', strtolower(trim($match[1])));
                if( isset($retVal[$match[1]]) ) {
                    $retVal[$match[1]] = array($retVal[$match[1]], 
                                $match[2]);
                } else {
                    $retVal[$match[1]] = trim($match[2]);
                }
            }
        }
        return $retVal;
     }
  ?>

Sample Code Output:

https://graph.facebook.com/me/friends?access_token=<access_token>

HTTP Code: 200
ETag: "84a290085a1bb6df44534ac017bfed800c407a15"

Executing the same API call with request header If-None-Match: "84a290085a1bb6df44534ac017bfed800c407a15" returns : 

HTTP Code: 304

Fab Friday: Happy New Year!


Google Geo Developers Blog 6 Jan 2012, 5:02 pm CET

Author Photo

Inspired by Scott Knaster over on the Google Code Blog, I’m starting a new tradition of Fab Friday on the Google Geo Developers Blog. On most Fridays I’m going to post about something cool going on in the world of Google Maps. Nothing formal! So please don’t wear a tie to read my posts.

I’ve got a couple of fun things today. The first one comes from a member of my team, Chris Broadfoot, who put together this great screencast on working with the Styled Maps feature of the Google Maps API:

I also found a cool map you might like. The Domesday Book was the result of a survey in England commissioned by William the Conquerer and completed in 1086. It was a survey of all the landholdings in most of England and parts of Wales. Open Domesday maps this survey. And it also has an API in case you want to play with the data yourself.

Domesday Map Image

I originally found it on Google Maps Mania. I also find cool maps on a variety of sites, including Mapperz and the Google Earth Blog.

Posted by Mano Marks, Maps Developer Relations Team

Announcing In-App Currency Offers


Facebook Developer Blog 6 Jan 2012, 2:00 pm CET

Facebook gives users the ability to earn virtual currency by completing advertiser offers. For app developers, these offers can be a valuable additional source of revenue by helping them monetize users that may not otherwise pay for virtual currency. Today we’re launching in-app currency offers, which lets developers award users with their own in-app currency (e.g., Fred Currency in Fred's game) upon completing an offer.

Previously, developers were able to integrate Credits offers, where users earned Facebook Credits by completing offers. The new in-app currency offers product is in addition to the Credits offers product, and you can utilize either or both in your app.

In-app currency offers supports both Offerwall and Dealspot. An Offerwall implementation enables your app to open a Facebook dialog with an interactive list of advertiser offers. A DealSpot implementation lets you prominently spotlight one offer. For more details, please refer to our offers documentation.

We hope this new product provides you an additional source of revenue, and we look forward to seeing how you incorporate this new functionality into your apps. Please post your questions and feedback in the comments below.

Platform Updates: Operation Developer Love


Facebook Developer Blog 4 Jan 2012, 7:30 pm CET

This past week, we provided an update on our Facebook Platform SDKs, a retrospective of Platform changes in 2011 and launched the following changes:

Stories In Timeline App Tab

Stories published from an app using Feed dialog or Graph API will now show in the app's tab on the user's timeline. This is consistent with Open Graph actions published from an app showing in the app's tab.

Improved Insights for Web Sites

We made two improvements to tracking and reporting Insights for Web sites. We now unpack bit.ly URLs and track and report referrals to the underlying URL. As a result, you will now get accurate referral reporting when you use short bit.ly URLs in Facebook posts. We now also track and report URLs shared and clicked in comments within Insights.

Breaking Changes effective this week

  • Requests 2.0 Efficient: The Request 2.0 Efficient migration will be enabled for all apps over the next few days. Please make sure to update your apps now to respect the updated request ID format to avoid any disruption of service. On January 15th this setting will be set to enabled for all apps. For more information please see the Requests docs.
  • FB.Canvas.getPageInfo: The getPageInfo method now requires a callback function and no longer returns a value synchronously. For more information on this change please see this blog post.

Upcoming Breaking Changes on February 1, 2012

  • Removing canvas_name field from application object: We will be deprecating the canvas_name field in favor of namespace field on the application object. See this blog post for more information.
  • Removing App Profile Pages: We will be deleting all App Profile Pages and redirecting all traffic directly to the App. See this blog post for more information.

Bug activity from 12/27 to 1/3

  • 131 bugs were reported
  • 28 bugs were reproducible and accepted (after duplicates removed)
  • 19 bugs were by design
  • 12 bugs were fixed
  • 56 bugs were duplicate, invalid, or need more information

Reported bugs fixed between 12/27 and 1/3

Activity on facebook.stackoverflow.com this week

  • 133 questions asked
  • 47 answered, 35% answered rate
  • 74 replied, 56% reply rate

Facebook Platform SDK Support


Facebook Developer Blog 30 Dec 2011, 6:00 pm CET

Over the last few weeks, we have had several questions from developers as to which SDKs we support. We wanted to clarify that we provide support for the following:

Please note that we are moving the location of the JavaScript SDK repository from connect-js to facebook-js-sdk and the location of the PHP SDK from php-sdk to facebook-php-sdk. Only the new repositories will be updated moving forward and the old repositories will be made private on April 1, 2012.

Reporting Issues

To report any bugs or issues with any of the above SDKs, please file a report in our Bugs Tool. We apologize for confusion caused by the Issues tabs in GitHub. We do not provide support for this channel and have since removed them from all of our GitHub repositories. We now have a dedicated team of engineers devoted to supporting developers and responding every day to bugs opened via our Bugs Tool

Cookies used by the SDKs

Our JavaScript and PHP SDKs support a common cookie format that allows you to access Facebook Platform from both client and server side code in a seamless fashion. Previously, we documented this cookie format. This resulted in many apps and SDKs taking a dependency on it. We would like to consider this cookie format to be an implementation detail so that we can make changes for security or other reasons, and advise apps not to take a direct dependency on the format. Rather than attempting to parse our cookies, we recommend that you use one of the above supported SDKs or use OAuth endpoints to directly authenticate and authorize users. Our Authentication Guide highlights how to perform authentication and authorization directly.

Deprecated SDKs

Throughout this past year, we have deprecated or removed the below SDKs. The fact that we no longer provide an official Facebook SDK for a given language/runtime, does not mean that you cannot write Facebook apps using those technologies. Rather, all of Facebook Platform (Graph API, Dialogs, etc.) can be accessed from any language or runtime with an HTTP library in a simple and straightforward way. In fact, many of our developers forgo our official SDKs completely and just use HTTP. We are simply deprecating these SDKs based on our need to reduce surface area and provide better support. We have no doubt that the various developer communities will create Facebook SDKs for these platforms over time.

  • Python SDK: The Python SDK is deprecated. We intend on making the GitHub repository private on April 1, 2012.
  • C# SDK: The C# SDK is deprecated. The GitHub repository will be made private on April 1, 2012.
  • Facebook iPhone SDK: This SDK is deprecated and replaced by the iOS SDK. We have made the repository private.

Please leave any questions or feedback in the comments below.

Building Professional Video Sites with YouTube APIs


YouTube API Blog 29 Dec 2011, 11:57 pm CET

Using video on your website can add greater depth and richness for your audience. However, to do encoding, hosting and streaming right it takes some time and skill. If you’re lacking in either, here are some suggestions for sites that make it easy to help you setup video-based websites.
VidCaster is a video content management system, whose goal is to make building a website with video as easy as possible. VidCaster makes use of custom URLs, video sitemaps, metadata, and thumbnails to integrate well with search engines. They provide lots of features to customize your video site, like uploading a logo, picking a theme and choosing custom colors, and you can even upload custom CSS. Using their video management interface, you can publish, unpublish and delete videos. VidCaster can even distribute the videos from your video site to third-party sites such as YouTube and Twitter, and they can also integrate analytics from third-party sources. VidCaster uses OAuth2 with the YouTube API to manage the user’s YouTube account, using both SUP (Simple Update Protocol) and polling to make sure a user’s video site is always in sync with their YouTube channel. Companies that use VidCaster include AirBnB, Hackers and Founders, and Dirtcast.
By integrating closely with YouTube’s data API, VidCaster makes it easy for users to take advantage of YouTube’s video service from within their own custom video site.
Moviecom.tv tries to make it easy for businesses to build video sites about their company. Like VidCaster, Moviecom.tv provides users with a variety of features to customize their video site. They too show videos hosted on YouTube, but their integration with YouTube doesn’t yet include all the features that VidCaster does — for instance, Moviecom.tv can show YouTube videos using the iframe player, but they haven’t yet integrated with YouTube’s data API. This is something they plan on doing early in 2012. Moviecom.tv also touts their mobile application which takes the friction out of recording and uploading video to the right place. And they’re doing well at it — they were recently named a Red Herring Global 100 Winner. Internet World, City Index, and Staples are all example sites created using their platform:
Companies like VidCaster and Moviecom.tv are a welcome part of the online video ecosystem. As Moviecom.tv CEO Gillian O'Neil once noted, Moviecom.tv isn’t competing with YouTube. By enabling third-party video sites to embed YouTube videos, YouTube isn’t trying to get a bigger piece of the pie. They’re making the pie bigger. Cheers, —Shannon -jj Behrens, YouTube API Team

2011 In Review


Facebook Developer Blog 29 Dec 2011, 11:00 am CET

As we near the end of 2011, we wanted to take a moment to recap the highlights from this year. Before doing so, we want to thank you for creating social apps that have delighted millions of users. From games to news, and music, we were excited and impressed by what you created this year. We cannot wait to see what we can build together in 2012.

New Products

We launched many new features that enabled more social and engaging user experiences:

New Tools for Developers

We focused on building new tools to help you develop apps more efficiently:

Transition to a Modern, Secure Platform

2011 was a year that we needed to streamline our Platform to make it more modern and secure. We know these sorts of changes were very painful and impacted many of you, but this was the right move for the ecosystem. We reduced the surface of Platform a great deal, which will enable us to provide better support in the future. These changes included:

Toward a Stable Platform

Late 2010 we first introduced Operation Developer Love and continued our efforts throughout 2011. We heard loud and clear that developers wanted a more stable Platform. As a result, we made the following changes:

In the new year we will continue to be focused on growth for your apps and working together to build social experiences for people across the web and mobile devices. Please post your thoughts in the comments below and keep the feedback coming.

Understanding Playback Restrictions


YouTube API Blog 28 Dec 2011, 10:30 pm CET

Have you ever tried to show a user a YouTube video embedded on your site only to find out that they don’t have access to view it? For instance, if you try to play the video below, it’ll say “This video contains content from test_yt_owner, who has blocked it on copyright grounds.” There are many reasons why video playback can be restricted. The user might be in a country where the video is blocked, or the video’s content owner might have decided to block access to the video from all mobile applications. While we strive to make YouTube content available everywhere, we believe it's important to give YouTube content owners the ability to control where their videos are viewed, which sometimes means you can't view videos in a certain country or on a certain device. With enhanced content controls comes increased complexity. The only foolproof way to determine if a user has access to watch a video is to ask them to try watching it. So, if you’re writing an application and you’d like to prevent users from seeing videos that they don’t have the ability to watch, here are a list of things to check: 1. yt:accessControl Videos that are available for embedding on third-party applications will have the following:
<yt:accesscontrol action='embed' permission='allowed' />
If you’d like to only search for videos that are embeddable, add format=5 to your query. Just as a video can be embeddable or not, it can also be syndicatable or not:
<yt:accesscontrol action='syndicate' permission='allowed' />
A video that is embeddable but not syndicatable will play on YouTube.com or on other sites that embed the YouTube player, but may not play on devices such as mobile phones or TVs. If you’d like to learn more about retrieving videos suitable for playback on mobile devices, see the developer’s guide. 2. Geo Restrictions Some videos may be restricted in certain countries. This restriction applies to where the viewer is located, not where your third-party server is located. For instance, if a video is blocked in the US, it will have the following:
<media:restriction type='country'  relationship='deny'>US</media:restriction>
When you make a query, you can add a restriction parameter to filter videos that will not be playable by a client with a specific IP or from a specific country. 3. yt:state It’s also important to check the yt:state of the video in the API response. Even if yt:accessControl indicates that syndication is allowed, yt:state might override it. For example, a video that has limited syndication would have the following:
<app:control>
<yt:state name='restricted' reasoncode='limitedSyndication'>
Syndication of this video was restricted by its owner.
</yt:state></app:control>
You might also see the message, “Syndication of this video was restricted by the content owner.” Hence, even if the uploader allows syndication, the content owner could override that and disallow syndication. For example, this could happen if someone uploads a video that contains a soundtrack that is owned by another content owner. 4. Rentals Some YouTube videos are rentals. You can tell that they are rentals because they have a media:price tag:
<media:price type='rent' price='1.99' currency='USD' yt:duration='PT2592000S' />
Note that the media:price tag is only included in the response if you use a developer key in the query. If you are building a non-browser based YouTube application where it would be impossible for the user to rent a video, you might want to filter out the rentals. You can do that by passing the parameter paid-content=false. 5. Other Restrictions not Currently Exposed via the API There are even more subtle restrictions that occasionally come into play. Not all of these are currently queryable via the API. For instance, some videos are only playable on a certain set of domains. As I mentioned above, the only foolproof way to know if a user has access to watch a video is to have them try watching it. Going back to the video above, you might be wondering why it won’t play. If you look at its video entry: http://gdata.youtube.com/feeds/api/videos/1kIsylLeHHU?v=2&prettyprint=true you’ll see that it’s blocked in all countries:
<media:restriction type='country' relationship='deny'>
BD BE BF...</media:restriction>
Furthermore, both syndication and embedding are disallowed:
<yt:accesscontrol action='embed' permission='denied' /><yt:accesscontrol action='syndicate' permission='denied' />
Hopefully this short blog post on video playback restrictions will help you write applications that have a better understanding of what videos users can and can’t watch. If you have any questions, you can ask them on our forum. Cheers, —Shannon -jj Behrens, YouTube API Team
More