Try the Diagram Editor now!

Use the Editor in Google Wave (discontinued).

Watch the screencasts showing the editor in Google Wave or Google+ Hangouts.

Check out our MIT-licensed source code on GitHub.

December 4, 2009


Did you ever wonder if it is spelled misbehavior or missbehavior? Now there is an gadget for that! Just punch in both possible spellings into Google Fight and hit Fight! The word with the most Google hits will win and is the correct spelling - probably.But that's not all! There are endless use cases for Google Fight:
  • Who is more popular? Michael or Peter? Just ask Google Fight.
  • Which place is nicer? Berlin or Potsdam? Google Fight knows the answer!
  • What should we eat for lunch? Pizza or Burger? Hit the Fight-Button and know what is good for you!
  • Should I cheat on my girlfriend? Yes or No?
Try it out for yourself and visit our public wave, where we provide an installer for this gadget. It's as easy as 1-2-3.

We would also like to point out, that Google Fight is fully collaborative. You see when other participants of the wave edit the words in the gadget just as you would expect from Google Wave.

Warning: If your life depends on it, do not depend on Google Fight!

Interested? Try and install gadget! Your feedback is very welcome!

December 2, 2009

Invity - Behind the Scenes

We hope you enjoyed Invity, our group management robot for Google Wave. Now we want to reveal the code behind our robot and share our thoughts and problems with you.

At first, we developed Invity as a pure robot without any sophisticated user interface. One had to type something like " myFriends" in a Blip to save a group. However, we quickly realized it would be cool to have a gadget that allows more comfortable user interaction. But as gadgets are not able to invite people, it was obvious to us that the robot has in some way to interact with the gadget. The reason is that the gadget has to delegate the user input to the robot and the robot has to push the info about a user's groups to the gadget.

We use the state of the gadget to save the input of a user.
When someone clicks on "Invite!", we do the following:
var state = wave.getState();
var viewer = wave.getViewer().getId();
var value = gadgets.json.stringify({ 'action' : action, 'groupName' : groupName, 'viewer' : viewer });
state.submitValue('command', value); 
On the robot side, we parse and execute the action the user specified like this:
JSONObject json = new JSONObject(command);
String action = json.getString("action");
String groupName = json.getString("groupName");
String viewer = json.getString("viewer");
if (action.equals("save")) {
    saveGroup(event, groupName, viewer);
The saveGroup method look like this:
private void saveGroup(RobotMessageBundle bundle, String groupName, String viewer) {
    PersistenceManager db = PMF.get().getPersistenceManager();
    List<String> participants = bundle.getWavelet().getParticipants();
    List<Group> groups = fetchGroupByName(groupName, viewer, db);
    if (groups.isEmpty()) {
          Group group = new Group(groupName, participants, viewer);
We were quite impressed how easy and reliable this saving of groups in the Data Viewer works. However, from the robot to the gadget, the communication does not work quite that well. When we tried to display the current groups of a user in the gadget, we encountered a strange behaviour:

We use the setProperty method in the following way to save the groups of all participants of a wave in the gadget state:
String allGroups = createJSONFromGroups(participants);
gadget.setProperty("allGroups", allGroups); 
We expected that this call would trigger the updateState callback as specified on the gadget side:
Unfortunately, the displayState method is not called when the robot changes the gadget state. So we had to build an ugly workaround which deletes the gadget and reinserts it after the robot commits a change:
private void reinsertGadget(RobotMessageBundle bundle) {
    List<Blip> allBlips = bundle.getWavelet().getRootBlip().getChildren();
    Blip gadgetBlip = deleteGadgetFromBlips(allBlips);
    Gadget newGadget = new Gadget(gadgetURL);
    updateGadgetState(bundle, newGadget);
We're not really happy with this solution, but as Google knows about this issue, we hope we can delete it soon.


You can get the full source code for the Robot and for the Gadget at Feel free to modify and reuse under the terms of the MIT License (

If you have not tried out Invity yet, just add to one of your waves.
Web Statistics
Embed Wave to Blogger