Clojure Robot on Google Wave
I’ve wanted a little project to start learning Clojure in a bit more detail, and having got access to Google Wave a couple of weeks back, I figured a suitable challenge would be to build and deploy a simple Wave robot to Google App Engine. So I did. And may I present… CENSOR BOT!
Censor Bot (email@example.com if you have a Wave account) listens to messages posted in a wave and removes naughty swear words. It’s a pretty simple beast (about 40 lines of Clojure in all), but is non-trivial enough to serve as a good first project. In this post I’ll go through the process of getting a Clojure Wave robot built, hosted on GAE and accessible in your wave account.
Firstly we have some dependencies:
- Java 6
- A Google App Engine account (sign up here)
- A Google Wave account
- The Google App Engine SDK
- Clojure 1.0
Firstly, download and install the Google App Engine SDK from here. Just unzip the SDK (latest is v1.2.2) somewhere useful. Whilst you’re there, it’d be a good idea to set up your GAE account too. Once you’re signed in (at http://appengine.google.com) you can click the “Create an application” button and reserve your app identifier. Note this down as you’ll need it later.
Next, ensure you’re running Java 6; you should see the following:
$ java -version
java version "1.6.0_13"
Java(TM) SE Runtime Environment (build 1.6.0_13-b03-211)
Java HotSpot(TM) 64-Bit Server VM (build 11.3-b02-83, mixed mode)
If you’re running a pre Java 6/JDK 1.6 version, you’ll need to upgrade as the Wave API only runs on Java 6. I suffered a couple of gotchas here on OS X. Firstly, open Applications/Utilities/Java Preferences.app and update the list so Java 6 is selected. This ensures code runs under that version of the JVM. However, Ant will still try and compile under JDK 1.5. You have to adjust your JDK symlinks too.
$ cd /System/Library/Frameworks/JavaVM.framework/Versions
$ sudo rm CurrentJDK
$ sudo ln -s 1.6 CurrentJDK
You’ll also need to download and install Clojure. Instructions here.
Now the fun can begin. cd to your favourite project location and run:
$ git clone git://github.com/indmill/censorbot.git
This has everything you need to write a basic Clojure Wave robot. The only things you’ll need to change are:
- In build.xml, update the sdk.dir property to point to your GAE SDK location.
- In war/WEB-INF/appengine-web.xml, change the application to be your GAE application identifier.
- That’s pretty much it, unless you’re feeling brave and want to rewrite my newbie Clojure code.
You should just be able to run:
$ ant deploy
now to deploy the app to GAE. It may complain that your GAE credentials are not stored. I had to run:
$ path/to/gae-sdk/bin/appcfg.sh update war
And voila, you should be able to add your newly deployed censorbot to a Wave and off you go. The censorbot doesn’t censor many actual rude words yet, but feel free to edit its dictionary.
The code itself is very straightforward if you have done any Clojure. The main entry point from Wave-land is the function:
(defn -processEvents [this bundle] (let [wavelet (.getWavelet bundle)] (welcome-if-new bundle wavelet) (doseq [event (blip-submitted-events (.getEvents bundle))] (censor (.getBlip event)))))
It retrieves the wavelet from the event bundle, welcomes itself to the wave then filters out BLIP_SUBMITTED events and censors the contents. I’ve tried to make it as functional as I can but proper Clojure hackers out there could probably tidy it up a lot. Anyway, I welcome any comments, and if my instructions have missed any steps let me know and I’ll improve. Thanks.