locked
How retrieve user's contacts' email address RRS feed

  • Question

  • Hello, I have a problem to get the contacts' email address.

    After I get Access Token, I use https://apis.live.net/v5.0/me/contacts?access_token=ACCESS_TOKEN  to get all contacts of this user.

    But, I can only get Names, email hashes etc. but not the email address. I have set the scope to wl.basic, wl.signin, wl.email.

    I guess this might be a policy which is the same as what Facebook does.

    But, I'm curious how this website can access the contacts' emails? http://svetlozar.net/address-book-importer-demo.html

    Can you please give me some advise?

    Thanks a lot.

    Regards,

    Bin

     

     

    Monday, January 30, 2012 11:23 PM

Answers

  • Hi Simon,

     

    Thank you very much for your detailed explanation.

    And can I have another question?

    So, as you mentioned, Microsoft doesn't officially allow APP or Website to get all contacts' email addresses without their authorization.

    Then, why Facebook can import all hotmail email addresses? and why this website: http://svetlozar.net/address-book-importer-demo.html can retrieve hotmail email addresses? Are they using other hotmail APIs?

     

    Thanks again!

    Regards,

    Bin

    The website you linked above is violating the Hotmail terms of use by screen scraping the Hotmail web experience using scripts. Facebook and a few other companies are a small set of partners are part of a program that enables mutual rights to import contacts from our service and theirs. This used to be an open program but is no longer available to new partners. 
    • Proposed as answer by Dare Obasanjo - MSFT Thursday, February 2, 2012 1:05 AM
    • Marked as answer by honeybin Thursday, February 2, 2012 1:27 AM
    Thursday, February 2, 2012 1:05 AM
  • While what I said is true, it is missing some conditions. First, the contact's user_id will only show up if the contact is a valid Windows Live user. Second, the contact's email will only show up if the application has wl.emails (as you have mentioned), and if that contact has given consent to your application to use emails.

    For instance, consider User A. If you go through User A's contacts, and see User B, who is a Windows Live user. You can use User B's user_id to get his/her email if User B has consented to your application previously.

    Given the above scenario, a better idea would be to save User B's email, and use email_hashes to find User B's email. More information on how to use email_hashes can be found here: http://msdn.microsoft.com/en-us/live/hh278351

    Getting all of contact's emails is not a scenario we offically support.

     

    Sorry for the incomplete information.
    Simon

    • Marked as answer by honeybin Thursday, February 2, 2012 1:27 AM
    Wednesday, February 1, 2012 9:52 PM

All replies

  • Hello

    You should be able to get the user's email address by preforming a GET on the contact's user_id. Please refer to the contact section in the documentation at http://msdn.microsoft.com/en-us/library/hh243648.aspx#contact.

    I hope this helps

    Simon

    Wednesday, February 1, 2012 4:43 AM
  • While what I said is true, it is missing some conditions. First, the contact's user_id will only show up if the contact is a valid Windows Live user. Second, the contact's email will only show up if the application has wl.emails (as you have mentioned), and if that contact has given consent to your application to use emails.

    For instance, consider User A. If you go through User A's contacts, and see User B, who is a Windows Live user. You can use User B's user_id to get his/her email if User B has consented to your application previously.

    Given the above scenario, a better idea would be to save User B's email, and use email_hashes to find User B's email. More information on how to use email_hashes can be found here: http://msdn.microsoft.com/en-us/live/hh278351

    Getting all of contact's emails is not a scenario we offically support.

     

    Sorry for the incomplete information.
    Simon

    • Marked as answer by honeybin Thursday, February 2, 2012 1:27 AM
    Wednesday, February 1, 2012 9:52 PM
  • Hi Simon,

     

    Thank you very much for your detailed explanation.

    And can I have another question?

    So, as you mentioned, Microsoft doesn't officially allow APP or Website to get all contacts' email addresses without their authorization.

    Then, why Facebook can import all hotmail email addresses? and why this website: http://svetlozar.net/address-book-importer-demo.html can retrieve hotmail email addresses? Are they using other hotmail APIs?

     

    Thanks again!

    Regards,

    Bin

    • Marked as answer by honeybin Thursday, February 2, 2012 1:27 AM
    • Unmarked as answer by honeybin Thursday, February 2, 2012 1:27 AM
    Wednesday, February 1, 2012 10:54 PM
  • Hi Simon,

     

    Thank you very much for your detailed explanation.

    And can I have another question?

    So, as you mentioned, Microsoft doesn't officially allow APP or Website to get all contacts' email addresses without their authorization.

    Then, why Facebook can import all hotmail email addresses? and why this website: http://svetlozar.net/address-book-importer-demo.html can retrieve hotmail email addresses? Are they using other hotmail APIs?

     

    Thanks again!

    Regards,

    Bin

    The website you linked above is violating the Hotmail terms of use by screen scraping the Hotmail web experience using scripts. Facebook and a few other companies are a small set of partners are part of a program that enables mutual rights to import contacts from our service and theirs. This used to be an open program but is no longer available to new partners. 
    • Proposed as answer by Dare Obasanjo - MSFT Thursday, February 2, 2012 1:05 AM
    • Marked as answer by honeybin Thursday, February 2, 2012 1:27 AM
    Thursday, February 2, 2012 1:05 AM
  • Thank you very much! That makes sense to me.

     

    Thursday, February 2, 2012 1:26 AM
  • Hi,

    I am also using the same MSN AI to grab user's contact details. And it is returning the following output. Since "email_hashes" is in Hashes format, I am not able to decode that.

    Can anyone tell me how do I decode this?

    { "id": "contact.49f4fa28000000000000000000000000", "first_name": Contact1, "last_name": null, "gender": null, "is_friend": false, "is_favorite": false, "user_id": null, "email_hashes": [ "6d5521f5eced6be2462b6d5b8eb95a851de9277a93b70e3ff2111bd98fad6b1a" ], "updated_time": "2011-08-24T07:55:13+0000" }

    Thanks,


    • Edited by Deecee2000 Thursday, June 28, 2012 12:25 AM
    Thursday, June 28, 2012 12:18 AM
  • The email_hashes are encoded by the following steps (take from here):

    Generate a set of email-address hashes

    Generate a hash that corresponds to the email address for each of your website's registered users. Each hash must be generated by following these steps:

    1. Trim leading and trailing white spaces from the email address, for example, Someone@Example.org.
    2. Trim leading and trailing white spaces from the requesting app's client ID, for example, 0000000603DB0F.
    3. Concatenate the results of steps 1 and 2, for example, Someone@Example.org0000000603DB0F.
    4. Convert the result of step 3 to lowercase, for example, someone@example.org0000000603db0f.
    5. Calculate the SHA-256 value of step 4 and convert the value to its hexadecimal equivalent, for example, 6A9F...63A4. (Part of the value is omitted here for brevity.)
    6. Convert the results of step 5 to lowercase, for example, 6a9f...63a4. The result of this step is the email-address hash.

    Unfortunately (or fortunately, depending on how you look at it), there is not a convenient way to decode the SHA-256 hash.

    Simon

    Thursday, June 28, 2012 12:41 AM
  • Hi Simon,

    Thanks for your prompt response.

    Does this mean that there is no way to decode this email hashes if I use this API.

    I really don't want to make another calls to hotmail contact pages and parse the contacts.

    I was also wondering how come other websites able to decode this? i.e. Facebook, LinkedIn

    Thanks,

    Monday, July 9, 2012 8:58 PM
  • That is correct. We do not provide a way to decode the email_hash. They are there to be used as an index into your own database, that you'd have to build as users login and consent to your application. This database would contain a mapping from a user's email_hash to the user's email. Then you could quickly look up an email using the email_hash (if you have it that is).

    Otherwise, for Facebook and LinkedIn, please refer to Dare's reply. It is marked as an answer on this thread.

    Simon

    Monday, July 9, 2012 9:27 PM
  • Thanks Simon again,Yes, I do understand about facebook and other websites.

    One thing I don't understand is how to map users email addresses into my application since I don't have any decoded email addresses.

    For example, in my application, if any user wants to import their contact list, they have to enter his/her email login details. And the API returns whole bunch of contacts list. All these contacts emails are encoded. I wouldn't have their original email addresses. Then how can I map their original email address with encoded emails?

    Thanks,

    Monday, July 9, 2012 9:52 PM
  • When a user consents to your application with wl.emails, you get the user's email address. You can now take this email address and compute the corresponding email_hash for it. Then you can take these two values and store them in the same row in a database 

    Now when you see an array of email hashes, you can take each one and look in your database to see if you have a row that contains it. If you do have a row with the given email_hash, that same row will have the email address that corresponds to the email_hash. If you do not have a row with the given email_hash, then that user's email is not stored in your database (more than likely because the user has not logged in and consent to your application yet).

    Note: You do not have to use a database, I'm just using that as an example. You can store it in away that serves your purpose.

    Hope this helps

    Simon

    Monday, July 9, 2012 10:08 PM
  • Hi Simon.

    It's unfortunate as you said that

    "Getting all of contact's emails is not a scenario we offically support."

    and 

    "The website you linked above is violating the Hotmail terms of use by screen scraping the Hotmail web experience using scripts."

    How can we as web developer know which website service to employ to obtain the full list of our users consent's hot mail contacts without violating your policy? Do you have a list of available service that we can have a look at or we'll have to use the illegal screen scrapping as you have mentioned.

    Thanks.

    Saturday, August 4, 2012 1:29 PM
  • Hi Simon.

    It's unfortunate as you said that

    "Getting all of contact's emails is not a scenario we offically support."

    and 

    "The website you linked above is violating the Hotmail terms of use by screen scraping the Hotmail web experience using scripts."

    How can we as web developer know which website service to employ to obtain the full list of our users consent's hot mail contacts without violating your policy? Do you have a list of available service that we can have a look at or we'll have to use the illegal screen scrapping as you have mentioned.

    Thanks.

    Microsoft does not endorse any service to provide or resell access to the email contacts of Hotmail or Outlook.com users. 
    Monday, August 6, 2012 6:59 PM
  • <div>
        <div id="first_name" class="Name"></div>
        <div id="name" class="Name"></div>
        <div id="last_name"></div>
        <div id="email"></div>
        <div id="address"></div>
        <div id="phone"></div>
         
        <div id="signin"></div>
    </div>
    <script src="//js.live.net/v5.0/wl.js" type="text/javascript"></script>
    <script type="text/javascript">
        // Update the following values
        var client_id = "enter your client id",
           
            redirect_uri = "enter your redirect url";

        function id(domId) {
            return document.getElementById(domId);
        }

        
    function displayMe() {
        WL.login({
            scope: ["wl.signin", "wl.basic", "wl.postal_addresses", "wl.phone_numbers", "wl.emails"]
        }).then(
            function (response) {
                WL.api({
                    path: "me",
                    method: "GET"
                }).then(
                    function (response) {
                        var e1=document.getElementById("first_name");
                        e1.innerText = response.first_name;
                        var e5=document.getElementById("name");
                        e5.innerText = response.name;
                       
                        var e2=document.getElementById("last_name");
                        e2.innerText = response.last_name;
                        var e3=document.getElementById("email");
                        e3.innerText = response.emails.preferred;
                        var e4=document.getElementById("address");
                        e4.innerText = response.addresses.personal.street + " " +
                            response.addresses.personal.city + " " +
                            response.addresses.personal.state + " " +
                            response.addresses.personal.postal_code + " " +
                            response.addresses.personal.region
                        document.getElementById("phone").innerText = response.phones.personal;
                      
                    },
                    function (responseFailed) {
                        document.getElementById("infoArea").innerText =
                            "Error calling API: " + responseFailed.error.message;
                    }
                );
            },
            function (responseFailed)
            {
                document.getElementById("infoArea").innerText =
                    "Error signing in: " + responseFailed.error_description;
            }
        );
           
    }
      /*  function displayMe() {
            var imgHolder = id("meImg"),
                nameHolder = id("meName"),
                emailHolder = id("meEmail");
                
            alert(nameHolder.id);  
            
            if (imgHolder.innerHTML != "") return;

            //if (WL.getSession() != null) {
                WL.api({ path: "me/picture", method: "get" }).then(
                        function (response) {
                            if (response.location) {
                                 
                                imgHolder.innerHTML = "<img src='" + response.location + "' />";
                            }
                        }
                    );

                WL.api({ path: "me", method: "get" }).then(
                        function (response) {
                            nameHolder.innerHTML = response.name;
       
                        }
                    );
                        
              WL.api({ path: "me/emails", method: "get" }).then(
                        
                        function (response) {
                            alert(response.emails.preferred);
                            if (response.emails) {
                                alert(response.emails);
                                emailHolder.innerHTML = response.emails.preferred;
                            }
                        }
                    );          
            }
    */

        function clearMe() {
            id("meImg").innerHTML = "";
            id("meName").innerHTML = "";
        }
       
     
        WL.Event.subscribe("auth.sessionChange",
            function (e) {
                if (e.session) {
                    displayMe();
                }
                else {
                    clearMe();
                }            
            }
        );

        WL.init({ client_id: client_id, redirect_uri: redirect_uri, response_type: "code" });

        WL.ui({ name: "signin", element: "signin" });
    </script>
    Wednesday, September 26, 2012 12:21 PM
  • Hello Simon,

    this is regarding the post on email hashes:

    we are developing a social site application , which requires us to retrieve hotmail contact email addresses but microsoft supports sending email hashes but not email addresses. Is there any other way where we can retrieve the email addresses from hotmail.

    Thanks

    chandrika

    Thursday, March 7, 2013 10:46 AM
  • I am trying to figure out who can help you with this. I should be able to answer this question early next week once I get a response from a few people.

    Thanks

    Simon

    Saturday, March 9, 2013 2:54 AM
  • I am trying to figure out who can help you with this. I should be able to answer this question early next week once I get a response from a few people.

    Thanks

    Simon

    Hi Simon,

    Hope you are doing well. May you please tell me that have you got response on it? I am regularly waiting for your reply on this ticket. Please suggest a way to extract the hotmail contacts. As previous API has deprecated.

    Thanks,

    Sherman

    • Proposed as answer by DK0083 Friday, June 14, 2013 4:05 PM
    Friday, June 14, 2013 6:51 AM
  • Dear Sherman,

    The answers provided by Dare are still correct. We do not provide the un-hashed email address information anymore through our SDK. Depending on your scenario, you may want to have a look at the contact picker available on windows 8 and windows phone 8.

    Thanks!

    Stephane

    Tuesday, June 25, 2013 11:01 PM
  • http://isdk.dev.live.com/dev/isdk/ISDK.aspx?category=scenarioGroup_hotmail&index=1

    I don't know if you even check your own examples because the one above doesn't work. Also /me/contacts returns only a single contact (which by the way I don't even have in my contacts(!!!)). wl.contacts and wl.emails scopes are reported non-existent, so, thanks a lot for having me waste a bunch of time and nerves trying to figure out how to get a list of contacts following your (recently updated) documentation. Way to go.

    Wednesday, June 26, 2013 1:22 PM
  • Hi Alex,

    I'm sorry you are encountering issues and lost time on it. I've just tried the iSDK and /me/contacts returns me my contacts. I'm assuming that you have an outlook.com account, if so, could you check that you contacts are available there? There may be an issue on our side.

    Also, could you point me to the documentation page you have found incorrect?

    Best regards

    Stephane

    Wednesday, June 26, 2013 2:35 PM
  • Hi Stephane,

    I'm sorry I lost my temper there.. As for my outlook account, after not being able to export contacts in the api, I tried to export to .csv and also got the one same weird contact as in live api.. When I created account, i imported contacts from gmail, and they are all listed there on the contact page, but when i exported them to csv - got only one. As for this example:

    http://msdn.microsoft.com/en-us/library/live/hh826527.aspx#readwrite_javascript

    I got 'undefined scope' error for wl.contacts (and when I looked at the docs, there wasn't any such scope, only wl.contacts_emails and similar..).

    Best regards

    Wednesday, June 26, 2013 8:04 PM
  • Hi Alex,

    No worries, I understand the frustration. Thanks for reporting the incorrect documentation. We will fix it.

    As for the contact export issue, I'll have to follow up internally to see what next steps we can take to debug this further.

    To set expectations and prevent you from losing more time, you will not be able to retrieve the un-hashed email address of the contacts, only basic information.

    Thanks!

    Stephane

    Wednesday, June 26, 2013 10:54 PM
  • Hi Alex,

    Can you confirm if you have used this Connect UI to import your gmail contacts? If you have, try creating a new contact directly in outlook and you should be able to retrieve it through the API (you can just use the interactive SDK to try that out).

    Thanks!

    Stephane

    Thursday, June 27, 2013 5:32 PM
  • Hi Stephane,

    Yes, I have used the connect ui to import gmail contacts. I have created a new contact directly in outlook, and voila, it does get exported to cvs, and I can get the contact information via live api (except emails, of course). As for the other 200+ contacts which I've imported, and which don't get exported, I really don't know what to say, except that for this kind of a bug you should be at least fair enough to say that this is some kind of a 'beta' testing version. And what I really don't understand is what kind of a policy is to deny access to users contact's emails when they themselves authorize it?

    Thanks.Alex

    Sunday, June 30, 2013 11:08 AM