Optimize Facebook Graph API Queries with Real-Time Updates

    Applications for Facebook can have diverse functionality: for example, often the application will have enough information received through the API while the user is working with the application. But what if your application should work with the most recent user data, even if they have not opened it for more than a month?

    There are two ways to receive data not only while the user is working with the application:
    1. Get offline_access permission from the user (save the “eternal” user access_token) and receive the necessary data “according to the schedule” (pull the cron script).
    2. Write a script that will receive all data changes from Facebook, configure and subscribe to updates through Real-Time Updates.

    Under the cat, you will learn a virtual example of how using real-time updates helps reduce the number of API requests per day by more than 100 times in some situations. We will write a script for subscribing to updates and check its operation, receiving data on the change of objects from Facebook itself.

    At the beginning of the article contains a lot of theory, which is similar to the Russian translation of the documentation page from Facebook. If it’s easier for you to read in English, you can skip everything in the Second method to the section Example of Real-Time Updates . But for some reason, after the first reading, I was unable to configure this functionality. I hope this article helps you figure this out faster.

    First way


    The functionality of some applications may be related to the need to receive data on a schedule. For example, you collect statistics on the number of page likes from a specific directory. To do this, you receive data at intervals of once an hour. This is a good use case; otherwise, you simply won’t get this data. But often this method is also used for objects where updates can be received not “on schedule” but real-time from Facebook itself.

    Of the serious disadvantages of the first method, the following can be distinguished:
    • The less frequently data is checked, the less reliable it is.
    • High resource costs with frequent updates.
    • Users are reluctant to allow offline_access - access to their data at any time.

    Imagine that you have made an application whose functionality is tied to the user's friends, and it is very important for you to have the latest information. Let's say your application has been installed by 1000 users. And let 1 hour be the acceptable caching time for friend data. As a result, every day you will send 24,000 requests so that your database of user friends is up to date! And you have only 1000 users, and we can assume that there will be no more than a couple of hundred changes in friends for everyone in a day (well, this is a guess based on personal experience).

    To solve the shortcomings of the first method, Facebook made Real-Time Updates for its Graph API.

    Second way


    Support for real-time updates allows your application to subscribe to changes in data on Facebook. Your application receives updates from Facebook and saves data, instead of polling Facebook servers “on schedule”. Caching data and using this API can improve the reliability of the application and reduce its loading time. Whenever a change to which you are subscribed occurs, Facebook makes an HTTP POST request to the data update processing script with a list of changes. The server will send you a notification of the change within a couple of minutes after it appears.

    The objects

    At the moment, you can subscribe to the following types of objects:
    • user - receive notifications about specific fields and user relationships with the corresponding Graph API nodes. *
    • permissions - Receive notifications when a user changes permissions for your application.
    • page - to receive notifications when the pages that have added (installed) your application change their general properties.

    * Not all properties and relationships of the User object you can subscribe to. For example, links are available to you: feed, friends, activities, interests, music, books, movies, television, likes, checkins. But at the same time, you cannot yet subscribe to changes in these links: home, tagged, posts, photos, albums, videos, groups, notes, events, inbox, outbox, updates, accounts

    Subscription

    In order to set up a subscription to updates, you need:
    1. Set up a script (URL) that will receive both HTTP GET (for verification of the subscription) and POST (about changing data) requests from Facebook.
    2. Make a POST request to Graph API
      https://graph.facebook.com// subscriptions
      to subscribe, and be prepared to process a verification request.

    By sending a request to
    https://graph.facebook.com// subscriptions? access_token = ...
    You can do three things, depending on which HTTP POST, GET, or DELETE request you send:
    1. Add and change subscription (POST).
    2. Get a list of all objects as well as their fields that you subscribed to (GET)
    3. Delete Subscription (DELETE)

    The request must include the access_token application, which can be obtained using your application ID (app-id) and application secret key (app-secret). Just send an HTTP GET
    https://graph.facebook.com/oauth/access_token?client_id=& client_secret =& grant_type = client_credentials
    and the answer will come: access_token = ...

    Adding and changing a subscription

    So, you read above where you need to send a request to add a subscription. Do not rush to immediately fulfill these requests - the structure of the presentation of the material is not the same as the sequence of necessary steps. This is done specifically to study the material sequentially. But in the example, you will be the first to fulfill the queries that are described in the last part before the example.


    An application can have only one subscription for each of the possible types of objects. If you add an object that already has a subscription, the existing subscription will be replaced with a new one. To add or change a subscription, you must send a POST request containing the fields:
    • object - object type: user, permissions or page. You will monitor all objects of this type, for example, all users of your application.
    • fields - The list (elements separated by commas) of the properties and relationships of the selected object. For example, to monitor changes in the name, picture, friends fields of the user, as well as the News Feed link, you must specify the value “name, picture, friends, feed”
    • callback_url - The URL to which Facebook will post changes to which the application is subscribed.
    • verify_token is the “secret code” that you set in order to verify the authenticity of the request. It will be passed to the subscription processing script.

    Getting a list of all objects and their fields that you subscribed to
    By making a GET request to the subscription URL
    https://graph.facebook.com// subscriptions? access_token = ...
    You will receive a response with JSON-encoded content that lists your subscriptions. I subscribed to the friends connection of the user object, as well as offline_access in permissions. Here is the answer:
    {
      "data": [
         {
            "object": "user",
            "callback_url": "http://millione.tv/<path to script>",
            "fields": [
               "friends"
            ],
            "active": true
         },
         {
            "object": "permissions",
            "callback_url": "http://millione.tv/<path to script>",
            "fields": [
               "offline_access"
            ],
            "active": true
         }
      ]
    }
    

    Delete Subscription

    To delete an entire subscription to all objects, send a DELETE request. If you want to unsubscribe from a specific object, specify the object parameter (for example, object = user).

    Your callback server


    Facebook servers make an HTTP GET request to your callback_url when you try to add or modify a subscription. After a successful subscription, Facebook servers will send change notifications using HTTP POST to the same URL.

    Subscription Verification

    Before the subscription is finally added or modified, Facebook servers will make an HTTP GET on your callback_url with the following parameters:
    • hub.mode - The string 'subscribe' is passed in this parameter.
    • hub.challenge - Random string.
    • hub.verify_token is the “secret code” that you set in order to verify the authenticity of the request that you submitted to Facebook.

    The script for processing data updates should first check the value of hub.verify_token - the “secret code” that you transmitted to Facebook, and then return the hub.challenge parameter back. This is done specifically to protect the script as a means of conducting a DDoS attack on the server.
    Note for developers: In PHP, a period is automatically converted to an underscore in parameters. Therefore, you must refer to $_GET["hub_mode"], $_GET["hub_challenge"]and $_GET["hub_verify_token"].

    Change Notifications

    When the data changes, and there is a valid subscription, Facebook servers make an HTTP POST request for the callback_url that you specified. The request content type will be application / json; body - JSON-encoded string containing information about one or more changes. An example can be seen below in the application code.

    It should be noted that the line will not contain data on the current value. Therefore, you will need to make a regular request to the API to receive them (due to security policy). You can download the necessary data immediately so that the user, returning to the application, does not experience complications with an increase in download time.

    Facebook aggregates the changes and sends them in batches every 5 seconds, or if the number of changes has exceeded 1000. In the case when the change notification was not delivered to you, Facebook will try again, and then a little later, reducing the frequency of requests in the next 24 hours.

    Real-Time Updates Work Example


    We put theory into practice. To do this, you will need hosting, a PHP script that will be located on your domain at the specified address callback_url. You will also need a Facebook app. You can use the existing one, or create a new one on the developer’s application page .

    1. Application



    2. The script for processing data updates

    Save the script for callback_url
     
    / * Note the request must complete within 15 seconds.
    Otherwise Facebook server will consider it a timeout and
    resend the push notification again. * /
     
    define ('VERIFY_TOKEN', '');
    $ method = $ _SERVER ['REQUEST_METHOD'];
     
    if ($ method == 'GET' && $ _GET ['hub_mode'] == 'subscribe'  
                         && $ _GET ['hub_verify_token'] == VERIFY_TOKEN) {
       echo $ _GET ['hub_challenge'];
    } else
       if ($ method == 'POST') {
           $ data = file_get_contents ("php: // input");
           $ fh = fopen ('data.txt', 'a') or die ('open file');
           if (-1 == fwrite ($ fh, $ data)) {die ('write data'); }
           fclose ($ fh) or die ('close file');
       }
     
    ?>


    3. Add a subscription

    After that, we will use the new tool for Facebook developers - Graph API Explorer .


    Select a POST request to add a subscription and fill in all the fields. To get access_token (applications), open a link in the browser, filling in the app-id and app-secret with the data of your application.
    https://graph.facebook.com/oauth/access_token?client_id=& client_secret =& grant_type = client_credentials

    The path to the script can be facebook / callback.php for example. It is important that you take the app-secret from the application settings, and you create the secret code in verify_token yourself!

    So, if nothing happened after clicking Submit in the gray box below, it means you still added a subscription to the friends connections of the user object, and now, as soon as any user of your application adds or removes one of their friends, Facebook will send a notification to callback_url . In my example, I added a subscription also to the offline_access permissions object.

    4. Create user activity

    If your application has been installed, it's okay. If not, too. The sequence of actions is the same.

    First you need to add the offline_access permission. If the application has not been installed, this will happen automatically. My application is not installed. I will try to call the authorization window through the browser line. Open the link by replacing app-id with the id of your application and replacing site-url with http: // <your domain>:
    https://www.facebook.com/dialog/oauth?client_id=& redirect_uri =& scope = offline_access



    After successful authorization, Facebook will redirect you to http: // <your domain> /? Code = ...

    According to the logic contained in the script - when processing an incoming notification, we simply add the transmitted JSON-encoded line to the text file data.txt, which will be located in the same directory as the script. Check if this file was created and what information it contains.

    My added information looks like this:
    {"object":"permissions","entry":[{"uid":"100001828786121","id":"100001828786121","time":1310669052,"changed_fields":["connected"]},{"uid":"100001828786121","id":"100001828786121","time":1310669052,"changed_fields":["offline_access"]}]}

    As you can see, I installed the application and allowed offline_access permission. By uid you can determine the user whose data has changed, and by time - the time of addition.

    5. Delete actions

    You can go to the application settings on Facebook, open your application and remove the offline_access permission. In the data.txt file, you will see that you are again sent a notification. You can also add or remove one of your friends - you will see that these notifications that you subscribed to will come to callback_url and will be processed by your script.

    conclusions

    Now you know about the wonderful feature of Facebook Real-Time Updates, which can send you information about changes in user data and permissions. Unfortunately, for some reason, when the user deleted the application, the data did not change. Therefore, as if the new method did not save time and resources - nevertheless, when implementing certain tasks (for example, sending mailing to all users of the application), it is still worthwhile to preliminarily go through all the users in your database through the regular API, checking if they have your application installed .

    Also popular now: