Java, Eclipse and Web programming Tutorials
Follow me on twitter

Google Wave - Tutorial

Lars Vogel

Version 1.3

02.01.2010

Revision History
Revision 0.129.08.2009Lars Vogel
First version
Revision 0.230.08.2009Lars Vogel
Added embedded
Revision 0.301.09.2009Lars Vogel
clean-up
Revision 0.402.09.2009Lars Vogel
more information
Revision 0.503.09.2009Lars Vogel
Screenshot of Wave, first working robot
Revision 0.606.09.2009Lars Vogel
Clean-up of description, better GAE description
Revision 0.707.09.2009Lars Vogel
Added buzzword bot from Oliver Gierke
Revision 0.811.09.2009Lars Vogel
Added link to Google Wave example apps
Revision 0.929.10.2009Lars Vogel
Added link to the standard Google Wave system
Revision 1.025.12.2009Lars Vogel
General re-work
Revision 1.128.12.2009Lars Vogel
improved robot description
Revision 1.230.12.2009Lars Vogel
added one week in average to wait for account
Revision 1.302.01.2010Lars Vogel
added logging

Google Wave

This article describes Google Wave and the usage of the Google Wave API to build a robot.

This article was developed with Java 6.0 and Eclipse 3.5.


Table of Contents

1. Google Wave
1.1. What is Google Wave
1.2. Getting access
1.3. Wave, Wavelets and Blips
1.4. Protocol
2. Extensions
3. Installation of the Google Tools for Eclipse
4. Installation requirements for Wave Robot Development
5. Robots and Google App Engine
6. Your first Robot
6.1. Overview
6.2. Create Project
6.3. Add libraries
6.4. Create Servlet and Servlet mapping
6.5. Create Configuration File
6.6. Configure your application
6.7. Deploy your application to GAE/J
6.8. Test your robot
6.9. Extend your robot
7. Logging
7.1. App Engine
8. Thank you
9. Questions and Discussion
10. Links and Literature
10.1. Google Wave Links

1. Google Wave

1.1. What is Google Wave

Google Wave is a communication platform which merges the mediums email, forum, chat, instance messaging and wiki.

Google Wave can be separated into the product, the platform and the protocol. The product is what people can use, the platform allows developers to extend the Wave product and the protocol takes care of the synchronization between wave documents and other services.

The Google Wave product looks similar to the following screenshot.

1.2. Getting access

Currently Google is running a beta program so not everyone can join Google Wave. You can sign-up to a waiting list on the Google Wave homepage . Google tries to grand access to Wave as fast as possible; currently access is usually given within a week after sign-up.

Google Wave has two environments. The Wave sandbox and the standard Wave Server. The standard wave server can be found https://wave.google.com/wave . The Wave sandbox system can be found here https://www.wavesandbox.com .

1.3. Wave, Wavelets and Blips

A wave is a threated conversation between one or several parties (people or programs (robots)).

A wave can be seen as an envelop which contains wavelets. A wavelet is a subset of a larger conversation (== wave). Access control can be given based on wavelets and all participants in a wavelet have full read and write access to the wavelet.

Wavelets contain blips. A Blip is a single, individual message. Blips can be have the status "published" or "draft". Blip stores their content in a XML document.

The Google Wave API operates either on wavelets or on blips.

1.4. Protocol

The Wave protocol is based on XMPP ("Extensible Messaging and Presence Protocol").

The Google Wave protocol will immediately update all clients in case a change occurs.

Changes in a wave the are communicated as deltas between client and server, e.g. only the changes are communicated.

2. Extensions

The Google Wave platform supports the development of Robots and Gadgets. A robot runs on a server while the gadget runs on the client. The gadget will manipulate the Wave XML locally and the delta is send to the server.

A robot can get added to a wave. After you added a robot to a Wave the robot will get notified if the Wave changes and can then react to the changes.

A robot must be currently hosted on the Google App Engine and is an application which interfaces with a Wave via the Wave protocol.

The following tutorial will focus on developing Google Wave Robots.

3. Installation of the Google Tools for Eclipse

The following assumes that you have experience using Eclipse. I assume your are using Eclipse 3.5. For an introduction please see Introduction to Eclipse .

Google offers a Eclipse plugin that provides both Google App Engine and GWT development capabilities.

Install the plugins from http://dl.google.com/eclipse/plugin/3.5 via the update manager of eclipse (please see Using the update manager of Eclipse for details).

Install all available features from the Google update site.

Tip

This installation will also in include the GWT and App Engine SDK into your Eclipse preferences. Check Window -> Preferences -> Google -> App Engine / Web Toolkit. The SDK is included in your Eclipse installation directory under "/plugins/". Here you find Eclipse plugins for GWT and App Engine which contain the SDK.

4. Installation requirements for Wave Robot Development

Tip

Wave robot development requires Java 1.6.

Download the required libraries from from http://code.google.com/p/wave-robot-java-client/ the following libraries

  • wave-robot-api-*.jar

  • jsonrpc.jar

  • json.jar

5. Robots and Google App Engine

Currently a robot needs to run on the Google App Engine to participate in a Wave. We will use the Google App Engine for Java which is also called GAE/J.

Therefore you need to

  • Register yourself on the Google App Engine

  • Create an application which will become your Wave robot (this will be later part of this tutorial).

To learn about the Google App Engine and how to create please a application please see see Google App Engine Development with Java

Create now a account at the Google App Engine Homepage in case you have not yet done this.

Create also an application which we will later use to deploy our robot to. My application will be called "vogellawave".

6. Your first Robot

6.1. Overview

The following will develop a robot for Google Wave. This robot will be a "buzzword" detector. If you add the robot to a wave you can register certain words as buzzword. If buzzwords are used more then 3 times the robot will add "bingo" to the wave conversation.

6.2. Create Project

Create a new Web Application Project "de.vogella.google.wave.firstrobot". Select only GAE support. The procedure for creating a project is described in Google App Engine .

6.3. Add libraries

Put the three waves jars you downloaded earlier in the folder "/war/WEB-INF/lib" and add them to the project build path.

6.4. Create Servlet and Servlet mapping

Create the following Java class.

				
package de.vogella.google.wave.firstrobot;

import com.google.wave.api.AbstractRobotServlet;
import com.google.wave.api.Blip;
import com.google.wave.api.Event;
import com.google.wave.api.EventType;
import com.google.wave.api.RobotMessageBundle;
import com.google.wave.api.TextView;
import com.google.wave.api.Wavelet;

public class MyWaveServlet extends AbstractRobotServlet {

	private static final long serialVersionUID = 1L;

	@Override
	public void processEvents(RobotMessageBundle bundle) {
		Wavelet wavelet = bundle.getWavelet();
		
		if (bundle.wasSelfAdded()){
			Blip blip = wavelet.appendBlip();
			TextView textView = blip.getDocument();
			textView.append("Moin, moin wave");
		}
		
		for (Event e: bundle.getEvents()){
			if (e.getType()== EventType.WAVELET_PARTICIPANTS_CHANGED){
				Blip blip = wavelet.appendBlip();
				TextView textView = blip.getDocument();
				textView.append("Hello, wave");
			}
		}
	}

}

			

Map your servlet to the path "/_wave/robot/jsonrpc" by changing the web.xml to the following.

				
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
	<servlet>
		<servlet-name>WaveRobot</servlet-name>
		<servlet-class>de.vogella.google.wave.firstrobot.MyWaveServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>WaveRobot</servlet-name>
		<url-pattern>/_wave/robot/jsonrpc</url-pattern>
	</servlet-mapping>
</web-app>

			

Tip

The path must be "/_wave/robot/jsonrpc", Wave requires this default path.

6.5. Create Configuration File

Google Wave requires that a cofiguration file "capacities.xml". This file will tell Wave about the capabilities and authorizations of the robot.

In folder /war create the folder "_wave" and create the file "capabilities.xml".

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

			

Tip

Every time you change this file, e.g. by adding new capabilities, you have to increase the version in this file.

Tip

The available permissions can be found in the enumeration "google.wave.api.EventType".

6.6. Configure your application

The file "appengine-web.xml" needs to have the correction application id. You find this file in the folder "war/WEB-INF"

In step Google App Engine and Robots you should have created an application on the Google App Engine. In the file "appengine-web.xml" enter this application. For example I have registered "vogellawave" therefore my file looks like the following.

				
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
	<application>vogellawave</application>
	<version>1</version>
	
	<!-- Configure java.util.logging -->
	<system-properties>
		<property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
	</system-properties>
	
</appengine-web-app>
			

6.7. Deploy your application to GAE/J

Deploy your application to the Google app engine by pressing the highlighted button.

See Google App Engine for Java for details on deployment.

6.8. Test your robot

Create a new wave. Press add participant and type yourapplication@appspot.com, e.g. in my example vogellawave@appspot.com. The system will asked you if you want to add the robot to your contacts. Select yes. Once you added the robot to your wave it should add his greetings to your wave.

6.9. Extend your robot

Tip

This buzzword bot has been developed and provided by Oliver Gierke and slightly modified by Lars Vogel . .

To test this you can use the existing bots "vogellawave@appspot.com" (from Lars) or "wavebuzzbot@appspot.com" (from Oliver).

This robot will allow to register buzzwords via the "!addbuzzword word" command, show the available buzzwords via "!showbuzzwords" and reset the buzzword counter via "!reset". See later for an example.

Add the event BLIP_SUBMITTED to your capabilities.xml

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

			

Change your servlet to the following.

				
package de.vogella.google.wave.firstrobot;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.servlet.ServletException;

import com.google.wave.api.AbstractRobotServlet;
import com.google.wave.api.Blip;
import com.google.wave.api.Event;
import com.google.wave.api.EventType;
import com.google.wave.api.RobotMessageBundle;


/**
 * Small sample bot for Google Wave to demonstrate bot behavior. This one will
 * allow registering buzzwords and react on occurrence of them afterwards. After
 * having found 5 words it will shout BINGO!
 * 
 * @author Oliver Gierke 
 */
public class MyWaveServlet extends AbstractRobotServlet {

    private static final long serialVersionUID = -8582338473962188402L;
    private static final String COMMAND = "!addbuzz";
    private static final String RESET_COMMAND = "!reset";
    private static final int COUNT_TO_WIN = 5;

    private List<String> buzzwords;
    private int count;


    @Override
    public void init() throws ServletException {

        buzzwords = new ArrayList<String>();
        buzzwords.addAll(Arrays.asList("Wave", "Google", "Android", "GTUG",
                "DevDusk"));
        count = 0;
    }

    @Override
    public void processEvents(RobotMessageBundle bundle) {

        for (Event event : bundle.getBlipSubmittedEvents()) {

            if (event.getType() == EventType.BLIP_SUBMITTED) {

                Blip blip = event.getBlip();

                if (!maybeLearnBuzzword(blip)) {
                    detectBuzzwordIn(blip);
                    bingoWon(blip);
                }

                eventuallyReset(blip);
            }
        }
    }

    /**
     * @param blip
     */
    private void bingoWon(Blip blip) {
    	
        if (count == COUNT_TO_WIN) {
            blip.createChild().getDocument().append("BINGO!");
            count = 0;
        }
    }

    /**
     * @param blip
     */
    private boolean maybeLearnBuzzword(Blip blip) {

        String text = blip.getDocument().getText();

        if (text.startsWith(COMMAND)) {
            String buzzword =
                    text.substring(COMMAND.length(), text.length() - 1).trim();
            buzzwords.add(buzzword);

            blip.createChild().getDocument().append(
                    String.format(
                            "Added %s to buzzwords! Owning %s buzzwords now!",
                            buzzword, buzzwords.size()));
            return true;
        }
        return false;
    }


    private void detectBuzzwordIn(Blip blip) {

        String text = blip.getDocument().getText();

        for (String buzzword : buzzwords) {
            if (text.contains(buzzword)) {
                Blip child = blip.createChild();
                child.getDocument().append("Gotcha!");
                count++;
                break;
            }
        }
    }


    private void eventuallyReset(Blip blip) {

        if (blip.getDocument().getText().startsWith(RESET_COMMAND)) {

            count = 0;
            blip.createChild().getDocument().append("Reseted!");
        }
    }
}

			

Re-deploy your servelet.

In Google Wave create a new Wave and add your robot to the wave.

See the following screenshot for a possible usage of the robot.

7. Logging

7.1. App Engine

In case of problems you can check the log on the GAE. Please see How to access the log in Google App Engine .

8. Thank you

Thank you for practicing with this tutorial.

Please note that I maintain this website in my private time. If you like the information I'm providing please help me by donating.

9. Questions and Discussion

For questions and discussion around this article please use the www.vogella.de Google Group. Also if you note an error in this article please post the error and if possible the correction to the Group.

I believe the following is a very good guideline for asking questions in general and also for the Google group How To Ask Questions The Smart Way.

10. Links and Literature