After much hard work, the team at MyBlogLog and the Yahoo! Developer Network--including but definitely not limited to Todd Sampson, Ian Kennedy, J.R. Conlin, and the one and only Chris Goffinet--have released the MyBlogLog API into limited public beta.
Included in the API are the usual goodies already found in the reader roll, plus other stuff like tags, discussion, and outside communities.
That last bit is important: suddenly there's a wide-open source of information about who lives where on the Web. Over the past week I've begun pinging various services as they come up for my users; as of right now, we should see:
Although I am a developer who works for Yahoo!, I don't work on MyBlogLog or any of the other services that show up here. Absolutely nothing you see on this page--including random stuff written and broadcast by any of the services that are being returned as a result of connections between the MyBlogLog API and outside services--should be taken as official messaging from Yahoo!
In addition to MyBlogLog, data for this hack comes from a wide variety of sources, including Yahoo's MyBlogLog, Flickr, Upcoming, and del.icio.us services. I believe I've attributed it properly, by linking to http://developer.yahoo.com/about, as requried by YDN's attribution page.
// API-powered mybloglog badge, case-hardened
// copyright Kent Brewster, 2008
// see http://kentbrewster.com/first-steps-with-the-mybloglog-api for details
// currently includes:
// sites authored (with recursive exploration; click to go!)
// most recent Twitter tweet, last five Flickr photos, last five del.icio.us bookmarks,
// last five pages Dugg, last five songs scrobbled at last.fm, next five events from upcoming,
// last five movies favorited on YouTube,
// current positions from LinkedIn, if you have a public profile at linkedin.com/yourname
( function() {
var trueName = '';
for (var i = 0; i < 16; i++) { trueName += String.fromCharCode(Math.floor(Math.random() * 26) + 97); }
window[trueName] = {};
var $ = window[trueName];
$.f = function() {
return {
init : function(el) {
$.f.getDetails = [];
$.f.pingDelicious = [];
$.f.pingDugg = [];
$.f.pingLastFM = [];
$.f.pingLinkedIn = [];
$.f.pingUpcoming = [];
$.f.pingYouTube = [];
$.f.svcUrl = {
"30 boxes":"~",
"bebo":"http://bebo.com/Profile.jsp?MemberId=~",
"blogger":"http://www.blogger.com/profile/~",
"del.icio.us":"http://delicious.com/~",
"digg":"http://www.digg.com/users/~",
"ebay":"http://myworld.ebay.com/~",
"facebook":"http://www.facebook.com/profile.php?id=~",
"flickr":" http://www.flickr.com/photos/~/",
"friendster":"http://~.blogs.friendster.com/",
"google calendar":"http://~.jaiku.com/",
"jaiku":"http://~.jaiku.com/",
"jumpcut":"http://www.jumpcut.com/~",
"kiva":"http://www.kiva.org/lender/~",
"last.fm":"http://www.last.fm/user/~",
"linkedin":"http://www.linkedin.com/in/~",
"livejournal":"http://~.livejournal.com/",
"myspace":"http://myspace.com/~",
"netflix":"http://rss.netflix.com/QueueRSS?id=~",
"openid":"~",
"plaxo":"~",
"pownce":"http://www.pownce.com/~",
"second life":"~",
"shelfari":"http://www.shelfari.com/~",
"stumbleupon":"http://~.stumbleupon.com",
"technorati":"http://www.technorati.com/people/technorati/~",
"textamerica":"http://~.textamerica.com/",
"the dj list":"http://www.thedjlist.com/djs/~",
"twitter":"http://www.twitter.com/~",
"typekey":"http://profile.typekey.com/~",
"upcoming":"http://upcoming.yahoo.com/user/~",
"wakoopa":"http://www.wakoopa.com/~",
"wink":"http://wink.com/profile/~",
"yelp":"http://www.yelp.com/user_details?userid=~",
"youtube":"http://youtube.com/user/~",
"zorpia":"http://www.zorpia.com/~"
};
if (document.getElementById(el)) {
if (mbl_recent_visitor) {
$.f.currentUser = mbl_recent_visitor;
}
$.w = document.getElementById(el);
$.w.innerHTML = '';
$.w.h = document.createElement('H3');
$.w.appendChild($.w.h);
$.w.c = document.createElement('DIV');
$.w.appendChild($.w.c);
$.w.f = document.createElement('DIV');
$.w.f.className = 'attrib';
var a = document.createElement('A');
a.innerHTML = 'Web services by Yahoo!';
a.href = 'http://developer.yahoo.com/about/';
a.target = '_blank';
$.w.f.appendChild(a);
$.w.appendChild($.w.f);
$.f.callback = trueName + '.f.getUsers';
$.f.appid = '[my api key here]';
$.f.count = 16;
$.f.orgCommunityId = '2006110818574284';
$.f.communityId = $.f.orgCommunityId;
$.w.c.innerHTML = '';
$.w.h.innerHTML = 'Pinging the MyBlogLog API....';
$.f.getUsers();
}
},
getCurrentUser : function() {
$.f.getCurrentVisitorCallback = function(r) {
delete $.f.getCurrentVisitorCallback;
$.f.removeScript(trueName + '.f.getCurrentVisitorCallback');
$.f.renderUser(r);
};
var callback = trueName + '.f.getCurrentVisitorCallback';
var url = 'http://mybloglog.yahooapis.com/v1/user/';
url += $.f.currentUser;
url += '?format=json&callback=' + callback;
url += '&appid=' + $.f.appid;
$.f.runScript(url, callback);
},
getUsers : function() {
$.w.c.innerHTML = '';
$.f.foundCurrentUser = false;
$.f.pingUsers = function(r) {
delete $.f.pingUsers;
$.w.h.innerHTML = ''
$.w.h.appendChild(document.createTextNode('Recent Visitors to '));
var a = document.createElement('A');
a.innerHTML = r.name;
a.href = 'http://www.mybloglog.com/buzz/community/' + r.id;
a.target = '_blank';
$.w.h.appendChild(a);
if ($.f.communityId != $.f.orgCommunityId) {
$.w.h.appendChild(document.createTextNode(' - '));
var a = document.createElement('A');
a.innerHTML = 'back to BFG';
a.style.color = '#00f';
a.rel = $.f.orgCommunityId;
a.onclick = function() {
$.f.communityId = this.rel;
$.f.getUsers();
}
$.w.h.appendChild(a);
}
$.f.removeScript($.f.callback);
if (r.users && r.users.user) {
var max = r.users.user.length;
for (var i = max; i > 0; i--) {
var t = i - 1;
$.f.renderUser(r.users.user[t]);
}
} else {
$.w.h.appendChild(document.createTextNode(' - No readers found, sorry!'));
}
if ($.f.currentUser) {
$.f.getCurrentUser();
}
};
var url = 'http://mybloglog.yahooapis.com/v1/community/';
url += $.f.communityId;
url += '/readers?format=json&callback=' + trueName + '.f.pingUsers';
url += '&count=' + $.f.count;
url += '&appid=' + $.f.appid;
$.f.runScript(url, $.f.callback);
},
renderUser : function(u) {
var div = document.createElement('DIV');
div.className = 'r';
div.id = u.id;
var p = document.createElement('P');;
var img = document.createElement('IMG');
img.src = u.pict;
img.height = '48';
img.width = '48';
img.alt = u.nickname;
img.title = u.nickname;
img.align = 'absmiddle';
p.appendChild(img);
p.appendChild(document.createTextNode(' '));
var a = document.createElement('A');
a.href = u.url;
a.target = '_blank';
a.innerHTML = u.nickname.replace(/<em>/, '').replace(/<\/em>/, '');
p.appendChild(a);
if ($.f.currentUser) {
if (div.id == $.f.currentUser) {
p.appendChild(document.createTextNode(' -- this is you!'));
}
}
div.appendChild(p);
$.w.c.appendChild(div);
$.f.getReaderDetails(div.id);
},
getReaderDetails : function(id) {
var n = $.f.getDetails.length;
$.f.getDetails[n] = function(r) {
delete $.f.getDetails[n];
$.f.removeScript(trueName + '.f.getDetails[' + n + ']');
var s = r.sites_authored;
if (s && s.site) {
var p = document.createElement('P');
p.appendChild(document.createTextNode('Sites Authored -- click to explore reader communities!'));
p.appendChild(document.createElement('BR'));
var cj = s.site.length;
if (cj > 6) {
cj = 6;
}
for (var j = 0; j < cj; j++) {
var a = document.createElement('A');
a.title = s.site[j].description;
a.rel = s.site[j].id;
a.onclick = function() {
$.f.communityId = this.rel;
$.f.getUsers();
}
var img = document.createElement('IMG');
img.src = s.site[j].pict;
a.appendChild(img);
p.appendChild(a);
}
document.getElementById(id).appendChild(p);
}
var p = document.createElement('P');
if (r.tags && r.tags.tag && r.tags.tag.length) {
p.appendChild(document.createTextNode('Tags: '));
var t = r.tags.tag.length;
for (var i = 0; i < t; i++) {
var a = document.createElement('A');
a.href = r.tags.tag[i].url;
if (i) {
p.appendChild(document.createTextNode(', '));
}
a.innerHTML = r.tags.tag[i].name.toLowerCase();
a.title = 'Tagged "' + r.tags.tag[i].name + '" by ' + r.tags.tag[i].count + ' user';
if (r.tags.tag[i].count > 1) {
a.title += 's';
}
a.title += '.';
a.alt = a.title;
p.appendChild(a);
}
p.appendChild(document.createTextNode('. Know this person? '));
var a = document.createElement('A');
a.innerHTML = 'Add some tags.';
a.target = '_blank';
a.href = 'http://www.mybloglog.com/buzz/members/' + r.screen_name;
p.appendChild(a);
} else {
p.appendChild(document.createTextNode('No tags found. Know this person? '));
var a = document.createElement('A');
a.innerHTML = 'Go play tag!';
a.target = '_blank';
a.href = 'http://www.mybloglog.com/buzz/members/' + r.screen_name;
p.appendChild(a);
}
document.getElementById(r.id).appendChild(p);
if (r.profile.services && r.profile.services.service && r.profile.services.service.length) {
var p = document.createElement('P');
p.appendChild(document.createTextNode('Meet Me On: '));
for (var i = 0; i < r.profile.services.service.length; i++) {
if (i) {
p.appendChild(document.createTextNode(', '));
}
var a = document.createElement('A');
a.innerHTML = r.profile.services.service[i].name;
if ($.f.svcUrl[r.profile.services.service[i].name]) {
a.href = $.f.svcUrl[r.profile.services.service[i].name].replace(/~/,r.profile.services.service[i].id);
}
a.target = '_blank';
p.appendChild(a);
if (r.profile.services.service[i].name == 'upcoming') {
$.f.getUpcoming(r.id, r.profile.services.service[i].id);
}
if (r.profile.services.service[i].name == 'twitter') {
$.f.getTweet(r.id, r.profile.services.service[i].id);
}
if (r.profile.services.service[i].name == 'flickr') {
$.f.getFlickr(r.id, r.profile.services.service[i].nsid);
}
if (r.profile.services.service[i].name == 'del.icio.us') {
$.f.getDelicious(r.id, r.profile.services.service[i].id);
}
if (r.profile.services.service[i].name == 'linkedin') {
$.f.getLinkedIn(r.id, r.profile.services.service[i].id);
}
if (r.profile.services.service[i].name == 'digg') {
$.f.getDugg(r.id, r.profile.services.service[i].id);
}
if (r.profile.services.service[i].name == 'last.fm') {
$.f.getLastFM(r.id, r.profile.services.service[i].id);
}
if (r.profile.services.service[i].name == 'youtube') {
$.f.getYouTube(r.id, r.profile.services.service[i].id);
}
}
p.appendChild(document.createTextNode('. '));
document.getElementById(r.id).appendChild(p);
}
};
var callback = trueName + '.f.getDetails[' + n + ']';
var url = 'http://mybloglog.yahooapis.com/v1/user/';
url += id;
url += '?format=json&callback=' + callback;
url += '&count=' + $.f.count;
url += '&appid=' + $.f.appid;
$.f.runScript(url, callback);
},
getYouTube : function(id, nick) {
var n = $.f.pingYouTube.length;
var p = document.createElement('P');
p.rel = nick;
p.id = 'youtube_' + n;
document.getElementById(id).appendChild(p);
var callback = trueName + '.f.pingYouTube[' + n + ']';
$.f.pingYouTube[n] = function(r) {
var o = document.getElementById('youtube_' + n);
delete $.f.pingYouTube[n];
$.f.removeScript(trueName + '.f.pingYouTube[' + n + ']');
if (r.value.items) {
o.parentNode.insertBefore(document.createTextNode('YouTube Movies:'), o);
var c = r.value.items;
var b = c.length;
if (b > 5) { b = 5; }
for (var i = 0; i < b; i++) {
var a = document.createElement('A');
var img = document.createElement('IMG');
img.src = c[i]['media:group']['media:thumbnail'][0].url;
img.height = c[i]['media:group']['media:thumbnail'][0].height;
img.width = c[i]['media:group']['media:thumbnail'][0].width;
img.title = c[i]['media:group']['media:title'].content;
a.appendChild(img);
a.href = c[i].link;
a.target = '_blank';
o.appendChild(a);
}
}
};
var url = 'http://pipes.yahoo.com/kentbrew/youtube_getmovies?_render=json&_callback=' + callback + '&s=' + nick;
$.f.runScript(url, callback);
},
getUpcoming : function(id, nick) {
var n = $.f.pingUpcoming.length;
var p = document.createElement('P');
var ul = document.createElement('UL');
ul.rel = nick;
ul.id = 'upcoming_' + n;
p.appendChild(ul);
document.getElementById(id).appendChild(p);
var callback = trueName + '.f.pingUpcoming[' + n + ']';
$.f.pingUpcoming[n] = function(r) {
var o = document.getElementById('upcoming_' + n);
delete $.f.pingUpcoming[n];
$.f.removeScript(trueName + '.f.pingUpcoming[' + n + ']');
if (r.value.items && r.value.items[0] && r.value.items[0].channel.item) {
o.parentNode.insertBefore(document.createTextNode('Upcoming events:'), o);
var c = r.value.items[0].channel.item;
var b = c.length;
if (b > 5) { b = 5; }
for (var i = 1; i < b; i++) {
var li = document.createElement('LI');
var a = document.createElement('A');
a.innerHTML = c[i]['xCal:summary'];
a.href = c[i]['link'];
a.target = '_blank';
li.appendChild(a);
var d = c[i]['xCal:dtstart'];
var pd = d.substr(0, 4) + '-' + d.substr(4, 2) + '-' + d.substr(6, 2);
li.appendChild(document.createTextNode(' - ' + pd));
o.appendChild(li);
}
}
};
var url = 'http://pipes.yahoo.com/kentbrew/upcoming_getevents?_render=json&_callback=' + callback + '&s=' + nick;
$.f.runScript(url, callback);
},
getLastFM : function(id, nick) {
var n = $.f.pingLastFM.length;
var p = document.createElement('P');
var ul = document.createElement('UL');
ul.rel = nick;
ul.id = 'lastFM_' + n;
p.appendChild(ul);
document.getElementById(id).appendChild(p);
var callback = trueName + '.f.pingLastFM[' + n + ']';
$.f.pingLastFM[n] = function(r) {
var o = document.getElementById('lastFM_' + n);
delete $.f.pingLastFM[n];
$.f.removeScript(trueName + '.f.pingLastFM[' + n + ']');
if (r.value.items && r.value.items[0] && r.value.items[0].channel.item) {
o.parentNode.insertBefore(document.createTextNode('Recently scrobbled tracks from last.fm:'), o);
var c = r.value.items[0].channel.item;
var b = c.length;
if (b > 6) { b = 6; }
for (var i = 1; i < b; i++) {
var li = document.createElement('LI');
var t = c[i].title.split(' \u2013 ');
var artist = document.createElement('A');
artist.href = c[i].description;
artist.innerHTML =t[0];
artist.target = '_blank';
li.appendChild(artist);
li.appendChild(document.createTextNode(' : '));
var song = document.createElement('A');
song.innerHTML = t[1];
song.href = c[i].link;
song.target = '_blank';
li.appendChild(song);
o.appendChild(li);
}
}
};
var url = 'http://pipes.yahoo.com/kentbrew/lastfm_getrecenttracksbyuser?_render=json&_callback=' + callback + '&s=' + nick;
$.f.runScript(url, callback);
},
getDugg : function(id, nick) {
var n = $.f.pingDugg.length;
var p = document.createElement('P');
var ul = document.createElement('UL');
ul.rel = nick;
ul.id = 'dugg_' + n;
p.appendChild(document.createTextNode('Recently Dugg:'));
p.appendChild(ul);
document.getElementById(id).appendChild(p);
var callback = trueName + '.f.pingDugg[' + n + ']';
$.f.pingDugg[n] = function(r) {
var o = document.getElementById('dugg_' + n);
delete $.f.pingDugg[n];
$.f.removeScript(trueName + '.f.pingDugg[' + n + ']');
if (r.value.items && r.value.items[0]) {
var c = r.value.items[0].story;
var b = c.length;
if (b > 5) { b = 5; }
for (var i = 0; i < b; i++) {
var li = document.createElement('LI');
var a = document.createElement('A');
a.href = c[i].link;
a.innerHTML = c[i].title;
a.target = '_blank';
li.appendChild(a);
o.appendChild(li);
}
}
};
var url = 'http://pipes.yahoo.com/kentbrew/digg_getduggbyuser?_render=json&_callback=' + callback + '&s=' + nick;
$.f.runScript(url, callback);
},
getLinkedIn : function(id, nick) {
var n = $.f.pingLinkedIn.length;
var p = document.createElement('P');
var ul = document.createElement('UL');
ul.rel = nick;
ul.id = 'linkedin_' + n;
p.appendChild(document.createTextNode('Current Positions from LinkedIn:'));
p.appendChild(ul);
document.getElementById(id).appendChild(p);
var callback = trueName + '.f.pingLinkedIn[' + n + ']';
$.f.pingLinkedIn[n] = function(r) {
var o = document.getElementById('linkedin_' + n);
delete $.f.pingLinkedIn[n];
$.f.removeScript(trueName + '.f.pingLinkedIn[' + n + ']');
if (r.value.items) {
var c = r.value.items;
var b = c.length;
if (b > 5) { b = 5; }
for (var i = 0; i < b; i++) {
var li = document.createElement('LI');
li.innerHTML = c[i].content;
o.appendChild(li);
}
}
};
var url = 'http://pipes.yahoo.com/kentbrew/linkedin_getcurrent?_render=json&_callback=' + callback + '&s=' + nick;
$.f.runScript(url, callback);
},
getDelicious : function(id, nick) {
var n = $.f.pingDelicious.length;
var p = document.createElement('P');
var ul = document.createElement('UL');
ul.rel = nick;
ul.id = 'delicious_' + n;
p.appendChild(document.createTextNode('Bookmarked on del.icio.us:'));
p.appendChild(ul);
document.getElementById(id).appendChild(p);
var callback = trueName + '.f.pingDelicious[' + n + ']';
$.f.pingDelicious[n] = function(r) {
var o = document.getElementById('delicious_' + n);
delete $.f.pingDelicious[n];
$.f.removeScript(trueName + '.f.pingDelicious[' + n + ']');
var b = r.length;
if (b > 5) { b = 5; }
for (var i = 0; i < b; i++) {
var li = document.createElement('LI');
var a = document.createElement('A');
a.innerHTML = r[i].d;
a.href = r[i].u;
a.target = '_blank';
li.appendChild(a);
li.appendChild(document.createElement('BR'));
if (r[i].t) {
li.appendChild(document.createTextNode('Tags: '));
var z = r[i].t.length;
if (z > 5) { z = 5; }
for (var j = 0; j < z; j++) {
var a = document.createElement('A');
a.innerHTML = r[i].t[j];
a.href = 'http://del.icio.us/' + o.rel + '/' + r[i].t[j];
a.target = '_blank';
li.appendChild(a);
if (j < z - 1) {
li.appendChild(document.createTextNode(', '));
}
}
}
o.appendChild(li);
}
};
var url = 'http://del.icio.us/feeds/json/' + nick + '?callback=' + callback;
$.f.runScript(url, callback);
},
getTweet : function(id, nick) {
var p = document.createElement('P');
p.id = 'twitterStatus_' + nick;
p.innerHTML = '';
document.getElementById(id).appendChild(p);
var callback = trueName + '.f.pingTweet';
var url = 'http://twitter.com/statuses/user_timeline/' + nick + '.json?callback=' + callback;
$.f.runScript(url, 'tweet_' + nick);
},
pingTweet : function(r) {
if (r.error) {
} else {
if (r[0]) {
var nick = r[0].user.screen_name;
if (document.getElementById('twitterStatus_' + nick)) {
var t = document.getElementById('twitterStatus_' + nick);
var p = document.createElement('P');
p.innerHTML = 'Twittering:';
t.appendChild(p);
var p = document.createElement('P');
var tweet = r[0].text;
p.innerHTML = tweet;
t.appendChild(p);
}
}
}
// sometimes fails; if there are no updates, there's no nick, so the script tags stays inline
$.f.removeScript('tweet_' + nick);
},
getFlickr : function(id, nick) {
var p = document.createElement('P');
p.id = 'flickrStream_' + nick;
p.innerHTML = '';
document.getElementById(id).appendChild(p);
var callback = trueName + '.f.pingFlickr';
var url = 'http://api.flickr.com/services/feeds/photos_public.gne?id=' + nick + '&lang=en-us&format=json&jsoncallback=' + callback;
$.f.runScript(url, callback + '_' + nick);
},
pingFlickr : function(r) {
var nick = r.title.split('from ')[1];
var nsid = r.items[0].author_id;
if (document.getElementById('flickrStream_' + nsid)) {
var p = document.getElementById('flickrStream_' + nsid)
p.innerHTML = 'Flickr Photos:<br />';
var max = r.items.length;
if (max > 7) { max = 7; }
for (var i = 0; i < max; i++) {
var a = document.createElement('A');
a.href = r.items[i].link;
a.title = r.items[i].title;
a.target = '_blank';
var img = document.createElement('IMG');
img.src = r.items[i].media.m.replace(/m.jpg/, 's.jpg');
a.appendChild(img);
p.appendChild(a);
}
var scriptId = trueName + '.f.pingFlickr_' + nsid;
$.f.removeScript(scriptId);
}
},
runScript : function(url, id, p) {
var s = document.createElement('script');
s.id = id;
s.type ='text/javascript';
s.src = url;
if (!p) {
p = document.getElementsByTagName('body')[0];
}
p.appendChild(s);
},
removeScript : function(id) {
if (document.getElementById(id)) {
var s = document.getElementById(id);
s.parentNode.removeChild(s);
}
}
};
}();
var init = function() { $.f.init('mbl'); };
if(typeof window.addEventListener !== 'undefined') {
window.addEventListener('load', init, false);
} else if(typeof window.attachEvent !== 'undefined') {
window.attachEvent('onload', init);
}
} )();
If you're curious about the coding style, please take a look at Case-Hardened JavaScript. More about implementing nothing-but-net API clients using the SCRIPT tag hack may be found under Presentations, in BBC Search Widget and Wikipedia Search Widget. I do take these presentations on the road; if you're interested in seeing it in person, please hit me up in Contact.
Got the most recent user thing figured out, thanks to a quick conversation yesterday with Todd and Chris and Ian before Hack Lunch. They've added a global variable to the MyBlogLog tracker, mbl_recent_visitor. If you're signed in to MyBlogLog, you ought to show up at the very bottom of the stack, with "this is you!" next to your screen name.
In other interesting news, YUI now supports the script tag hack, with the new Get utility. I may finally have to break down and give it a try....
Oh, and: it looks like I may be putting on my booth-bunny ears and heading to ETech. Fun fun fun!
In other interesting news: looks like I'll be speaking on behalf of the MyBlogLog crew at Search SIG: Search & The Social Graph, next Tuesday the 12th at 6:30pm. Details are online at SDForum; it says you should register fast, since these events fill up. (They do.)
Also: the requests for a call to determine the current user's MyBlogLog ID have been relayed to the Powers that Be ... hopefully we'll have an answer soon.
You can see it in action on the Raven SEO Blog, where we provide full profile pages promoting each of our community members.
Since Digg--unlike Twitter--doesn't give you back the user name you were querying, it's impossible to fire off five different queries for five different users and be sure that the results will go into the proper DOM elements ... so I punted, and used Pipes, which will allow proper callbacks. (See the Digg_getDuggByUser pipe for grisly details.) This is also probably easier on Digg, since Pipes caches repeated calls.
Jitendra: if you know a MyBlogLog ID, you can run the mybloglog.yahooapis.com/v1/user API to get details. If you run mybloglog.yahooapis.com/v1/community and ask for only one record, you should (in theory) be looking at your most current visitor ... but I see that's not always true when I compare the last face on my reader roll to the last face on the community API's return.
I think the API will be much more useful when aimed at getting an aggregate sense of the interests of your audience, and not trying to pin down each individual reader.
Where this starts to get really fun is when we look at second-order and inter-community effects. What are TechCrunch readers bookmarking on del.icio.us? What are those Boing Boing hipsters listening to on Last.fm? When we look at the tags our readers have hung on themselves and each other, what do we see? Who ARE these guys, anyway?
I'm nodding in agreement with Marshall Kirkpatrick's post on ReadWriteWeb right now: "There may be little reason to use APML [Attention Profile Markup Language] if a website can offer personalized content based on a user's tags in Del.icio.us, Flickr, YouTube, etc. all via one easy to use service, MyBlogLog. It's not open and it's not as democratic as a distributed, portable, standards based approach would be - but it's also for better baked and will soon be ready to use."
"The most recent visitor might not be you if you just got here and have not seen anything else on the site; I can't imagine the API could possibly be that fast. (I'm willing to be pleasantly surprised, though.)"
On my screen I am actually the first visitor, the API is pretty snappy ;)
Found something I don't understand this morning. If a user has exactly one tag or service, the result is an object:
{"tags":{"tag":{"name":"foo"}}}
Otherwise it's an array:
{"tags":{"tag":[{"name":"foo"},{"name":"bar"}]}}
Since my script is looking for an array, users with exactly one tag or service see nothing. I've alerted the Proper Authorities; sorry for any confusion.
Just a heads up: looks like there's a typo in the code right now... pownce is being spelled "pounce" in the generated URL. Didn't scan over them all, but that one popped out.
Thanks man!