Twittey-Bot :: Technical Details

Looks like Guy Kawasaki was talking (point 6) about using twitter for web 2.0 publicity again, at the recent Nasscom - Tweetup meet. Twitteybot is just that, a dead simple tweet automator :). This post deals with the technical details. The source code is available here. The overall architecture of the website is simple.
The application is hosted on the Google App Engine and uses the built in persistance, user accounts, cron jobs and tasks.
Starting from the persistence layer, there are are two major objects; one to store the twitter account auth tokens, and the other to store actual tweets that have to be scheduled. There is another object to stores the application properties and it primarily stores the twitter oauth key and secret. I put them in the database instead of a properties file to enable revocation, etc without having to redeploy the application.
The servlet layer simply fetches this data using either the TwitterAccountManager or the StatusManager classes. The UI makes direct calls to these classes to manage the data at the backend.
The UI is simply an interface to modify the objects at the backend. The only other functionality are the tool boxes at the left that let a user schedule and shrink the tweets. These are purely javascript functions that modify the values to be sent to the backend.
The cron job runs every minute, checking for tweets, older than the current time. If it finds any, it adds them to a taks queue. The Task queue looks at the tweets, one after the other and is responsible for posting them to twitter. The twitter oauth credentials are saved in memcache as they would not change very often.
A lot of code has been written, and a lot more need to be. Please take a look at the site and criticize, suggest or even appretiate.
Here are the list of issues that I would be working, once I get back. I would definitely welcome help, so if you are interested in churning out some code, do drop me a comment.

Finally, I have a website !!

A weekend of hacking, some static HTML pages spiced with CSS and Javascript and I have a presence on the internet. I just published the last commit to github and have a decent looking website up and running. The site is available here
Some of the requirements that I had set are
  • Progressive Javascript, the site should work without CSS/Javascript also
  • Only static content would be possible as the site is hosted on github
  • Most contents of the site have unique URLs. 
I would not rant on the design or the code of the site, instead I would simply highlight two interesting challenges that I came across while building the site.

The site is static, but I wanted the home page to have posts from this blog displayed. I also wanted to show randomly picked projects too. The feedburner javascript had all the content preceeded with a document.write. Since I was loading this content using jquery's $.load, document.write was executed in the window content and hence, overwrote the page contents. The way this was solved was to load all this content in an iFrame. The iFrame calls a method in the container document with the HTML content that is displayed with the formatting.

The second challenge was having fragment identifier as a navigator. Though a well known pattern, the only deviation in this case was that the module names and HTML should be the same. The javascript does not poll for the URL fragment identifier yet, but it does change when the user navigates to a project, etc.

Please do check out the site which is more of a cataloged archive for this blog.

I can see the future .. thats why I schedule my tweets

That was a neat little catch-phrase to introduce the project that I have been working over the last weekend - Time2Tweet. The project helps compulsive [or lazy :) ] "tweeters" to  schedule tweets that are uploaded file.
The idea started when I was looking for a tool that lets me automate tweets, typically send things like quotations, geek humor and other things to my twitter account. There are tools to update twitter from RSS feeds or create tweet publicity, but nothing for bulk scheduling.

The application is simple; all that the use does is logs into the application (the application is on Google App Engine, so logins use Google Accounts) and authorizes twitter accounts. Once this is done, the user uploads a file that contains one tweet per line. There are scheduling options that let the user specify the time interval or the total duration all the tweets should take.
The user interface was inspired from Google Reader, and the application on App Engine uses features like cron jobs and tasks lists to get the job done.
One discussion that came up was regarding the requirement to have a use log in with Google credentials. Though this method allows users to manage multiple accounts, most individuals would schedule only with one account. Maybe I would fork a branch sometime soon for implementing this variant.
The typical uses of this application could be
  • Help companies send marketing messages easily
  • Bots that tweets aimed at teaching foreign languages, one tweet at a time. This, I presume, is a lot easier that reading books.
  • Create bots that quote tweets from books like the Gita, Quran or the bible.
In a post that would follow, I plan to post the technical details. In the mean time, if you would like to take a look at teh code, it is hosted here and the application is available at http://time2tweet.appspot.com.

Duration Input Component

Free from, input box style controls are always fascinating. Its always a pleasure to type in the dates and the computer understand it automatically. I came across the  a Date processing library that parses such free form dates. I was working on the TwitteyBot over the weekend and I needed a component where a user could enter time durations.
As a requirement, the user would enter durations that resemble any of the following text
  • 1 day, 10 hours and 15 minutes
  • 1 minute + 1 hour
  • Duration is 1 minute 
I tried writing a parser, similar to Date.js and here it how it looks like.
The source code for parsing this is simple and self explanatory.