Google Wave – My First Bot

Sunday, November 1st, 2009

Last week, I went to the Google Technology User Group in London, which was all on the subject of Google Wave.  Lars and Steph, of Google Wave video, and Google Maps fame gave an excellent talk on Wave, how it was doing, where it was going, and the challenges they’re still facing in getting Wave ready for prime time and a public release.

I’ve had a developer account for some time now, and the talk finally got me motivated into messing around with more of the APIs.  So I created a bot.  Then I created another one.  Because the first one didn’t do anything.

1.  Get Eclipse

So far, the choices for creating Google bots are rather limited because there are rules that they must be hosted on AppEngine (for now).   So first off, get Eclipse – because it makes the entire process of doing that incredibly easy.  You can download Eclipse here.

2.  Get the AppEngine SDK.

Once you’ve got Eclipse installed and running, go to Help -> Install New Software.  Enter this URL to get at the Google AppEngine SDK.

http://dl.google.com/eclipse/plugin/3.5

3.  Create your project.

Go to File->New, and select Web Application Project.  If you don’t have that option, something’s gone wrong with your SDK download, so check step 2.

Uncheck the Googe Web Toolkit, we don’t need that.  But otherwise fill out the Project Name and Package as you see fit.

4.  Add the libraries from the Wave extensions SDK

Download wave-robots-api.jar, json.jar, and jsonrpc.jar and drop those into your project under war/WEB-INF/lib/.

Once you’ve done that, select File->Refresh, then Project->Properties from the main menu, and select Java Build Path.  Click Libraries, and Add JARs, to select the three that you’ve just added.

5.  Write your servlet class.

This is where the bulk of your bot logic (or lack of it), goes.

package helloworld;
import com.google.wave.api.*;
public class HelloWorldServlet extends AbstractRobotServlet {
	public void processEvents(RobotMessageBundle bundle) {
		for (Event e: bundle.getEvents()) {
			if (e.getType() == EventType.BLIP_SUBMITTED) {
			Blip blip = e.getBlip().createChild();
			TextView textView = blip.getDocument();
			textView.append("Hello.  Are you the world?");
			break;
			}
		}
	}
}

6. Add a servlet mapping.

Edit the file, war/WEB-INF/web.xml and add a servet-mapping just below the one you have already.

<servlet-mapping>
<servlet-name>HelloWorld<servlet-name>
<url-pattern>/_wave/robot/jsonrpc</url-pattern>
</servlet-mapping>

7. Add a capabilities file.

Add a folder under war/_wave. Create a file under that called capabilities.xml. This tells Wave which events your robot is going to respond to. In our case, we’re going to respond whenever a blip is saved (blip_submitted)./ There is a full list of capabilities in the full api docs.

<?xml version="1.0" encoding="utf-8"?>
<w:robot xmlns:w="http://wave.google.com/extensions/robots/1.0">
<w:capabilities>
<w:capability name="BLIP_SUBMITTED" content="true" />
</w:capabilities>
<w:version>3</w:version>
</w:robot>

8.  Get an AppEngine account.

That kind of finishes off the Wave-bot.  So you’ll need an AppEngine account to continue.  So go ahead and sign up, and create an application.  Incidently, I couldn’t find my created apps since I have a Google Apps / Domain account.  if that’s the case for you as well, you can find your apps list at http://appengine.google.com/a/<domain>.  Not sure why Google don’t detect that, but there we go.

9.  Deploy to AppEngine

Click the friendly little icon ae_deploy_button from your Eclipse toolbar, and enter your details to deploy you new robot.  Try not to scream “fly my pretties” as you do so.  I dare you.  Make sure you click the App Engine Project Settings button, and provide you Application ID, the same as you created in step 8.

10.  Add your app to a wave

The address of your robot will be applicationid@appspot.com, and you can add it just like any other robot.

You should now be able to interact with your bot.

bot

And if you’d like to see my first bot in action – please drop in and say hello by adding it to your wave: insulteveryone@appspot.com.

Now. World peace.  Where did I leave that file?

Rescuscitating AMM with Amazon Web Service signed requests

Wednesday, August 26th, 2009

A few days ago Amazon added a requirement to their AWS that all requests to the service be signed, lest they be rejected. I’ve been using Sozu’s excellent Amazon Media Manager plugin for a while now to manage the currently reading list on this blog. It’s been a great way to keep track of exactly what I have read (avoiding the need to, like, remember), as well as masking my illiteracy by pasting a giant list of what is commonly known as airport trash.

Unfortunately, this is one plugin that hasn’t been updated in quite a while (after all, if ain’t broke…), so it broke. Being the sort of developer that’s quite happy to pick up a block of php and hack it until it works, I stumbled across this blog entitled ‘Amazon® AWS HMAC signed request using PHP‘, which has a function to download.

So to fix AMM:

1. Download that file, and copy the contents into the bottom of amm_parser.php.

2. In the same file (amm_parser.php), replace your _setUrl function with this one:

function &_setUrl() {
	//Build URL from base URL and other required parameters
	switch ($this->_locale) {				
		case 'uk':
			$region = 'co.uk';
			break;
		case 'de':
			$region .= 'de';
			break;
		case 'jp':
			$region .= 'co.jp';
			break;
		case 'fr':
			$region .= 'fr';
			break;
		case 'ca':
			$region .= 'ca';
			break;
		case 'us':
		default:
			$region = 'com';
			break;
	}
	$public_key = "< < Your Access Key ID >>";
	$private_key = "< < Your Secret Access Key >>";
	$url = aws_signed_request($region, array(
			"Operation"=> "ItemSearch",
			"Keywords" => $this->_parameters[Keywords],
			"ResponseGroup"=>$this->_parameters[ResponseGroup],
			"SearchIndex" => $this->_parameters[SearchIndex],
			"AssociateTag" => urlencode($this->_associate_tag)),
			$public_key, $private_key);
	return $url;
}

3. Oddly enough, this new method requires a private secret key which Amazon recommends to not give to anyone. So I’m not going to post mine here, even though it’s required for the plugin to work. So before I ponder that particular nugget of madness, you’ll need to sign up for an AWS developer account, and find your own keys via the Access Identifiers page. These need to be added into the function above.

That should be enough to get you back up and running again, although selfishly I’ve only really tested it for my needs alone. So please let me know if it works, or fails miserably.

For all the legal bits, I’m not at all affiliated with Amazon or Sozu – so please use at your own risk :)

C# Joins with Linq and Lambdas

Saturday, August 8th, 2009

I’m always forgetting the syntax for lambda joins in C#, because I never use them enough and get bored looking for reminders enough that I just revert back my old ways and use the query expression instead. So rather than find a good tutorial and bookmark it, I’ll post it here instead. By the time it falls off the front page, I’ll just about have remembered how to do it without needing this anyway :)

Query Syntax

var products = from audio in DbContext.DataContext.ProductAudios
join product in DbContext.DataContext.ProductAudios on audio.ProductId equals product.ProductId
select new { Product = product, Audio = audio };

Lambda Syntax

var products = DbContext.DataContext.ProductAudios.Join(
                DbContext.DataContext.Products,
                audio => audio.ProductId,
                product => product.ProductId,
                (audio, product) => new { Product = product, Audio = audio });

It might look like more code because of my formatting, but I find the lambda syntax much convenient when chaining queries together with other where’s and groupby’s, especially when that might be split across different methods. It also isolates your join nicely, whereas I find the query syntax will start to get particularly unreadable with more complex queries.

Last but not least, another piece of linq-join-related syntax I’m finding myself always having to look up a lot is for left outer joins. Fortunately I always end up at MSDN for that one, so I’ll just link to it here:
How to: Perform Left Outer Joins

Running Ruby methods within C# / .NET

Thursday, July 23rd, 2009

The last example might have been a little too trivial, even by my standards. Even I struggled to imagine a scenario where I might ever need to use it. So hopefully this one will be a little bit more interesting and demonstrate something more useful.

Useful, but still just as simple as the previous examples, that is. Again – you’ll need your references from the downloaded IronRuby bin/ folder. And as you’ve come to expect, a very simple ruby script defining a lambda function.

$m = lambda {
            a = Array.new
            a.push(2, 3)
            (4..50).each do
               |i|
               (2..(Math.sqrt(i).ceil)).each do
                  |thing|
                  if (i.divmod(thing)[1] == 0)
                     a.push i
                     break
                  end
               end
            end
            return a
         }

From this, we’ll get an array of the prime numbers. The function can then be executed rather nicely from within your .NET code like this:

var ruby = Ruby.GetEngine(Ruby.CreateRuntime());
ruby.Execute(@"
    $m = lambda {
//.. snip..
            return a
         }
");
var rubyContext = Ruby.GetExecutionContext(ruby);
var m = (Proc)rubyContext.GetGlobalVariable("m");
var rubyArray = (RubyArray) m.Call();
foreach (var o in rubyArray)
{
    Console.Write(string.Format("{0},", o));
}

Now we’re really starting to leverage that syntactical beauty of ruby within .NET and jumping (almost) seamlessly between the two. Now, I really should do some demos on something more useful than prime numbers, and perhaps get into one of the big areas of interest of Ruby – testing frameworks. Not tonight though :)

Demo project available as usual:

Executing complete (Iron)Ruby scripts from within native C# / .NET

Wednesday, July 22nd, 2009

Running Ruby code as-is within .NET is almost too simple to even write home about. In fact I almost didn’t, but after I wrote it the solution stared up at me with its big brown eyes, and I couldn’t resist. I’m not totally sure when I’d ever need to use this, but perhaps taking some legacy Ruby scripts where I don’t really care about the results, and still want to run them amongst some other .NET tasks. It might come up in some obscure unit testing one day. You never know.

So, this still serves as an example of how simple it can be to run ruby scripts within .NET. We’ll get to making use of some return values, and running individual methods in the next post.

Following on from the last example, the following ruby script prints all the prime numbers between 1 and 50.

state = Numeric.new
print "2,3,"
(4..50).each do
   |i|
   (2..(Math.sqrt(i).ceil)).each do
      |thing|
      state = 1
      if (i.divmod(thing)[1] == 0)
         state = 0
         break
      end
   end
   print "#{i}\," unless (state == 0)
end

With the ruby script complete (you can also run this with the ir.exe that ships with IronRuby if you like)… Next start up a new project within Visual Studio, and add some references from your downloaded IronRuby bin folder (IronRuby.dll, IronRuby.Libraries.dll etc…).

You only need a few lines of code to execute your ruby script.

using IronRuby;
// ..
var runtime = Ruby.CreateRuntime();
runtime.ExecuteFile(@"ruby/run.rb");

As before, you can download the full example to check it and run for yourself. And also as before, you will also need IronRuby.