This week I suddenly realized that one month ago, we implemented XFN on iknow.co.jp – the startup I’m working for. I almost completely forgot about this and I needed some 20%-google-time distraction from my day to day tasks. So I thought about doing a quick search and jacking in a simple friend finder that uses the Social Graph API. A friend finder meaning: you input your SNS-X username and you will get all SNS-X usernames that are your friends on SNS-Y, SNS-Z.

To my amazement I couldn’t find any straightforward pieces of code actually doing this. All I could find was the usual pretty printed JSON outputs. So I rolled up my sleeves and did some Javascript hacking myself.

Click here for a Demo

I wrote a Javascript class that you can easily use to enable a friend-finder on your own SNS site. Basically there are two main parameters:
  • A regular expression determining the profile URL structure of an SNS
  • The profile URL of the person to recommend friends to, eg: twitter.com/dominiek

The code should be fully customizable for your own SNS, feel free to use it however you want: (don’t forget to fetch socialgraph.js)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// callback:
function contact_found(username, is_new, on_site_name, on_profile_url) {
  // a user on this site was found and is a friend on_profile_url
  // this is also where the is_friend_already? check goes
}

// callback:
function contact_search_status(percentage) {
  // progress report, might take a while to query everything
}

// setup regexp for this SNS
var site_regexp = new RegExp(/http:\/\/www\.iknow\.co\.jp\/user\/([^\/]+)/);

// setup library and pass in callbacks (contact_search_status is optional)
var social_graph = new SocialGraph(site_regexp, contact_found, contact_search_status); 

// recommend for user dominiek
social_graph.contacts_for('http://www.iknow.co.jp/user/dominiek'); 

When doing a search, about 8 to 40 calls are done to the SocialGraph API to walk through all the data. That’s one of the reasons why I really love JSON – all of this stuff is done on the client side.

Please note that any profile URL used in gathering friends data has to be referred to or must refer some other XFN relationships. The more ‘me’ and ‘contact’ links, the better the results will be. iknow.co.jp is actually a very good example of this.

Note: a fellow developer (Zev Blut) pointed out to me that instead of fooling around with too many regular expressions it’s good to look into Node Canonicalization

Last year I discovered the website Wakoopa.com. At first I didn’t quite get the usefulness of using Wakoopa but after using it I really came to love it. Wakoopa let’s you broadcast your software activity usage by installing a little tray icon. On your Wakoopa profile you can track your software usage trends. Since I’m a proud Mac user and believe in radical transparency I am broadcasting the usage of my software to the world:

Right now on this blog you can see my Latest Tweets and Interesting Links. That data get’s updated everytime I bookmark something (using Delicious) or tweet something (using Twitter). I really like the real-time and heartbeat aspect of it.

While taking a shower a couple of weeks ago I was thinking of using the Wakoopa data to make a little widget. Most of my time is spend in front of my Macbook, so it would be nice to display what I’ve been doing the last hours on my Mac. I want to display it in a simple single sentence like “Recently I’ve been programming”. I don’t want to overload my visitors with too much data. Of course when they click on the sentence they are taken to my Wakoopa profile

I contacted the Wakoopa team a couple of weeks ago to ask whether they could provide this activity data in form of a JSON feed (essential for making a badge/widget). They replied to me within a couple of hours and implemented it! That’s agile baby! Unfortunately I wasn’t so agile on my private projects and only build my widget yesterday.

Using the just released Wakoopa JSON api I’ve written a big ugly piece of Javascript that serves as the widget:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<script type="text/javascript">
  var wakoopa_activity = {'Design': 'designing',
                          'Communication': 'mailing and chitchating',
                          'Browsers': 'surfing the web',
                          'Programming': 'coding like hell',
                          'Audio': 'slacking off',
                          'Video': 'slacking off', // jacking off? 
                          'Tools': 'doing some funky stuff'}
  var wakoopa_username = null;
  
  function wakoopa_doing_now(data) {
    var app = null;
    var activity = '';
    for(var i = 0; data.length > i; i++) {
      if (app == null || app.active_seconds <= data[i].active_seconds) {
        app = data[i];
      }
    }
    if(app.category) {
      activity = wakoopa_activity[app.category.name];
      if (!activity) {
        activity = app.category.name;
      }
      if (app.category.name == 'Tools') {
        if (app.name == 'iTerm' || app.name == 'Terminal') {
          activity = 'unix fu';
        }
      }
    }
    title = 'my software usage on wakoopa.com';
    document.getElementById('wakoopa_activity').innerHTML = '<a href="http://wakoopa.com/' + wakoopa_username + '" alt="' + title + '" title="' + title + '">Recently I\'ve been ' + activity + '.</a>';
  }
  
  function wakoopa_recent_activity_for(username) {
    var script = document.createElement( 'script' );
    wakoopa_username = username;
    script.type = 'text/javascript';
    script.src = 'http://wakoopa.com/' + username + '/recently_used.json?callback=wakoopa_doing_now';
    document.getElementsByTagName('head')[0].appendChild( script );
  }
</script>
<img style="float: left; margin-right: 6px" src="http://wakoopa.com/favicon.ico"/>
<div id="wakoopa_activity"></div>
<script type="text/javascript"> wakoopa_recent_activity_for('dominiek'); </script>

You can copy and paste this in your blog to display what you’ve been doing recently on your machine. Make sure to replace my username with yours.

Today and yesterday I’ve spend another couple of hours coding and designing away on my (autistic) little project Wigitize.com. I’m keeping an exact log of the amount of hours I’m spending and what’s happening so I will publish some full-exposure articles about how to build a project like this.

Currently these are the things that still need to be done:

  • enabling people to choose a style for their widget
  • write a simple API and a page to show how it works
  • optimize backend so that a background worker will be used
  • allowing people to ‘grab the grabber’ so that they can offer widgets of their own content to their users
  • renting a machine with bandwidth, I’m thinking of slicehost.com (much cheaper than EC2)
  • rethinking the name WIGITIZE. It sounds good to my Dutch-English, but it might not for Natives.

Another little sneak preview:

click image to expand

I've wanted to do this for a while now, basically a service that allows you to convert RSS feeds into embeddable widgets. (Little geeky, yes I know, more about this later!)

click to view the mocked up design:


Dominiek.com, Now with Extra Data

on December 02, 2007

This week, a cool Japanese coder reminded me of the importance of blogging: it is the best resume out there. Also, it is you permanent footstep into the eternal virtual world.

This week I have been playing around with the JSON feeds that twitter offers. This is how I got the 'What am I doing now?' in the top here. I also did it for delicious. I am very excited about these JSON widgets and I will soon start coding and blogging more about it. Too bad last.fm doesn't have them yet.

Soon, I will also start blogging about the project I'm consulting for: