32

I have an email address and want to find out if there is a Facebook user linked to this address. If there is, then I want to retrieve the url to this users profile page and save it somewhere. I do not have a facebook application, but, if necessary, I would use existing account data to login to facebook and perform the task.

I thought this would be an easy task, but somehow it's not. I read through the Graph API documentation and there you find instructions on how to search public data. It says the format is:
https://graph.facebook.com/search?q=QUERY&type=OBJECT_TYPE

But trying this with an email address in the q param and user in the type param without further information results in an OAuthException saying "An access token is required to request this resource." However, if you click the example search links Facebook generates a url with the mentioned access token related to the currently logged on user. Performing searches with this token gives the expected results. But i cannot figure out how to get this user session access token after logging in. Every time I search on how to get an access token I only find information regarding Facebook apps and retrieving permissions for basic or specific data access. This is, as I mentioned, not what I am looking for, as I don't have and don't need a facebook app.

Since Facebook gives me the needed token in the example links I thought it shouldn't be a problem to get it too. Or do they only have it because of home advantage? Also, the Outlook Social Connector Provider for Facebook is able to retrieve Facebook data just via an email address (and the account data provided). So I thought, if Microsoft can do this stuff I should be also possible to do simliar things.

Last but not least this is the more frustrating since I, theoretically and practically, am already able to find users profile url just by searching for the email address. I don't even have to be logged on to Facebook. And it's not the official API way.
If I perform a web request to http://www.facebook.com/search.php?init=s:email&q=example@domain.com&type=users I get the expected search result. The problem is that I have to parse the HTML code and extract the url (that's okay) and that the result page is possibly subject to change and could easily break my method to extract the url (problematic).

So does anybody has an idea what's the best way to accomplish the given task?

bkaid
  • 51,465
  • 22
  • 112
  • 128
Andreas Adler
  • 771
  • 1
  • 9
  • 16
  • I'm putting a bounty on this question. Screen scraping just can't be the right answer. In my case, I do have a Facebook app ID, but I don't appear to be able to use my app's access token; I have to use the access token for a user (e.g. my personal account) which I really don't want to do for my high-volume Facebook app! – Dan Fabulich Sep 13 '11 at 22:40
  • 1
    There's a filed bug that query-by-email doesn't work for application access tokens; it only works for user (real human) access tokens. https://developers.facebook.com/bugs/167188686695750 – Dan Fabulich Sep 19 '11 at 20:25
  • 1
    Another filed bug makes it sound like they've deliberately disabled query-by-email: https://developers.facebook.com/bugs/453298034751100 – Owen Blacker Jul 29 '13 at 14:34
  • FQL will no longer be available: https://developers.facebook.com/docs/reference/fql/?locale=en_US – Taras Melnyk Mar 19 '19 at 08:39

11 Answers11

16

The definitive answer to this is from Facebook themselves. In post today at https://developers.facebook.com/bugs/335452696581712 a Facebook dev says

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).

So, alas, the simple answer is you can no longer search for users by their email address. This sucks, but that's Facebook's new rules.

Dave Sag
  • 13,266
  • 14
  • 86
  • 134
7

Simply use the graph API with this url format: https://graph.facebook.com/search?q=zuck@fb.com&type=user&access_token=... You can easily create an application here and grab an access token for it here. I believe you get an estimated 600 requests per 600 seconds, although this isn't documented.

If you are doing this in bulk, you could use batch requests in batches of 20 email addresses. This may help with rate limits (I am not sure if you get 600 batch requests per 600 seconds or 600 individual requests).

Community
  • 1
  • 1
bkaid
  • 51,465
  • 22
  • 112
  • 128
  • I wouldn't want to do it in a way that isn't approved by Facebook. (What if they start blocking our IP addresses?) – Dan Fabulich Sep 14 '11 at 16:09
  • 2
    Searching on email via the Graph API is definitely allowed. The only reason I used several access tokens was because I was impatient with the rate limit. If you stay within your rate limit (or if you exceed the limit, wait a few minutes before trying again) you will have no issue. – bkaid Sep 14 '11 at 16:12
  • 3
    1) Fake accounts are absolutely not allowed. 2) Temporary applications don't work; you can't use an application access_token for this Graph API query. You have to use a real human's access_token. 3) Circumventing the rate limit by switching between your friends accounts is allowed, but will get you and your friends accounts temporarily blocked for up to 24 hours. (I state this from experience.) That's why my bounty is to find a better way. – Dan Fabulich Sep 15 '11 at 17:52
  • Could also try batch requests then. Your options are 1) screen scraping (against TOS), 2) using the API within its (unpublished) rate limits, or 3) using the API and skirting around its rate limits. What other possible ways could you imagine? – bkaid Sep 15 '11 at 23:24
  • My earlier comments are now obsolete since you edited your answer, but the answer as written is still incorrect. If you create an application and use its access token with the URL you provide, you'll get an error: "A user access token is required to request this resource." Application access tokens are not allowed; you have to use a real human's access token. That's because query-by-email is not for apps; it's for finding friends. Hence, it may not be legit to impersonate humans for this at all; it's not really a human's request. – Dan Fabulich Sep 19 '11 at 20:21
  • Separately, you raise a good point that this problem may not be solvable. My hope was that somebody would say: "If you do the query like this, it'll work" (FQL? Old REST API? Magic?) But if it's impossible, then I agree, I'll have to consider my other options. – Dan Fabulich Sep 19 '11 at 20:23
  • 3
    It looks like Facebook has removed the ability to find-by-email with user access tokens recently. – tiegz Jan 25 '12 at 19:27
7

In response to the bug filed here: http://developers.facebook.com/bugs/167188686695750 a Facebook engineer replied:

This is by design, searching for users is intended to be a user to user function only, for use in finding new friends or searching by email to find existing contacts on Facebook. The "scraping" mentioned on StackOverflow is specifically against our Terms of Service https://www.facebook.com/terms.php and in fact the only legitimate way to search for users on Facebook is when you are a user.

Dan Fabulich
  • 37,506
  • 41
  • 139
  • 175
6

Maybe this is a little bit late but I found a web site which gives social media account details by know email addreess. It is https://www.fullcontact.com

You can use Person Api there and get the info.

This is a type of get : https://api.fullcontact.com/v2/person.xml?email=someone@****&apiKey=********

Also there is xml or json choice.

oneNiceFriend
  • 6,691
  • 7
  • 29
  • 39
3

I've captured the communication of Outlook plugin for Facebook and here is the POST request

https://api.facebook.com/method/fql.multiquery
access_token=TOKEN&queries={"USER0":"select '0', uid, name, birthday_date, profile_url, pic, website from user where uid in (select uid from email where email in ('EMAIL_HASH'))","PENDING_OUT":"select uid_to from friend_request where uid_from = MY_ID and (uid_to IN (select uid from #USER0))"}

where
TOKEN - valid access token
EMAIL_HASH - combination of CRC32 and MD5 hash of searched email address in format crc32_md5
MY_ID - ID of facebook profile of access token owner

But when I run this query with different access token (generated for my own application) the server response is: "The table you requested does not exist" I also haven't found the table email in Facebook API documentation. Does Microsoft have some extra rights at Facebook?

Jan Zahradník
  • 2,417
  • 2
  • 33
  • 44
1

This is appeared as pretty easy task, as Facebook don't hiding user emails or phones from me. So here is html parsing function on PHP with cURL

/*
    Search Facebook without authorization
    Query
        user name, e-mail, phone, page etc
    Types of search
        all, people, pages, places, groups, apps, events
    Result
        Array with facebook page names ( facebook.com/{page} )
    By      57ar7up
    Date    2016
*/
function facebook_search($query, $type = 'all'){
    $url = 'http://www.facebook.com/search/'.$type.'/?q='.$query;
    $user_agent = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.109 Safari/537.36';

    $c = curl_init();
    curl_setopt_array($c, array(
        CURLOPT_URL             => $url,
        CURLOPT_USERAGENT       => $user_agent,
        CURLOPT_RETURNTRANSFER  => TRUE,
        CURLOPT_FOLLOWLOCATION  => TRUE,
        CURLOPT_SSL_VERIFYPEER  => FALSE
    ));
    $data = curl_exec($c);

    preg_match_all('/href=\"https:\/\/www.facebook.com\/(([^\"\/]+)|people\/([^\"]+\/\d+))[\/]?\"/', $data, $matches);
    if($matches[3][0] != FALSE){                // facebook.com/people/name/id
        $pages = array_map(function($el){
            return explode('/', $el)[0];
        }, $matches[3]);
    } else                                      // facebook.com/name
        $pages = $matches[2];
    return array_filter(array_unique($pages));  // Removing duplicates and empty values
}
57ar7up
  • 403
  • 8
  • 16
  • Using exactly what you have above with `$results = facebook_search( 'e-mail', 'people' );` and `var_dump( $results );` I get a valid response. I'm not seeing where you specify the e-mail, phone, etc. though. Could you share? – ScottD Sep 07 '16 at 20:47
1

Andreas, I've also been looking for an "email-to-id" ellegant solution and couldn't find one. However, as you said, screen scraping is not such a bad idea in this case, because emails are unique and you either get a single match or none. As long as Facebook don't change their search page drastically, the following will do the trick:

final static String USER_SEARCH_QUERY = "http://www.facebook.com/search.php?init=s:email&q=%s&type=users";
final static String USER_URL_PREFIX = "http://www.facebook.com/profile.php?id=";

public static String emailToID(String email)
{
    try
    {
        String html = getHTML(String.format(USER_SEARCH_QUERY, email));
        if (html != null)
        {
            int i = html.indexOf(USER_URL_PREFIX) + USER_URL_PREFIX.length();
            if (i > 0)
            {
                StringBuilder sb = new StringBuilder();
                char c;
                while (Character.isDigit(c = html.charAt(i++)))
                    sb.append(c);
                if (sb.length() > 0)
                    return sb.toString();
            }
        }
    } catch (Exception e)
    {
        e.printStackTrace();
    }
    return null;
}

private static String getHTML(String htmlUrl) throws MalformedURLException, IOException
{
    StringBuilder response = new StringBuilder();
    URL url = new URL(htmlUrl);
    HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
    httpConn.setRequestMethod("GET");
    if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK)
    {
        BufferedReader input = new BufferedReader(new InputStreamReader(httpConn.getInputStream()), 8192);
        String strLine = null;
        while ((strLine = input.readLine()) != null)
            response.append(strLine);
        input.close();
    }
    return (response.length() == 0) ? null : response.toString();
}
sakibmoon
  • 2,026
  • 3
  • 22
  • 32
Zach-M
  • 2,127
  • 18
  • 12
0

First I thank you. # 57ar7up and I will add the following code it helps in finding the return phone number.

function index(){
    // $keyword = "0946664869";
    $sql = "SELECT * FROM phone_find LIMIT 10";
    $result =  $this->GlobalMD->query_global($sql);
    $fb = array();
    foreach($result as $value){
        $keyword = $value['phone'];
        $fb[] = $this->facebook_search($keyword);
    }
    var_dump($fb);

}

function facebook_search($query, $type = 'all'){
    $url = 'http://www.facebook.com/search/'.$type.'/?q='.$query;
    $user_agent = $this->loaduserAgent();

    $c = curl_init();
    curl_setopt_array($c, array(
        CURLOPT_URL             => $url,
        CURLOPT_USERAGENT       => $user_agent,
        CURLOPT_RETURNTRANSFER  => TRUE,
        CURLOPT_FOLLOWLOCATION  => TRUE,
        CURLOPT_SSL_VERIFYPEER  => FALSE
    ));
    $data = curl_exec($c);
    preg_match('/\&#123;&quot;id&quot;:(?P<fbUserId>\d+)\,/', $data, $matches);
    if(isset($matches["fbUserId"]) && $matches["fbUserId"] != ""){
        $fbUserId = $matches["fbUserId"];
        $params = array($query,$fbUserId);
    }else{
        $fbUserId = "";
        $params = array($query,$fbUserId);
    }
    return $params;
}
Asdrubal
  • 2,421
  • 4
  • 29
  • 37
0

WARNING: Old and outdated answer. Do not use


I think that you will have to go for your last solution, scraping the result page of the search, because you can only search by email with the API into those users that have authorized your APP (and you will need one because the token that FB provides in the examples has an expiry date and you need extended permissions to access the user's email).

The only approach that I have not tried, but I think it's limited in the same way, is FQL. Something like

SELECT * FROM user WHERE email 'your@email.com'
Manuel Pedrera
  • 5,347
  • 2
  • 30
  • 47
  • 1
    Thanks for the answer. But it's still not what I'm looking for. For my scenario it's okay when the token expires after some time. I only need it for a quick search, just to see wheter Facebook finds a user with this email or not. So using this limited session token would be fine. And as mentioned above, the Outlook Facebook Connector is somehow able to do exactly what I want to do (login with provided credentials and fetch user data based on a given email address). Regarding the FQL approach: This doesn't work since the email field isn't indexed and therefor not queryable. – Andreas Adler Mar 09 '11 at 11:11
  • Marked as answer because I asked what would be the best way for this task and the approach of scraping the search result is indeed the simplest way for this. At least it was for me. – Andreas Adler Mar 11 '11 at 14:33
  • 1
    FQL is deprecated after v2.1 :( – Iván Guillén Sep 15 '14 at 18:06
0

Facebook has a strict policy on sharing only the content which a profile makes public to the end user.. Still what you want is possible if the user has actually left the email id open to public domain.. A wild try u can do is send batch requests for the maximum possible batch size to ids..."http://graph.facebook.com/ .. and parse the result to check if email exists and if it does then it matches to the one you want.. you don't need any access_token for the public information ..

in case you want email id of a FB user only possible way is that they authorize ur app and then you can use the access_token thus generated for the required task.

mjs
  • 657
  • 7
  • 14
  • 1
    This answer is incorrect. Facebook will give out your UID to anyone who already knows your email address, even if you mark your email address as private. (The reverse is not true: if I only know your UID, I can't access your private email address.) You just have to query like this, using a user access token: https://graph.facebook.com/search?q=zuck@fb.com&type=user&access_token= My problem is that I want to use my application's access token, or no token at all. – Dan Fabulich Sep 19 '11 at 20:46
  • you cannot use just about any access_token here.. i tried using my applications access_token here and got OAuthException.. – mjs Sep 20 '11 at 07:05
  • you used to be able to do this with a user access token, but Facebook removed this recently (including the old "Find Friends" page) – tiegz Jan 25 '12 at 19:28
0

Maybe things changed, but I recall rapleaf had a service where you enter an email address and you could receive a facebook id.
https://www.rapleaf.com/

If something was not in there, one could "sign up" with the email, and it should have a chance to get the data after a while.

I came across this when using a search tool called Maltego a few years back.
The app uses many types of "transforms", and a few where related to facebook and twitter etc..

..or find some new sqli's on fb and fb apps, hehe. :)

EO2
  • 364
  • 1
  • 7