import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import java.io.IOException;
import java.util.List;
public class test {
public static void main(String[] args) throws TwitterException, IOException {
// gets Twitter instance with default credentials
Twitter twitter = new TwitterFactory().getInstance();
try {
List<Status> statuses;
String user;
if (args.length == 1) {
user = args[0];
statuses = twitter.getUserTimeline(user);
} else {
user = twitter.verifyCredentials().getScreenName();
statuses = twitter.getUserTimeline();
}
System.out.println("Showing @" + user + "'s user timeline.");
for (Status status : statuses) {
System.out.println("@" + status.getUser().getScreenName() + " - " + status.getText());
}
} catch (TwitterException te) {
te.printStackTrace();
System.out.println("Failed to get timeline: " + te.getMessage());
System.exit(-1);
}
}
}
A Twitter hot tweets viewer to show at most 10 "representative tweets" selected from the tweets of a twitter user.
There are two types of "representativeness": (1) the author's definition -- the number of like; and (2) Twitter's popularity.
Please add a twitter_config file as advised here before the following steps.
npm install
npm start
Twitter is running OAuth, so we need a server to fetch tweets from Twitter. As for the server setup, I use node.js and express.js web framework. In order to deal with Twitter's Oauth and pull data from Twitter, Twitter Libraries can help a lot, and I go with TwitterJSClient by @BoyCook. During the development, I use Gulp to automate and enhance my workflow. I also perform unit tests on the APIs of the server with Mocha and Chai. At last, I deploy the application to AWS EC2.
The diagram above shows the system architecture of first type of "representativeness": the author's definition -- the number of like. When an user visit the landing page of our server, the server returns indexV2.html. After the user enters one twitter handle, top 10 liked tweets will be displayed in the decreasing order.
On the client side, in the main.js file, the display of top 10 liked tweets is done as follows: (1) The keypress "Enter" triggers an AJAX request and expects to receive data consisting of an array of tweet IDs; (2) On receiving the expected data, Twitter's factory function twttr.widgets.createTweet() help us to dynamically generates the desired widgets; (3) The browser will show top 10 liked tweets in a decreasing order.
function apiV2 (event){
if (event.which == 13 || event.keyCode == 13) {
event.preventDefault();
var twitterID = document.getElementById("twitterID").value;
// remember to replace localhost with your site IP
var url = "http://localhost:3000/hot2?twitterID="+twitterID;
$.getJSON( url, function( data ) {
noShow.style.display= (data.length === 0) ? "" : "none";
for (var i=0; i<tweetNum; i++) {
// clear div
document.getElementById(`id${i}`).innerHTML = "";
// Twitter factory api for dynamically generating widgets
twttr.widgets.createTweet(
data[i],
document.getElementById(`id${i}`),
{
align: 'left'
})
......
}
On the server side, in the index.js file, I leverage twitter.getUserTimeline by @BoyCook to pull the most recent 200 tweets of the designated twitter ID from Twitter. Then, I sort those tweets by their number of liked and return top 10 liked tweets to the client. One enhancement could be made by replacing sort() with the help of a priority queue.
app.get('/hot2', function (req, res) {
twitter.getUserTimeline({ screen_name: req.query.twitterID, count: '200'},
error,
function (data) {
toBeSent2 = [];
data = JSON.parse(data);
// Sort tweet IDs by the number of liked
function cmp(a, b) { return b.cnt - a.cnt; };
var tweetArr = [];
for (var i=0; i<data.length; i++) {
tweetArr.push({id: data[i].id_str, cnt: data[i].favorite_count});
}
tweetArr.sort(cmp);
// Top 10 liked tweets
var topNumber = 10;
for (var i=0; i<topNumber; i++) {
if (tweetArr[i]) toBeSent2.push(tweetArr[i].id);
}
res.json(toBeSent2);
}
);
});
The diagram above shows the system architecture of second type of "representativeness": Twitter's popularity. When an user visit another landing page of our server, the server returns index.html. After the user enters one twitter handle, top 10 popular tweets will be displayed, where Twitter does not indicate how they evaluate the popularity.
The client side works very similar to the abovementioned. The difference is sending the request to another API.
On the server side, in the index.js file, I leverage twitter.getSearch by @BoyCook to pull the most 10 popular tweets of the designated twitter ID from Twitter, and return top 10 liked tweets to the client.
app.get('/hot', function (req, res) {
var q = "from:"+req.query.twitterID;
twitter.getSearch({ 'q': q , 'result\_type':'popular', 'count': '10'},
error,
function (data) {
toBeSent = [];
data = JSON.parse(data);
for (var i=0; i<data.statuses.length; i++) {
toBeSent.push(data.statuses[i].id_str);
}
res.json(toBeSent);
});
});
Unit testing on the three APIs (GET /, GET /hot, GET /hot2) of the server.
I use Gulp to help on JS file uglify and html minify.
Due to the limitation (max 200 tweets) of tweetsTwitter's timeline API, if we would like to pull more than 200 of most recent tweets, we need to check with Working with Timelines to paginate large result sets.