JavaFX Twitter Client

By Rakesh Menon, April 21, 2009

Tweeter is a client for twitter. It uses twitter's REST API. User can view all public twitter status and that of friends. The status of logged-in user can be added and deleted from this client.

Following twitter APIs are used

Understanding the Code

Public statuses are obtained from RSS feed using RssTask. The task is scheduled to update every 1 minute. In onItem we get the item instance from which message is retrieved.

Source Code
    
        feedTask = RssTask {
            
            location: "http://twitter.com/statuses/public_timeline.rss"
            interval: 60s
            
            onChannel: function (channel : Channel):Void {
                delete statuses;
            }

            onItem: function(item : Item): Void {
                var title = "{item.title}";
                var index = title.indexOf(":");
                var user = title.substring(0, index);
                var message = title.substring(index + 1);
                insert Status {
                    text: message
                    user: User {
                        name: user
                    }
                } into statuses;
            }

            onException: function(ex) : Void {
                onException("{ex.getMessage()}");
            }
            
            onDone: function(): Void {
                updateStatus(statuses);
            }
        }
        feedTask.start();    

For retrieving status of friends, the user is authenticated. A new HttpHeader instance is created using HttpHeader.basicAuth(user, passwd) API. The header is added to HttpRequest header for authentication. Request is submitted to statuses/friends_timeline. List of status from friends is returned if user is successfully authenticated. If not, an exception is thrown.

Source Code
    
    function updateStatusList() : Void {

        var httpHeader = HttpHeader.basicAuth(user, passwd);
        var httpRequest = HttpRequest {

            location: "http://www.twitter.com/statuses/friends_timeline.xml"
            headers: [ httpHeader ]

            onInput: function(is: InputStream) {
                try {
                    StatusParser{ updateStatus: updateStatus }.parse(is);
                } finally {
                    is.close();
                }
            }

            onException: function(ex: java.lang.Exception) {
                onException("{ex.getMessage()}");
                show = false;
                loggedIn = false;
            }
            
        };
        httpRequest.start();
    }

Status is set by posting a request to statuses/update. The message is send as a Pair with key as "status" and value as message to be set.

Source Code
    
    function addStatus(message : String) : Void {

        if(not ((message != null) and (message.trim().length() > 0))) {
            return;
        }
        
        var httpHeader = HttpHeader.basicAuth(user, passwd);
        var httpRequest = HttpRequest {

            location: "http://twitter.com/statuses/update.xml"
            headers: [ httpHeader ]
            method: HttpRequest.POST

            onInput: function(is: InputStream) {
                is.close();
            }

            onOutput: function(os: OutputStream) {
                var urlConverter = URLConverter{};
                var pair = Pair {
                    name: "status"
                    value: ListItem.trimString("{message}", 140)
                };
                var encodedMessage = urlConverter.encodeParameters([pair]);
                os.write(encodedMessage.getBytes());
                os.close();
            }

            onException: function(ex: Exception) {
                onException("{ex.getMessage()}");
            }

            onDone: function() {
                updateStatusList();
            }
        };
        httpRequest.start();
    }

Every status message is associated with a message id. This is used as parameter to delete a message. A post request is sent to statuses/destroy with message id.

Source Code
    
    function deleteStatus(id : String): Void {
        
        if(not ((id != null) and (id.trim().length() > 0))) {
            return;
        }

        var httpHeader = HttpHeader.basicAuth(user, passwd);
        var httpRequest = HttpRequest {

            location: "http://twitter.com/statuses/destroy/{id}.xml"
            headers: [ httpHeader ]
            method: HttpRequest.POST

            onInput: function(is: InputStream) {
                is.close();
            }

            onOutput: function(os: OutputStream) {
                os.close();
            }

            onException: function(ex: java.lang.Exception) {
                onException("{ex.getMessage()}");
            }
            
            onDone: function() {
                updateStatusList();
            }
        };
        httpRequest.start();
    }    

End session API is used for logout. A post request is sent to account/end_session.

Source Code
    
    public function logout() : Void {

        if(not loggedIn) { return; }
        
        updateTimeline.stop();
        delete statusListItem;
        loggedIn = false;
        
        var httpHeader = HttpHeader.basicAuth(user, passwd);

        user = "";
        passwd = "";

        var httpRequest = HttpRequest {

            location: "http://twitter.com/account/end_session.xml"
            headers: [ httpHeader ]
            method: HttpRequest.POST

            onOutput: function(os: OutputStream) {
                os.close();
            }

            onException: function(ex: java.lang.Exception) {
                onException("{ex.getMessage()}");
            }
        };
        httpRequest.start();
    }

References