Javascript (JQuery): Social networking feeds all in one place

Today we are going to get feeds from Twitter, Facebook, Youtube and Flickr all in one place for your website using JSON and the JQuery library:

Be careful on this page with wrapped lines!

Firstly we declare the jquery library in our head section (obviously download it first and change the path to match your system:

<script src="lib/jquery-1.4.2.min.js"></script>

Now we define a div to put all the feeds in:

<div id="l_tweets"><br /><br />Social Networks Update:</div>

Now let’s write some Javascript! We’ll start with Twitter:

<script type="text/javascript">
//twitter - use your own username in the getJSON line
//we'll get the feed and work out how many days ago the content was posted
$.getJSON("http://twitter.com/statuses/user_timeline.json?screen_name=username&include_entities=true&count=5&callback=?",
function(data){
$.each(data, function(i,item){
dp = item.created_at.split(" ");
cr = Date.parse(dp[1]+' '+dp[2]+' '+dp[5]);
tm = (new Date()).getTime();
dy = (tm - cr) / 86400000;
ct = item.text;
ct = ct.replace(/http:\/\/\S+/g,'<a href="$&" target="_blank">$&</a>'); //make urls into links, do the same for hashtags etc:
ct = ct.replace(/\s(@)(\w+)/g,' @<a onclick="javascript:pageTracker._trackPageview(\'/outgoing/twitter.com/\');" href="http://twitter.com/$2" target="_blank">$2</a>');
ct = ct.replace(/\s(#)(\w+)/g,' #<a onclick="javascript:pageTracker._trackPageview(\'/outgoing/search.twitter.com/search?q=%23\');" href="http://search.twitter.com/search?q=%23$2" target="_blank">$2</a>');
//add the feed to the div
$("#l_tweets").append('<div> '+ct+'<br />'+Math.round(dy)+' days ago</div><br />');
}); //each
} //function
); //json

Note that the # and @ replace lines may wrap here, but they should be on one line.

[EDIT – this no longer works for Facebook since they change their authentication methods, please see my new post to get the Facebook feed]

Let’s do the same thing for Facebook now – getting the date into a format that Javascript understands is a little more complicated this time:

//facebook - again use your own username
$.getJSON("http://graph.facebook.com/username/posts?limit=5&callback=?",
function(json){
$.each(json.data, function(i,fb){
if (fb.type=='video' || fb.type=='link') {
if (fb.link) fb.message = '<a href="' + fb.link + '" target="_blank">' + fb.name + '</a>';
else fb.message = '<a href="' + fb.source + '" target="_blank">' + fb.name + '</a>';
}
else fb.message = fb.message.replace(/http:\/\/\S+/g,'<a href="$&" target="_blank">$&</a>');
var d=new Date();
dt1 = fb.created_time.split("T");
dt2 = dt1[0].split("-");
d.setDate(dt2[2]);
d.setFullYear(dt2[0]);
d.setMonth(dt2[1]-1);
cr = Date.parse(d);
tm = (new Date()).getTime();
dy = (tm - cr) / 86400000;
$("#l_tweets").append('<div>' + '' + fb.message + '' + '<br />(' + Math.round(dy) + ' days ago)</div><br />');
}); //each
} //function
); //json

The quotes either side of the fb.message counteract an Internet Explorer problem where content appears as undefined. Now on to Youtube, this is quite similar, but we are throwing images into the mix:

//youtube - as ever, replace your username
$.getJSON('http://gdata.youtube.com/feeds/users/username/uploads?alt=json-in-script&max-results=5&callback=?',
function(data) {
$.each(data.feed.entry, function(i, item) {
var published = item['published']['$t'];
var url = item['media$group']['media$content'][0]['url'];
var media_title = item['media$group']['media$title']['$t'];
var media_descr = item['media$group']['media$description']['$t'];
var thumb = item['media$group']['media$thumbnail'][0]['url'];
var d=new Date();
dt1 = published.split("T");
dt2 = dt1[0].split("-");
d.setDate(dt2[2]);
d.setFullYear(dt2[0]);
d.setMonth(dt2[1]-1);
cr = Date.parse(d);
tm = (new Date()).getTime();
dy = (tm - cr) / 86400000;
//note this next part is all one line
$("#l_tweets").append('<div><a href="' + url + '"><img src="' + thumb + '" width="64" height="36"><br />' + media_title + ' (' + media_descr + ')</a><br />(' + Math.round(dy) + ' days ago)</div><br />');
}); //each
} //function
); //json

Just one more to go – Flickr. A couple of things to note here. Firstly, your user id in the JSON link is not your username, you can map your username to the id here: http://idgettr.com. Secondly, all the other feeds have have a method of limiting results (I have chosen 5 results each so far). For this feed, we must create our own limiter.

//flickr - see the nore above about your user id
var i = 0;
$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?id=user_id&lang=en-us&format=json&jsoncallback=?",
function(data){
$.each(data.items, function(i,item){
if (i<5) {
var d=new Date();
dt1 = item.published.split("T");
dt2 = dt1[0].split("-");
d.setDate(dt2[2]);
d.setFullYear(dt2[0]);
d.setMonth(dt2[1]-1);
cr = Date.parse(d);
tm = (new Date()).getTime();
dy = (tm - cr) / 86400000;
//this is all one line again
$("#l_tweets").append('<div><a href="' + item.link + '"><img src="' + item.media.m + '" width="64" height="36"><br />' + item.title + '</a><br />(' + Math.round(dy) + ' days ago)</div><br />');
i++;
} //i
}); //each
} //function
); //json

In the websites I have implemented this on, I haven’t needed to return the feeds in date order (currently they are in order of social network). To order them, this is what I would do:
1) create an array to hold the feeds
2) instead of appending the feeds to the div, add them to the array with days first, then a delimiter, then the feed
(e.g. socnet_updates.push(Math.round(dy)+’_DELIMITER_<div>’+ct+'<br />’+Math.round(dy)+’ days ago</div><br />’);)
3) after the scripts have run, wait a couple of seconds for the data to be filled out (use setTimeout counting the number of feeds returned until you have them all) and the order the array by date (use a natural order algorithm)
4) finally, iterate through the array, split the strings by your delimiter and append the second part to the div

If anyone wants me to show you that code, let me know.