Workaround to Facebook’s Graph API Search locale change

No Gravatar

So Facebook decided to change the meaning of the locale parameter to the search parts of the Graph API – and label the decision “by design” after 2 months of thinking. Not “design change” or “bug we don’t feel like fixing” – just “If it worked before – that was a mistake”. The handling of the problem is described in this bug-report.

If you do not use it, you probably don’t care, but if you do this would probably be fatal to your searches.

The problem

I would like to know what Facebook users in my country (Denmark) writes about my local branch of the phone company Telia. To find out, I would ask the graph:

https://graph.facebook.com/search?q=Telia&locale=da_DK

The locale-parameter would ensure that I only get results from danish Facebook sources. At least that was the case until December 5, 2012. After that, the locale-parameter changed role – now it will just localize certain field identifiers in the JSON reply. This is useless and all of a sudden I get heaps of irrelevant results from users in other countries in other languages. Facebook remains silent about what to do instead.

The workaround

For my projects I’ve used the following workaround – it’s Q&D, ugly and it takes up unnecessary resources, both for my own service and for Facebook, but it has been tested to work. One known drawback – if the same Facebook user mentions our search term more than once, only the last one is returned.

First – perform the search as always – in simple PHP (make sure to add your own validations):

<?php
$searchterm = 'telia';
$geturl = "http://graph.facebook.com/search?q=" . urlencode($searchterm) . "&type=post";
$fb_reply = file_get_contents($geturl, 0, null, null);
$fb_arr = json_decode($fb_reply, TRUE);
$reply_data = $fb_arr['data'];

Now $reply_data contains an array of posts – something like:

Array
(
 [0] => Array
 (
   [id] => 10002333417237_486897434763199
   [from] => Array
   (
     [name] => some name
     [id] => 100027398117237
   )
  [message] => Missing home
...

Look at the [from]-section to figure out who posted the message. Actually you are going to need all the from->id’s from all posts in the reply from Facebook. Why? Because you want to extract the senders locale and filter out any posts that does not match the locale you require. I use something like this to create an array of Facebook uid’s:

$users = array();
foreach ($reply_data as $pkey => $post) {
 $uid = $post['from']['id'];
 $users[$uid] = $pkey;
}

Next we ask Facebook about the users using FQL. Actually we only want to know about users if they have our locale:

$FQL = sprintf("SELECT uid, name, locale FROM user WHERE uid IN (%s) AND locale = 'da_DK';", implode(array_keys($users), ','));
$fql_query = "http://graph.facebook.com/fql?q=" . urlencode($FQL);
$fql_result = file_get_contents($fql_query, 0, null, null);
$fql_users = json_decode($fql_result, TRUE);

Now $users is a one-to-one mapping from users to matching posts, we’ll “join” the filtered user list with the $users-array and have – a list of posts from users with the requested locale:

$valid_posts = array();
foreach($fql_users['data'] as $dk_user) {
 $uid = $dk_user['uid'];
 $postkey = $users[$uid];
 $valid_posts[] = $reply_data[$postkey];
}

The $valid_posts-array now contains posts matching the needed locale – somewhat like before December 5th 2012.

Conclusion

I wonder why Facebook took the decision they did. It is just asking for workarounds like this. Now instead of one Facebook Graph request I will make two AND Facebook gets to send me a lot more data than I need. The data is still public (for now anyway) – let’s see if it stays that way.

Posted in Facebook, PHP, Tips Tagged with: , , , , , ,
4 comments on “Workaround to Facebook’s Graph API Search locale change
  1. JorgeNo Gravatar says:

    I have also made the same Q&D php :-)
    But this “solution” is incomplete for me because you can get the locale field from a user but you can’t get it from a page. Do you know a way to get the locale or the language for a Facebook page_id?

    Thanks in advance

  2. BotacticNo Gravatar says:

    Hello,

    What about selector “since”? Should I add “&since=1dayago” to the 1st query in variable $geturl?

    I mean:
    $geturl = “http://graph.facebook.com/search?q=” . urlencode($searchterm) . “&type=post&since=1hourago”;

    Doesn’t work … :/

  3. Jens Ulrik LangeNo Gravatar says:

    Thinking that this could probably be improved a lot using FQL Multiqueries somehow.

    @Jorge: Haven’t tried that. The graph says (for example):

    {
    “about”: “SOMMERENS FESTIVAL I TISVILDELEJE d. 18. juli – 20. juli 2013. Koncerterne leveres af kendte og upcoming kunstnere. SEND VIDERE TIL DINE VENNER”,

    “is_published”: true,
    “location”: {
    “street”: “Hovedgaden 114″,
    “city”: “Tisvildeleje”,
    “state”: “”,
    “country”: “Denmark”,
    “zip”: “3220”,
    “latitude”: 56.058267059896,
    “longitude”: 12.06385917591
    },
    “mission”: “SPIL PÅ MUSIK I LEJET 18. – 20. JULI 2013\nSend din musik på spilpaa@musikilejet.dk, så vurderer …
    }

    Where the location->country (if defined) would make sense to use – but I guess not all pages has a location – and a location is not exactly the same as a locale.

    @Botactic: Sounds odd. Have not done that recently but just tried typing http://graph.facebook.com/search?q=thorning&type=post&since=1minuteago in my browser. It worked without problems for me.

  4. botacticNo Gravatar says:

    Hello, so how can i get information from pages and fanpages in this solution? I compared the graph with this solution and the graph has more results, i mean results form FPs and Pages.

    Any ideas?

1 Pings/Trackbacks for "Workaround to Facebook’s Graph API Search locale change"
  1. […] Facebook Busted Its API “By Design:” Here’s the Workaround […]

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>