So we use this toolkit from Octazen to scrape contact lists off of various sites. Our ever eager users (ab)used this feature so much that hotmail blocked us.
So I waded through reams of API docs over at http://dev.live.com and finally came up with this prototype perl script to talk to their API servers. Gets the job done for now. Will want to rewrite it in native Java and add decent error handling soon. Hopefully this post here will help other folks needing to talk to Live API:
#!/usr/bin/perl
#
# Output tab separated values for a given hotmail username/password
#
# Implementation of Windows Live Contacts API
# http://msdn2.microsoft.com/en-us/library/bb463974.aspx
#
# Uses RPS authentication described here:
# http://msdn2.microsoft.com/en-us/library/bb447721.aspx
#
use HTTP::Request;
use LWP::UserAgent;
my $username = shift || die "Need a username\n";
my $password = shift || die "Need a password\n";
my $apikey = 'YOURAPIKEY';
my $ua = LWP::UserAgent->new;
my $uri = 'https://dev.login.live.com/wstlogin.srf';
my $req = HTTP::Request->new(POST => $uri);
$req->content_type('application/soap+xml');
my $xml = <<EOF
<s:Envelope
xmlns:s = "http://www.w3.org/2003/05/soap-envelope"
xmlns:wsse = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:saml = "urn:oasis:names:tc:SAML:1.0:assertion"
xmlns:wsp = "http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wsu = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wsa = "http://www.w3.org/2005/08/addressing"
xmlns:wssc = "http://schemas.xmlsoap.org/ws/2005/02/sc"
xmlns:wst = "http://schemas.xmlsoap.org/ws/2005/02/trust">
<s:Header>
<wlid:ClientInfo xmlns:wlid = "http://schemas.microsoft.com/wlid">
<wlid:ApplicationID>$apikey</wlid:ApplicationID>
</wlid:ClientInfo>
<wsa:Action s:mustUnderstand = "1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</wsa:Action>
<wsa:To s:mustUnderstand = "1">https://dev.login.live.com/wstlogin.srf</wsa:To>
<wsse:Security>
<wsse:UsernameToken wsu:Id = "user">
<wsse:Username>$username</wsse:Username>
<wsse:Password>$password</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</s:Header>
<s:Body>
<wst:RequestSecurityToken Id = "RST0">
<wst:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</wst:RequestType>
<wsp:AppliesTo>
<wsa:EndpointReference>
<wsa:Address>http://live.com</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wsp:PolicyReference URI = "MBI"></wsp:PolicyReference>
</wst:RequestSecurityToken>
</s:Body>
</s:Envelope>
EOF
;
$req->content_length(length $xml);
$req->content($xml);
my $res = $ua->request($req);
# Ugly way of hacking out the binarysecuritytoken
my $resultxml = $res->content();
$resultxml =~ m,<wsse:BinarySecurityToken[^>]*>(.*)</wsse:BinarySecurityToken>,si;
my $binarytoken = $1;
# Request contacts
my $contactsurl = "https://cumulus.services.live.com/$username/LiveContacts/Contacts";
my $authheader = 'WLID1.0 t="' . $binarytoken . '"';
my $contactsreq = HTTP::Request->new(GET => $contactsurl, ['Authorization' => $authheader]);
my $contactres = $ua->request($contactsreq);
my $contactxml = $contactres->content();
use XML::Simple;
my $result = XMLin($contactxml, 'ForceArray' => ['Email', 'Contact']);
# parse emails
foreach my $c (@{$result->{'Contact'}}) {
my $fname = $c->{Profiles}->{Personal}->{FirstName};
my $lname = $c->{Profiles}->{Personal}->{LastName};
foreach my $a (@{$c->{Emails}->{Email}}) {
print "$fname\t$lname\t" . $a->{Address} . "\n";
}
}
Recent Comments