Here's a toolbar bookmarklet that looks for a MyBlogLog identifier on the page you're on, and uses the MyBlogLog API to dig out information about its reader roll:
You can try it here, or drag it to your bookmarks toolbar and run it anywhere else on the Web. (On IE, right-click, add to favorites, say Yes to continue past scary warning, and choose Links. You may then need to fiddle around with your Tools drop-down in order to get Links to show in your chrome.)
Astute readers will immediately recognize that some of the services we're querying don't actually have APIs, and those that do have vastly differing endpoints. To cut down on the amount of scripting required to send and receive data, I've rolled my own APIs for each of them, using Pipes.
Each takes an S parameter, the user id, and an optional N parameter, the number of items you want back from each endpoint, which defaults to 3. Output from all of these pipes looks substantially like this:
"items":[
{
"u":"http:\/\/twitter.com\/jlam\/statuses\/717107112",
"t":"jlam: Would anyone like to catch http:\/\/tinyurl.com\/3xz6kc tonite?"
},
{
"u":"http:\/\/twitter.com\/jlam\/statuses\/717097392",
"t":"jlam: @dearlazyweb a 713733562 Ben, John http:\/\/ejohn.org is writing one now. Meanwhile, see http:\/\/jQuery.com and http:\/\/learningJQuery.com"
},
{
"u":"http:\/\/twitter.com\/jlam\/statuses\/705479382",
"t":"jlam: Indeed @Coley Hong Kong has unbelievably awesome public transportation! The subway costs $0.10\/mile but profitable, and did an IPO in 2000."
}
]
If there's a thumbnail in the API, it shows up in the n object. Using Pipes eases the strain on these outside sites and provides a consistent output stream from many different sources, so a single subroutine can render all the many different results.
getActivity : function(mbl, api, nick, id) {
var callback = trueName + '_' + mbl + '_' + api + '_' + nick + '_' + id.replace(/@/, '');
window[callback] = function(z) {
var t = callback.split('_');
var mbl = t[1];
var api = t[2];
var nick = t[3];
var id = t[4];
if (t.length > 4) {
var n = t.length - 1;
for (var i = 5; i < n; i++) {
nick += '_' + t[i];
}
id = t[n];
}
if (z && z.value && z.value.items) {
var r = z.value.items;
for (var i = 0; i < r.length; i++) {
var li = document.createElement('LI');
li.className = api;
var img = document.createElement('IMG');
img.src = 'http://l.yimg.com/us.yimg.com/i/us/mbl/services/i' + api + '.png';
img.align = 'absmiddle';
li.appendChild(img);
var tx = r[i].t;
if (api == 'twitter') {
var tx = tx.replace(/http:\/\/([^\s,-]*)/gi, '<a href="http://$1" target="_blank">http://$1</a>').replace(/@([^\s,.!-]*)/gi, '@<a href="http://twitter.com/$1" target="_blank">$1</a>');
r[i].u = '';
}
if (r[i].u) {
var a = document.createElement('A');
a.href = r[i].u;
a.target = '_blank';
if (r[i].n) {
var img = document.createElement('IMG');
img.className = 'v';
if (api == 'flickr') {
img.className = 'q';
}
img.align = 'absmiddle';
img.src = r[i].n;
a.appendChild(img);
li.appendChild(a);
var a = document.createElement('A');
a.target = '_blank';
a.href = r[i].u;
}
} else {
var a = document.createElement('SPAN');
}
a.innerHTML = tx;
li.appendChild(a);
$.s.c.bd[mbl].appendChild(li);
}
}
$.f.addServiceIcon(mbl, api);
$.f.removeScript(callback);
};
if (id) {
nick = id;
}
var url = 'http://pipes.yahoo.com/kentbrew/blogjuice_' + api + '?_render=json&_callback=' + callback + '&s=' + nick;
$.f.runScript(url, callback);
}
This function is almost entirely generic; only a couple of exceptions (to remove the @ from Flickr ids, apply a special class name to Flickr thumbnails, and hotlink URLs in Twitter tweets) come into play. Feel free to clone or use my Pipes for your projects; they're all published and available.
We're using some techniques from Case-Hardened JavaScript here, most notably the practice of creating a single anonymous variable and a private global to hang all the code from; references to $.f and $.s refer to functions and structure.
When we create our dynamic script tags, we're naming them with window[callback] and passing information about what their user IDs, service nicknames, and API endpoints are inside the callback name. This allows us to remove each dynamically-generated script tag from the inside, once it's run.
To filter API output tx, we double down on our regular expressions. The first looks for http://; the second looks for an @:
var tweet = tx.replace(/http:\/\/([^\s,-]*)/gi, '<a href="http://$1" target="_blank">http://$1</a>').replace(/@([^\s,.!-]*)/gi, '@<a href="http://twitter.com/$1" target="_blank">$1</a>');
Adam Platti, Andrew Wooldrige, Aramys Miranda, Ash Patel, Ava Hristova, Bill Scott, Bob Zoller, Bradley Horowitz, Cameron Marlowe, Chad Dickerson, Chanel Wheeler, Chip Morningstar, Chris Goffinet, Christian Heileman, Dan Theurer, Dav Glass, Dave Balmer, David Filo, David Flanagan, Doug Crockford, Dustin Diaz, Ed Ho, Eric Marcoullier, Eric Wu, Ernie Hsiung, Gina Groom, Havi Hoffman, Hedger Wang, Ian Kennedy, Ian Lamb, Isaac Schleuter, JR Conlin, Jason Schupp, Jean-Paul Cozzatti, Jenny Han, Jeremy Gillick, Jeremy Zawodny, Jimmy Byrum, John Greene, Jonathan Trevor, Julian Lecomte, Kevin Brown, Lauri Voss, Leslie Sommer, Luke Wroblewski, Matt McAlister, Matt Sweeney, Micah Laaker, Mike Lee, Nate Koechley, Nathan Arnold, Nicholas Zakas, Norm Francis, PPK, Paul Hammond, Randy Farmer, Scott Schiller, Sean Michael Imler, Steve Souders, Steven Wheeler, Tenni Theurer, Thomas Sha, Tim O'Reilly, Todd Klootz, Todd Sampson, Tom Coates, and (most of all!) Vickie Brewster.