Search code examples
phpfacebookdownloadprofile-picture

Retrieving Facebook / Google+ / Linkedin profile picture having email address only


What I need

I need to automatically find & download profile picture for user knowing his email address only. Originally, I focused on Facebook considering the amount of people actively using it. However, there seem to be no direct support from their API anymore.

There was similar question here: How to get a facebook user id from the login email address which is quite outdated and current answers there are "it's deprecated" / "it's not possible"... EDIT: I've found even better question: Find Facebook user (url to profile page) by known email address (where it is actually explained why and since when this feature isn't supported)

There must be a way...

What makes me think that this should be possible is that Spokeo is somehow doing it: http://www.spokeo.com/email-search/search?e=beb090303%40hotmail.com

There are some services / APIs offering this kind of feature:
Clearbit
Pipl
...but I haven't found anything free.

Alternatives

If there is some workaround or different approach than using Facebook's API to achieve this, I would like to know. If Facebook is really completely hopeless here, then combination of these: Google+, Linkedin and/or Gravatar could do.


My first (original) attempt:

Once you have Facebook's username or user ID, it's easy to build URL to download the picture. So I was trying to look for Facebook's user IDs using emails with the /search Graph API:
https://graph.facebook.com/[email protected]&type=user&access_token=TOKEN

which unfortunatelly always ends with "A user access token is required to request this resource."

Using FB PHP API + FB App ID & Secret

I've also tried this: at first I retrieve access_token using app ID and secret and then I'm trying to use it as a part of /search request with curl:

function post_query_url($url, $data) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    $res = curl_exec($ch);
    curl_close($ch);
    return $res;
}

function get_query_url($url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_POST, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    $ret = curl_exec($ch);
    curl_close($ch);
    return $ret;
}

function get_retrieve_app_access_token($app_id, $secret) {
    $url = 'https://graph.facebook.com/oauth/access_token?client_id='.$app_id.'&client_secret='.$secret.'&grant_type=client_credentials';
    $res = get_query_url($url);
    if (!empty($res)) {
        $tokens = explode('=', $res);
        if (count($tokens) == 2)
            return $tokens[1];
    }
    return null;
}

function post_retrieve_app_access_token($app_id, $secret) {
    $url = 'https://graph.facebook.com/oauth/access_token';
    $data = 'client_id='.$app_id.'&client_secret='.$secret.'&grant_type=client_credentials';
    $res = post_query_url($url, $data);
    if (!empty($res)) {
        $tokens = explode('=', $res);
        if (count($tokens) == 2)
            return $tokens[1];
    }
    return null;
}

function get_id_from_email($email, $accessToken) {
    $url = 'https://graph.facebook.com/search?q='.urlencode($email).'&type=user&access_token='.$accessToken;
    $res = get_query_url($url);
    if (!empty($res)) {
        return $res;
    }
    return null;
}

echo 'Retrieving token...<br>';

$token = post_retrieve_app_access_token('MY_APP_ID', 'SECRET');
echo 'Retrieved token: ' . $token . '<br>';

echo 'Retrieving user ID...<br>';
$id = get_id_from_email('[email protected]', $token);
echo 'Retrieved ID: ' . $id . '<br>';

outputs something like:

Retrieving token...
Retrieved token: 367458621954635|DHfdjCnvO243Hbe1AFE3fhyhrtg
Retrieving user ID...
Retrieved ID: {"error":{"message":"A user access token is required to request this resource.","type":"OAuthException","code":102}}

Other info

Since it's asking for "user access token", I've also tried to go to Facebook's Graph Explorer: https://developers.facebook.com/tools/explorer/ let it generate access token for me and queried: [email protected]&type=user&debug=all That one ends with:

{
  "error": {
    "message": "(#200) Must have a valid access_token to access this endpoint", 
    "type": "OAuthException", 
    "code": 200
  }
}

...so Facebook seems kinda hopeless here.


Solution

  • That's exactly why Gravatar exists and why people use Gravatar, users know which public profile image they bind to which e-mail address and they know where to change it.

    Your app can have the possibility for users to upload their own profile image and fallback to Gravatar.

    If you just try to extract an image from Facebook or Google+, it might freak your users out and it will also be harder for them to know where your service got the profile image from.

    Using Gravatar in PHP it is as simple as this:

    <?php
    $email = "[email protected]";
    $default = ""; // absolute url to default image goes here or leave empty for default gravatar image
    $size = 200;
    
    $grav_url = "http://www.gravatar.com/avatar/" . md5(strtolower(trim($email))) . "?d=" . urlencode($default) . "&s=" . $size;
    
    header("content-type: image/jpeg");
    echo file_get_contents($grav_url);
    ?>
    

    Apart from that, you can also use Facebook and/or Google+ as external login providers where users can grant your application access to their profile information.