34

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/search?q=beb090303@hotmail.com&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('beb090303@hotmail.com', $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: search?q=beb090303@hotmail.com&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.

Community
  • 1
  • 1
LihO
  • 37,789
  • 9
  • 89
  • 156
  • 1
    You can't. There is no way to get user id from email address. – WizKid Apr 29 '15 at 12:30
  • @WizKid How come that spokeo.com can do that then? – LihO Apr 29 '15 at 16:14
  • There is nothing in the API to do it. So if they do it they must be doing something against Facebook Platform Policy or Facebook Terms of Service or Facebook Automated Data Collection Terms or all of them. – WizKid Apr 29 '15 at 20:16
  • @WizKid: If it's not supported by FB's API and trully against their policies, then how about Google+ and/or Gravatar? I've gold-plated this with some reputation, will hopefully lure some attention :) – LihO May 01 '15 at 12:56
  • Google are allowed to scrape Facebook as you can see in https://www.facebook.com/robots.txt . Why do think Gravatar can get your fbid from your email? And doesn't matter if you put a bounty on it. It is not possible – WizKid May 01 '15 at 12:59
  • @WizKid Sorry, this is not solely about the user id anymore. This is about how to get profile picture knowing the email address only. – LihO May 01 '15 at 13:05
  • How to do it using gravatar in PHP is explained at http://en.gravatar.com/site/implement/images/php/ – WizKid May 01 '15 at 14:35
  • You can try to use https://www.fullcontact.com/developer/docs/person/ its not very accurate. And basically it's not free. It has trial to try it. – Guntis May 06 '15 at 14:52
  • Do you need to automatically fetch the profile image for a pre-existing list of email addresses? Or do the people, whose profile image you're trying to get, actually use the site/app you are making that would show the profile picture? In case of the latter you could just set up a Facebook login for your site and request the user to authorize your site/app to fetch their basic profile info from Facebook when they first login to your site. – Haprog May 06 '15 at 18:36

5 Answers5

18

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@server.com";
$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.

huysentruitw
  • 25,048
  • 8
  • 76
  • 120
  • 2
    You can also pass `?d=404` to make Gravatar return a 404 if there is not a profile image associated with the email address. This is helpful in determining whether the user has customized their Gravatar image. – Curtis Gibby Mar 28 '16 at 23:05
8

There was a bug: Can't search for user by email after July 2013 Breaking Changes that has been closed as "By Design" with official response:

"The ability to pass in an e-mail address into the "user" search type was removed on July 10, 2013. This search type only returns results that match a user's name (including alternate name)" ~ Joseph Tuấn Anh Phan (Facebook Team)

so probably no direct support from Graph API.

I've tried Graph API Explorer where you can try to play with some FQL too (just need to select version 2.0 as newer versions are not supported anymore), unfortunately query like:

SELECT uid, name FROM user where email = 'some.email@gmail.com'

gives:

"error": {
  "message": "(#604) Your statement is not indexable. The WHERE clause must contain 
   an indexable column. Such columns are marked with * in the tables linked from
   http://developers.facebook.com/docs/reference/fql ", 
  "type": "OAuthException", 
  "code": 604
}

and reference for table user shows that only uid and third_party_id can be used in WHERE.

LihO
  • 37,789
  • 9
  • 89
  • 156
2

You should need access token as well as Facebook id of the user. without knowing them cannot get their profile pic

Thamaraiselvam
  • 6,391
  • 6
  • 39
  • 64
0

I think Spokeo might have an agreement with Facebook to access the data? I would not be surprised.

Anyway, if you are on a profile you can maybe search for profile_id in the HTML. It's a hack, not sure if it works.

Ely
  • 9,920
  • 3
  • 38
  • 60
0

You could always allow people to comment by logging in with their g+/facebook/whatever account (requires you to do something OpenID-like, though); if they've logged in, you should be able to get the facebook uid.

Also, there's something called libravatar, which allows people to associate pictures with their OpenID or email address (and which falls back to gravatar if they haven't configured anything specifically for libravatar); using that should give you more photos than if you stick to "just" gravatar.

Wouter Verhelst
  • 1,089
  • 11
  • 25