Build an effective Twitter stream client on top of NodeJS, using Socket.io and Twitter Bootstrap with few node.js lines of code! That’s the way I track node.js news!

To build this html5 webapp, I use Node.JS and the realtime socket library Socket.io. On top of that, the UI relies on Twitter Bootstrap!
This node.js app is simple to use, start the server, start your browser, add/remove keywords you want to track on Twitter. All of that made in a single page html5 app!
Fill free to fork me on GitHUB!
#!/usr/local/bin/node
sys = require('util');
express = require('express');
twitter = require('ntwitter');
app = express.createServer();
app.configure(function(){
app.use(express.static(__dirname + '/public'));
});
app.get('/', function(req, res, next){
res.render('/public/index.html');
});
app.listen(8080);
console.log('Server running at http://localhost:8080/');
var io = require('socket.io').listen(app);
io.set('log level', 1);
// myList handle list of streamed keywords
myList = [];
// util func to help delete val in array
Array.prototype.del = function(val) {
for(var i=0; i<this.length; i++) {
if(this[i] == val) {
this.splice(i, 1);
break;
}
}
}
CreateTwitter();
io.sockets.on('connection', function(socket) {
socket.on('data', function(action,data) {
if(action==='+') { // We add a keyword from the client
myList.push(data);
}
else { // We remove a keyword from the client
myList.del(data);
}
});
socket.on('getfilter', function() { // client ask for list of keywords we push it in myList array
socket.emit('pushfilter', myList);
});
if(myList.length!=0) { // if array not empty the stream :)
twit.stream('user',{track:myList}, function(stream) {
stream.on('data', function (tweet) {
socket.emit('message', JSON.stringify(tweet));
});
});
}
});
function CreateTwitter() {
twit = new twitter({ // add your own Twitter parameters
consumer_key: '',
consumer_secret: '',
access_token_key: '',
access_token_secret: ''
});
}
<!DOCTYPE HTML>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="bootstrap/css/bootstrap.css">
<link rel="stylesheet" href="bootstrap/css/bootstrap-responsive.css">
<title>Dashboard Node.JS + Socket.io from http://www.nodejs-news.com</title>
</head>
<body>
<div class="container-fluid">
<div class="navbar">
<div class="navbar-inner">
<div class="container">
<!-- .btn-navbar is used as the toggle for collapsed navbar content -->
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<!-- Be sure to leave the brand out there if you want it shown -->
<a class="brand" href="/public/index.html">Dashboard</a>
<!-- Everything you want hidden at 940px or less, place within here -->
<div class="nav-collapse collapse" style="height:0px;">
<!-- .nav, .navbar-search, .navbar-form, etc -->
<ul class="nav">
<li class="active">
<a href="http://www.nodejs-news.com" target="_blank" title="Node.js News web site">NodeJS News</a>
</li>
<li class="divider-vertical"></li>
<li class="">
<a href="http://www.it-wars.com" target="_blank" title="IT Wars yet another Geek">My French blog</a>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="row-fluid">
<div class="span3">
<form class="well" id="chat" >
<label>Twitter filter</label>
<input type="text" id="data" class="span2" placeholder="Add a Twitter tracker…">
<span class="help-inline">Submit an additional tracker!</span>
<button type="submit" class="btn" onclick="addTrack(); return false;" >Submit</button>
</form>
<div class="well">
<p>Twitter stream tracker(s):</p>
<div id="tracker">
</div>
</div>
</div>
<div class="span9">
<div class="well" id="twitter-stream">
<ul class="unstyled">
</ul>
</div>
</div>
</div>
</div>
<script src="/socket.io/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="/myscript.js"></script>
<script src="/bootstrap/js/bootstrap-alert.js"></script>
<script src="/bootstrap/js/bootstrap-collapse.js"></script>
</body>
</html>
myscript.js file :
var filters='';
var socket = io.connect();
socket.on('message', function(json) {
data = JSON.parse(json);
var replacePattern = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
var replacedText = (data.text).replace(replacePattern, '<a href="$1" target="_blank">$1</a>');
filters.forEach(function(str) {
var search = new RegExp(str, "gim");
replacedText = replacedText.replace(search, '<span class="label label-important">'+str+'</span>');
});
$("<li></li>").html("[" + data.user.screen_name + "] " + replacedText)
.prependTo("ul.unstyled")
.css({opacity:0}).slideDown("slow").animate({opacity:1},"slow");
});
socket.on("connect", function() {
socket.emit('getfilter', function() {
});
console.log("connected");
});
socket.on("disconnect", function() {
console.log("disconnected");
});
socket.on('pushfilter', function(f) {
filters=f;
$('#tracker').empty();
filters.forEach(function(str) {
$('<div class="alert alert-block alert-error fade in" id="'+str+'"><a class="close" data-dismiss="alert" id="'+str+'" href="#">×</a><p>'+str+'</p></div></div>').prependTo("#tracker");
});
});
function addTrack() {
socket.emit( 'data', '+', $('#data').attr('value'));
$('#data').val('');
socket.disconnect();
socket.socket.reconnect();
}
$("#tracker").delegate('a', 'click', function() {
socket.emit( 'data', '-', $(this).attr('id'));
socket.disconnect();
socket.socket.reconnect();
});
Fill free to fork me on GitHUB!