Thursday, December 23, 2010

Microsoft Montage experiment

The overview given at the official site of montage gives the best description of montage, so according to them:
Montage is a shareable, personal, visual album of the web. You are able to design your personal Montage around a topic by adding content that pulls information from a variety of sources including, RSS feeds, Twitter, Bing News, YouTube, video and Bing Images. Your Montage is constantly evolving as you arrange each area with the content of your choice - which is easy, intuitive and fun; and can be on any topic from, movies, sports, to robots.
 I found montage extremely interesting and fun. The possibilities with montage are infinite. You can design your resume, portfolio etc. The best part about it is that it's soo easy to use and learn that anyone can use this with alot of ease. I did a small experiment on montage and created a montage of "kurt cobain", the link is:

http://bit.ly/gHhQaQ

Saturday, December 11, 2010

Extract contacts from Gmail using google AuthSub

There are alot of apis provided by google in order to extract contacts from your gmail account (and alot of other things as well). But the easiest method to extract gmail contacts i found is using AuthSub.

In order to use AuthSub, it's not mandatory to register your app/website with google, however, if you don't do that, google will show a warning message to the user which doesn't look friendly at all. So, it's better to register your site with google. In order to do so, go to the link https://www.google.com/accounts/ManageDomains. You can add a new domain and also manage the domains you have added previously. Keep in mind that in order to use other APIs of google, you'll need to register your site with google and get app secret and key.In order to understand the working of AuthSub, look at the following image (taken from google).











Now, let's get on with the code. You need to tell Google that what information do you want to extract from user's account. Google calls this "Scope". In order to get the contacts, the scope is; https://www.google.com/m8/feeds/. The scope should be url encoded.When the user has authenticated, Google returns an access token in the url. Hence, in order to check if the user has authenticated or not, simply check if the url contains a parameter "token" and it's not empty. i.e.;

if (isset($_GET['token']) && !empty($_GET['token'])) {
     Authenticated();
else
    notAuthenticated();

If you look at the figure above, you'll see that the first step is to request for an access token, now, on in order to do that, we need to generate a authentication url. That can be done using the following code;

function notAuthenticated(){
   $returnURL = "http://www.example.com/getGmailContacts.php";
   $GoogleScope =  "https://www.google.com/m8/feeds/";
   $link = 'https://www.google.com/accounts/AuthSubRequest?scope='.$GoogleScope;
   $link .= '&session=1&secure=0&next='.urlencode($returnURL);
   echo "<a href='$link'>Click here to authenticate request</a>";
}

In the above code, the description of parameters are,
session: (optional) Boolean flag indicating whether the one-time-use token may be exchanged for a session token (1) or not (0)
secure: (optional) Boolean flag indicating whether the authorization transaction should issue a secure token (1) or a non-secure token (0). Secure tokens are available to registered applications only.
next: (required) URL the user should be redirected to after a successful login. This value should be a page on the web application site, and can include query parameters

there are some other parameters as well, the details can be seen at: http://code.google.com/apis/accounts/docs/AuthSub.html#AuthSubRequest

Now, the user will be asked to login to his account and then he will be shown a page whether the user allows the request. Once the user has approved the request, the user will be taken back to the "return url" with "token" parameter in the url parameters.

We have covered the first 4 points shown in the figure shown above. Let's see the code for the rest of 2 points.

function Authenticated(){
       $token = $_GET['token'];
       $Contacts = array ();
       $GMailAuthSubUrl = "https://www.google.com/accounts/AuthSubSessionToken";
       $GMailContactsUrl = "https://www.google.com/m8/feeds/contacts/default/full?max-results=1000";


In the above code, now we are making request to get the session token. The "max-results" parameter in the GmailContactsUrl tells how many contacts do you want to retrieve. Like Yahoo API, give a very big number here to get all your contacts using one call. Now, let's make the call using curl

       $headers = array('Authorization: AuthSub token='.$token,
                         'Content-Type: application/x-www-form-urlencoded');
               
       $cURLHandle = curl_init();
       curl_setopt($cURLHandle, CURLOPT_RETURNTRANSFER, 1);
       curl_setopt($cURLHandle, CURLOPT_TIMEOUT, 60);
       curl_setopt($cURLHandle, CURLOPT_SSL_VERIFYPEER, FALSE);
       curl_setopt($cURLHandle, CURLOPT_URL, $GMailAuthSubUrl);
       curl_setopt($cURLHandle, CURLOPT_HTTPHEADER, $headers);
       $response = curl_exec($cURLHandle);


after making the above call, we will get the session token in the response. We will use this session token to get the contacts of the user now.
           
           $newToken = substr($response, 6);
     $headers = array('Authorization: AuthSub token='.$newToken,
                       'Accept-Charset: utf-8, iso-8859-2, iso-8859-1',
                       'Content-Type: application/x-www-form-urlencoded');  

     $cURLHandle = curl_init();
     curl_setopt($cURLHandle, CURLOPT_RETURNTRANSFER, 1);
     curl_setopt($cURLHandle, CURLOPT_TIMEOUT, 60);
     curl_setopt($cURLHandle, CURLOPT_SSL_VERIFYPEER, FALSE);
     curl_setopt($cURLHandle, CURLOPT_URL, $GMailContactsUrl);
     curl_setopt($cURLHandle, CURLOPT_HTTPHEADER, $headers);
     $response = curl_exec($cURLHandle);
     curl_close($cURLHandle);

       

As you can see, in the above curl call, we have now called the gmail contact url with the session token. Now, let's get the contacts from the response.

     $namespaceChanged = str_replace("gd:email", "gdemail", $response);
     $retrievedContacts = new SimpleXMLElement($namespaceChanged);
            

     echo "<ul>";
     if (!empty($retrievedContacts->entry)) {
        foreach ($retrievedContacts->entry as $contact) {
           $email = strip_tags($contact->gdemail['address']);
           $name = strip_tags($contact->title);
           echo "<li>".($name!=""?$name:$email)." ( ".$email." ) </li>";
        }
    }
    echo "</li>";
}

I hope this post was useful.

Thursday, December 9, 2010

Extract contacts from Yahoo

Whenever you are building a social media website, one of the very important components is to allow the user to send invitations to his contacts in his email account.Yahoo is one of the biggest email services provider. In this post, I will be giving a brief tutorial on how to setup your website/application on yahoo and how to extract the contacts from your yahoo account. In the coming posts, I will also be discussing the methods to extract contacts from windows live mail (hotmail) and gmail. But let's focus on yahoo for the time bein.


Let's start with the registration  of your website/application on yahoo. The steps to do so are;
1. Go to "My Projects" section located at https://developer.apps.yahoo.com/projects (you need to login)
2. Click on "New Project". This will show you a popup showing two options. Now, if your application is an external website then select "Standard" and click continue. Since, this tutorial is for webapplications, therefore, I am assuming that you selected "Standard" and clicked "Continue"
3. On the following screen, select "Web based" under "Kind of application" if it's a website. Then enter the name, description of your website. In the "Application URL" you have to mention the url of the main page of your website. In the "Application Domain" you have to enter the domain name of your website. Keep in mind, that you have to enter the "domain name" only and the domain name shouldn't have path associated with it.
4. Since, we are going to extract the contacts of the user, we need to attach these permissions to our api key. Hence, under "Access Scope", select the second option i.e. "This app requires access to private user data". Once you select the second option, a list of permissions are shown below. Since, we are only interested in getting the contacts of the user, scroll down to the section "Yahoo! Contacts" and select "Read" from the dropdown menu next to it. Then scroll down to the "Relationships" section and select "Read/Write" from the dropdown menu next to it. Then click on Get an API key.
5. The next page will show you the options to get your application/website verified. Follow the steps mentioned to verify your application. You may skip this step, however, doing so will show a nasty warning whenever user tries to extract the contacts through your website.
6. Once done, you'll be shown your application/consumer key and secret. The application id is mentioned on the top under the application name on the same page.


Now, the website/application registration is done. Let's move on to the coding part. Yahoo provides various APIs to do the job, however, I will be using Yahoo PHP SDK for the purpose. You can download the PHP SDK from http://developer.yahoo.com/social/sdk/#php. You'll be needing the files placed in the "lib" folder in the archive you download.

The code is very simple. Though, in order to understand the code, you should be familiar with OAuth. As a first step, you need to include the "Yahoo.inc" file in your code. Make sure, that all the files in the "lib" folder are placed in the same folder. 

<?php
include_once ("Yahoo.inc");
$APP_KEY = "Your application key comes here";
$APP_SECRET = "Your application secret comes here";
$APP_ID = "Your application ID comes here";


As a first step, let's see if the session of the user is already initialized or not.

$isActive = YahooSession::hasSession($APP_KEY, $APP_SECRET, $APP_ID);


If the session of the user is not already initialized then we need to initialize the session first. In order to initialize the session, we need to take the user to the yahoo login page, once the user is logged in, he will be shown a screen to authorize the access to his contacts from our application and once the user has authorized, he is taken back to the page of our website which deals with the extraction of contacts. Now, you might be wondering, how on earth will that happen, well it's actually very simple. Yahoo will trace our application through app secret, app key and app id that we will pass with the url. And once the user has authorized the access, where to return??Well, again we will pass the return url to Yahoo. Enough talk, let's see the code;


$returnUrl = "the complete url of the page on which you want to return";

In this case, i'll be returning to this page. so let's say the name of this page is getYahooContacts.php and the name of domain is www.example.com, then the returnUrl should be "http://www.example.com/getYahooContacts.php"


if(!$isActive){
$authorization_url = YahooSession::createAuthorizationUrl($APP_KEY, $APP_SECRET, $returnUrl);
echo "<a href='$authorization_url'>Click here to get yahoo contacts</a>";
}else{
/*get and display contacts*/
}


Now, once the user has authorized the access, we will be brought to the same page (depending upon the $returnUrl). So, let's now talk about getting the contacts of the user;


In order to get contacts of the user, we need to first get the session object of the logged in user and get the id of the logged in user. We can achieve that using the yahoo api;


$session = YahooSession::requireSession($APP_KEY, $APP_SECRET, $APP_ID);
$user = $session->getSessionedUser();


Now, the built in function of yahoo api, "getContacts($start, $count)" called on the user object returns the contacts of the user..The problem with this is that it returns the contacts starting from the offset "$start" and returns "$count" number of contacts. Now, if you want to get all contacts of the user, one way is to loop through and keep asking for contacts untill  you get all contacts, however, you can use a simple trick. Give a very big number in the "$count" and 0 as "$start", this will give you all your contacts in one single call. Let's see the final code;

$contacts = new stdClass();
$contacts = $user->getContacts(0, 1000);

The most tricky part is to extract the email addresses from the yahoo returned object. The returned object is a bit complex one. You'd need to spend some time dumping the contents of entire object to see which things you require are place where. However, the following code does that for you, but those of you who want to see what other information is there (and believe me there is alot), dump the entire $contacts object and go through it

$contactsData = "<ul>";
foreach($contacts->contacts->contact as $singleContact){
   $name = "";
   $email = "";
   $yahooid = "";
   foreach($singleContact->fields as $singleField){
      if($singleField->type == "name"){
        $name = $singleField->value->givenName;
        if($singleField->value->familyName != "")
          $name .= " ".$singleField->value->familyName;
        }
        if($singleField->type == "email"){
          $email = $singleField->value;
        }else if($singleField->type == "yahooid"){
          $email = $singleField->value."@yahoo.com";
          $yahooid = $singleField->value;
        }
      }
      if($name == "")
        $name = $yahooid;


      $contactsData .= "<li>" . $email ." ( ". $name . " ) </li>";
}

$contactsData .= "</ul>";

echo $contactsData;


Hope you find this post helpful