Yahoo! Developer Network Blog
« Previous | Main | Next »
September 10, 2008
Getting started with the Yahoo! Address Book API
If there’s one internet application that people use most, it's probably email. However, email is worthless if you don't know where to send your messages and who you’re sending to; this makes the email address book one of the most widely used applications as well. In fact, the Yahoo! Address Book is a gold mine of relationships, connections, and history waiting to be tapped. To unlock that value, we’ve opened the Yahoo! Address Book to third-party developers.
This tutorial is aimed at helping new developers with a background in PHP get started with the Yahoo! Address Book APIs. I assume no prior knowledge of Yahoo technologies, but I do assume that you are familiar with network programming and understand how HTTP works at a basic level.
Before you get started, you’ll need an AppID (application identifier) from developer.yahoo.com (http://developer.yahoo.com/auth/appreg.html) with the correct scope of Address Book Read.
(Note: Sign up for an AppID at: http://developer.yahoo.com/wsregapp/)
For this tutorial to work, when you obtain your AppID, specify your application entry point to be:
http://www.domain.com/auth/bbauth.php
Substitute your own domain for www.domain.com. This structure will help you consolidate your landing pages (for Yahoo! and any other web services you choose) when you start building apps that rely on passing credentials to a receiving web page. The tutorial also assumes that you have access to an installation of PHP4 or PHP5 that is curl -capable.
When you are done with this tutorial, you should know how to do the following:
1) Present a user with a signed URL to login and pass user specific credentials back to your application.
2) Understand how to accept the user credentials and use them to make an authenticated call to the Y! Address Book APIs and get access to their data.
3) Use the built-in PHP SimpleXML() call to obtain specific fields from the user's address book.
Charles Wu
Platform Product Manager
Authentication
The Yahoo! Address Book API uses BBAuth, which relies on signed URLs to verify that legitimate parties are accessing a user's data. BBAuth uses a combination of a shared secret, cookies, and time-stamp to ensure that a user's data cannot be easily accessed. These checks protect the user, but can seem complex; many new developers struggle at this step to create a correctly signed URL.
This tutorial will not go into detail about the signing mechanics of how the authorization scheme works. Instead, I’ll rely on the “quick-start” PHP BBAuth libraries provided by Yahoo! at developer.yahoo.com. For developers who want a deeper understanding of BBAuth, please visit: http://developer.yahoo.com/auth/user.html.
My demo application will output the emails in a user's Yahoo! Address Book. It will have an HTML wrapper with a DIV to display the content depending on whether it’s a BBAuth-authenticated page or not. The wrapper code is pretty uninteresting, I’ve listed it here :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="look">
<h2>Address Book Tutorial Blog Post</h2>
<div>
<?php CreateContent(); ?>
</div>
<div id="content">
</div>
</div>
</body>
</html>
The interesting stuff is created in the CreateContent() call. Once it determines whether you’ve already authenticated, it gets the data. The pseudo-code is as follows:
if (empty(\$_GET["token"])) {
// User is not coming from BBAuth because it has not been called with a parameter "token" PRESUMABLY from BBAuth.
// Create a link for the user to log into BBAuth
} else {
// User is presumably being redirected from BBAuth
// so create an authenticated URL and get the address book data.
}
The key (no pun intended) in BBAuth is the pairing of the AppID (which can be publicly visible) and the shared secret (which should be kept hidden). These two cryptic strings are used to authenticate who you are. All your calls use some combination or transform of these items to demonstrate who you are. BBAuth also relies on time-stamps to make sure that a fresh call is made. I won’t apply the transforms directly, but instead will rely on PHP libraries from developer.yahoo.com and available in the BBAuth Quick Start bundle at: http://developer.yahoo.com/auth/quickstart/bbauth_quickstart.zip
Since these are global to everything we do, let's make them available to the page, and since they won't change, let's define them as constants.
define("APPID", '***-YOUR+APPID+HERE-***');
define("SECRET", '***-YOUR+SHARED+SECRET+HERE-***');
Next, we'll include the correct BBAuth library. We'll assume that it's in the same directory as this script, but you can modify the path to meet your needs. This library includes auth routines for the different types of APIs Yahoo! offers.
// Include the proper class file
$v = phpversion();
if ($v[0] == '4') {
include("ybrowserauth.class.php4");
} elseif ($v[0] == '5') {
include("ybrowserauth.class.php5");
} else {
die('Error: could not find the bbauth PHP class file.');
}
...
// Initialize the Authentication Object $authObj = new YBBauthREST(APPID, SECRET);
The demo script here does double duty: one part constructs a URL that directs a user to a login page for BBAuth and another uses the BBAuth token to make the actual API calls. Normally, your app would construct the login URL in one page, and then redirect to another page to collect the authorization token. Other applications choose a single page to handle the application flow and authentication. In this case, we use a single page.
Creating the Login URL
Assuming you don't have a token you’ll have to direct the user who is accessing your app to the correct page. The YBrowserAuth class has a single call that will generate the correct URL based on your credentials and the current time. The call is:
YBrowserAuth->getAuthURL('your_app_data', RETURN_USER_HASH boolean)
You'll want the RETURN_USER_HASH set to true to return the user token when completed. This user token is unique to the user who logs in and can be used to associate your application user data with the Yahoo! login. (This is similar to the user info that OpenID provides.) This token returns a signed URL that can be embedded in the page, where a user can click it to authenticate.
// You can send some data along with the authentication request
// In this case, the data is the string 'some_application_data'
echo 'You have not signed on using BBauth yet<br /><br />';
echo '<a href="'.$authObj->getAuthURL('some_application_data', true).'">Click here to authorize</a>';
The 'your_app_data' is a user-provided switch that your landing endpoint can use to direct to the correct function, for instance, if your web application uses both the Address Book API and the Mail API. If you come in from a point in your app that’s using Mail, you could pass the parameter 'mail' and your landing page will store the token. You can store it in a database and then redirect to the page that processes the mail API calls. If you’re coming from a place where the app needs to initiate an address book call, you can use 'addressbook' as the parameter and do a switch based on that.
Calling the Address Book
If a user clicks on the link generated above, they’ll be directed to a special Yahoo page and asked to enter user name and password on Yahoo!. The information in the URL means that once they’ve verified that your app is permitted to access their Contacts information, their browser is redirected to the landing page you provided when you got your AppID.
Yahoo! passes you a token that can be used for two weeks or until the user revokes permission. We pass that token via a GET parameter called "token." We also pass back the app data information you may have sent in the GET parameter called "appdata."
First, validate that the token you receive is correct. The validate_sig() call of the YBrowserAuth class extracts the appropriate information to ensure that the source and contents are from Yahoo!. Let's assume that this is correct. Now it’s time to get the address book data.
Constructing the Web Services Call
You need to construct an Address Book API query. The query structure is very similar to an SQL query, so it's easy. Start off with the root:
http://address.yahooapis.com/api/ws/v1/searchContacts?
Next, pick the data format you want for the return data. In my example we use XML. You can also specify JSON.
format=xml
Next, determine what fields you want returned. If you leave this out, you’ll get all fields for all contacts. In this example we only want email addresses to kickstart our invitation flow.
&fields=email
Finally, determine the search criteria you wish to apply. In this case, we only request contacts that have an email address.
&email.present=1
The completed query will look like this:
http://address.yahooapis.com/api/ws/v1/searchContacts?format=xml&fields=email&email.present=1
Note: Making a curl call on this will give you a 403 forbidden error. To make the call you now need to perform the same signing process as you performed to request the login URL. Your app makes a call to obtain a WSSID (Web Services Session ID) and the user's cookies. This is a limited time Session ID. In addition, you need to set the cookie. This additional step protects you and your users. The Ybrowserauth class provides a mechanism for that in the form of the makeAuthWSgetCall() that signs the URL, and returns what’s received from the web service.
$xmlstr=$authObj->makeAuthWSgetCall($path);
This sample code displays the information you received from the authentication web service for your information. We'll skip that here. You now have an XML file that can be parsed. The rest is standard PHP:
$xml = new SimpleXMLElement($xmlstr);
Iterating through the array creates an array that can be manipulated. In this case, because address books can be full of duplicates, we eliminate the dupes first, to be certain we don’t spam users with multiple invites.
$i = 0;
foreach ($xml->contact as $contact) {
$emails[$i] = $contact->email;
$i++;
}
$emails = array_unique($emails);
sort($emails);
The sample file prints out the emails and you’re done. The use of some simple libraries makes it a breeze to work with the Yahoo! Address Book API. Note the code from this tutorial will be available in the files section of the ydn-addressbook Yahoo Group.
Other links that might be of interest:
[1] A common authentication problem is that your timestamp may not align with Yahoo! time. Yahoo offers a time web service that returns the current time for your purpose:
http://developer.yahoo.com/util/timeservice/V1/getTime.html
[2] YDN Evangelist Dan Theurer has blog post on his blog explaining use the of BBAuth for Single Sign On and how to use the User Hash:
http://www.theurer.cc/blog/2006/09/29/bbauth-coding-single-sign-on/
Posted at September 10, 2008 10:31 AM | Permalink
Comments
Hi,
I am trying to write a sample application in .NET.
When I try to register for an application ID, I get errors as it doesnt seem to accept
http://localhost:48882/Default.aspx as the web URL.
To get an application ID, do I need to put real web site URL?
I was wondering, if I cant test in dev environment first, how can I put code on live site and test my changes?
is there anyway to get the samples run with a "localhost" url?
Thanks for your patience.
Posted by: StocksTom at October 22, 2008 5:53 AM
@StocksTom, the domain verification step must be able to access the server specified, so internal links like 'localhost' won't work.
You don't need to have your application live yet, you just need to verify that you own/control the domain in question. You could drop in the domain verification file without pushing your whole application.
For follow-on questions and information, I suggest following the ydn-addressbook discussion group:
http://tech.groups.yahoo.com/group/ydn-addressbook/
Brian Cantoni
Yahoo! Developer Network
Posted by: Brian Cantoni at October 22, 2008 3:10 PM
@Brian Cantoni: how would one receive the token/etc. if it forwards these GET requests to a domain than to localhost?
Posted by: Joey at January 7, 2009 8:40 AM
I eventually got over the hurdle by modifying the Windows Hosts file (located at C:\Windows\System32\Drivers\etc\hosts) and adding a custom host to redirect to localhost. You can retrieve the request at the modified URL.
Posted by: Joey at January 7, 2009 12:19 PM
Please can you be more explanative. This tutorial is so not complete. The last part
$xml = new SimpleXMLElement($xmlstr);
is not working for some reason. Please ellaborate on the part where we parse the GET results and show to user to send invites etc.
Posted by: JJ123 at February 12, 2009 7:10 PM
function CreateContent() {
// Create the BBauth object
$authObj = new YBBauthREST(APPID, SECRET);
// If Yahoo! isn't sending the token, then we aren't coming back from an
// authentication attempt
if (empty($_GET["token"])) {
echo 'You have not authorized access to your Yahoo! Mail account yet';
// Request a user hash and send some application data to be passed back
echo 'getAuthURL("some_application_data", true).'">Click here to authorize';
return;
}
// Validate the sig
if ($authObj->validate_sig()) {
echo 'BBauth authentication Successful';
echo 'The user hash is: '.$authObj->userhash.'';
} else {
die('BBauth authentication Failed Possible error msg is in $sig_validation_error:'. $authObj->sig_validation_error);
}
// Get the credentials for making authenticated web service calls
$xml=$authObj->getAccessCredentials();
if ($xml == false) {
die('WS CALL Failed: Possible errors are in $sig_validation_error: '. $authObj->sig_validation_error .
'or in $access_credentials_error: '. $authObj->access_credentials_error);
}
echo 'Timeout value is: '. $authObj->timeout .'';
echo 'Token value is: '. $authObj->token .'';
echo 'WSSID value is: '. $authObj->WSSID .'';
echo 'Cookie value is: '. $authObj->cookie .'';
echo 'appdata value is: '. $authObj->appdata .'';
echo ' If BBauth succeeded, then a simple tree of your mail folders is displayed below ';
echo '';
//@@@@@@@@@@@@@@ Test for retriving the email addresses @@@@@@@@@@
$query="http://address.yahooapis.com/api/ws/v1/searchContacts?format=xml&fields=email&email.present=1";
$xmlstr=$authObj->makeAuthWSgetCall($query);
$xml = new SimpleXMLElement($xmlstr);
$i = 0;
foreach ($xml->contact as $contact) {
$emails[$i] = $contact->email;
echo $emails[$i] ."";
$i++;
}
$emails = array_unique($emails);
sort($emails);
// The JSON-RPC call is an object with method and params attributes
$params = new stdclass(); // Empty params attribute
// Make the JSON-RPC call
$results = $authObj->ListFolders($params);
// Error from JSON-RPC transport
if ($results === false) {
die('Error in JSON-RPC method: '.$authObj->web_services_error);
}
// Standard JSON-RPC error
if (isset($results->error)) {
die('Error from inside JSON-RPC data. Message: '.$results->error->message.' Code: '.$results->error->code);
}
// Use the YUI Treeview control to display the mail folders
echo '
var tree;
function treeInit() {
tree = new YAHOO.widget.TreeView("treeDiv1");
var root = tree.getRoot();
var tmpNode = new YAHOO.widget.TextNode("Your Mail Folders ('.$results->result->numberOfFolders.')", root, false); ';
$i=0;
foreach ($results->result->folder as $fn) {
if ($fn->folderInfo->name == '@B@Bulk') $fn->folderInfo->name = 'Spam';
echo ' var tmpNode'.$i++ . '= new YAHOO.widget.TextNode("'.$fn->folderInfo->name.' (msgs: '.$fn->total.' unread: '.$fn->unread.' total bytes: '.$fn->size.')", tmpNode, false); ';
}
echo 'tree.draw();
}
';
return;
}
Posted by: Ken at April 22, 2009 3:34 AM
There are two methods
1. Generic, No user authentication required
2. Browser Based Authentication
If my app is a c/c++ program then which should I use. Can Generic be used to access Address book for read and write access. ?
Currently I registered my app as Generic access. I got AppId but from where I should get "secret".
Posted by: Kali at September 2, 2009 12:59 AM
I am trying to import yahoo address contacts in my application in .Net, but i am not getting the clue how to do it. Any one can help me???
Posted by: Shankar at December 16, 2009 4:45 AM
I am a php developer and I want to implement yahoo address book API in my project. Could you provide me the script in detail.
Posted by: mukesh at January 14, 2010 5:26 AM
I tried the example as above. I didn't get anything from it address book xml although manage to see "BBauth authentication Successful"
Please help
Thanks
Posted by: pay at January 14, 2010 1:39 PM
It's more simple than the Windows Live ! Contacts API but it's very similar with the libcurl php5...
Thanks for this article, it was very helpfull.
Now i have a Gmail, Hotmail & Yahoo! Contacts Importer ! Great !
Peace.
Posted by: blackmennewstyle at January 29, 2010 6:37 AM
Post a comment
Comment Policy: We encourage comments and look forward to hearing from you. Please note that Yahoo! may, in our sole discretion, remove comments if they are off topic, inappropriate, or otherwise violate our Terms of Service. Fields marked with asterisk '*' are required.
Subscribe
Recent Blog Articles
view all
YQL Open Table for Google Buzz now live
Tue, 09 Feb 2010
INSERT INTO twitter.status ...
Mon, 08 Feb 2010
Announcing the Yahoo! Brasil Open Hack Day 2010, 20-21 March
Mon, 08 Feb 2010
Marketing hacks, linchpins, and tech women of valor
Sun, 07 Feb 2010
Yahoo! India invites you to join the first India Hadoop Summit
Thu, 04 Feb 2010
Recent Links
Appcelerator Titanium + Yahoo YQL on Vimeo
Mon, 08 Feb 2010
Tue, 02 Feb 2010
PhoneGap | Cross platform mobile framework
Sat, 30 Jan 2010
Web developers can rule the iPad - O'Reilly Radar
Sat, 30 Jan 2010
rc3.org - Is the iPad the harbinger of doom for personal computing?
Thu, 28 Jan 2010
Archives
2010
2009
2008
2007
2006
2005
Recent Readers

