Google Code offered in: English - Español - 日本語 - 한국어 - Português - Pусский - 中文(简体) - 中文(繁體)
Learn about the Google Wave Federation Protocol and get involved
A robot is an automated participant on a wave. A robot can read the contents of a wave in which it participates, modify the wave's contents, add or remove participants, and create new blips and new waves. In short, a robot can perform many of the actions that any other participant can perform.
You can use a robot to perform actions such as the following:
You can do many more things with robots than those listed here. Additionally, as we expand the capabilities of the API, robots will be able to take advantage of these new features.
Development of Google Wave robots requires an appropriate client library. We currently have client libraries for the Java™ and Python programming languages.
You can find out more information about the client libraries, file issues, and make feature requests on the Google Wave Resources home page on Google Project Hosting. This page also contains download links for the latest client libraries.
A robot (as opposed to a gadget) actively participates in the wave through HTTP requests and responses using the Wave Robot protocol. You don't need to know the particulars of this protocol, however, as we provide both Java and Python client libraries which you can use to create and manage your robots. Documentation of the underlying Wave Robot HTTP protocol is forthcoming.
Currently, Wave supports robots built using Google
App Engine, the scalable web application environment. AppEngine identifies web
applications using an application.appspot.com web address. When
you create robots using AppEngine, you also implicitly define an HTTP interface
at the http://application.appspot.com URL. Wave will use this
address when communicating with the robot (and this address implicitly defines
a robot at this time).
The Java and Python client libraries allow you to design your robot without having to worry about handling and managing the individual HTTP requests. Because this is an early developer release, code may (and likely will) change in the future. However, the client libraries have been designed to be fairly stable. If you do wish to use the Wire Protocol directly, you are free to do so, but understand that this protocol may change in the future.
A user (or a UI extension) adds a robot to a wavelet like adding any other participant,
using the robot's App Engine application ID followed by @appspot.com
as its wave participant address. For instance, if the App Engine application ID for a robot is
parrotybot, the wave participant address for the robot is
parrotybot@appspot.com. Note that the robot is added by what appears
to be an email address, though the Wave API will use an HTTP mechanism to contact
the robot.
Note: For this developer preview release, all Wave robots must be implemented as Google App Engine applications. A future release will introduce the ability to host robots with any web host, at any web address.
You define the behavior of your robot by defining the events
which you wish your robot to be notified. Wave contacts the robot whenever one of these
events occur, such as a change made to a wave in which the robot is a participant.
The robot specifies which events it cares about in a capabilities.xml
configuration file, which Wave retrieves from the robot the first time the robot is
added to a wave.
A sample capabilities.xml file is shown below:
<w:robot xmlns:w="http://wave.google.com/extensions/robots/1.0"> <w:version>0.1</w:version> <w:capabilities> <w:capability name="BLIP_SUBMITTED"/> <w:capability name="DOCUMENT_CHANGED"/> </w:capabilities> </w:robot>
Note: this capabilities.xml file
is auto-generated by the Python client library; users of the Java client library
will need to create this file themselves.
Note that this file contains a single <capabilities> element consisting
of one or more <capability> elements. Each capability consists of
an event which the robot indicates to Wave its interest. When an event of that type
occurs, the Wave will dispatch to the robot an HTTP request.
Every robot must serve its configuration file at the following URL path:
http://applicationURL/_wave/capabilities.xml
Robots may additionally provide meta-information (known as a profile), which identifies a robot to other users (and other robots). Information within this profile is shown within a profile card when you click on the robot's avatar:

A profile consists of the following information:
name specifies the human-readable name of the robot. This name will be
displayed wherever you hover over the robot's avatar or display its profile card).imageUrl specifies the URL to use for the robot's
avatar image. For display within the profile card, dimensions of 100 x 100 pixels
are recommended. (Larger images should be avoided as well.)profileUrl specifies the URL where information about this profile
is available. This URL can be any URL you wish and will be linked within the
profile card.A robot, by default, does not provide this profile information. For Java robots, you must add a Profile servlet to your application which responds with this data. In Python, you provide this information within the robot's constructor. Consult the client library documentation for more information.
If a profile is available for a robot, it will be accessible at the following address:
robotName.appspot.com/_wave/robot/profile
Sending an HTTP GET request to this address will return
JSON containing the robot's profile properties:
{
"profileUrl": "http://tricky-bot.appspot.com/",
"imageUrl": "http://tricky-bot.appspot.com/images/avatar.png",
"name": "Tricky"
}
Note: The Google Wave client is temporarily not retrieving profiles for robot participants, so you will not see names, images, or URLs in the hover card for robots. This is a known issue. Please subscribe to the notify list to be notified when profiles are re-enabled.
The following events which a robot may subscribe to are particularly important:
wavelet_blip_created fires when a new wave blip has been created. wavelet_participants_changed fires whenever a participant (including
another robot) is added or removed from the wave.wavelet_title_changed fires whenever the wavelet title changes.blip_contributors_changed fires whenever the editors of a blip
change.blip_deleted fires whenever a blip is deleted from the wavelet.blip_submitted fires whenever a blip is submitted. Note
that this event only fires once the user clicks Done or moves to another blip.document_changed fires whenever content is added to a blip, at various
intervals.In addition to being event-driven, a robot can request that Wave contact it at regular intervals by specifying a schedule in the configuration file. These cron events allow the robot to perform actions that are not in direct response to changes to a wave, such as to update a wave with new information from an external system.
Note that a robot cannot contact Wave directly; it can only respond to wave-related events and cron events.
When an event occurs, Wave makes an HTTP request to the robot application using
a HTTP POST, the same method used when someone submits a
web form. All events regarding changes to wave data use the following URL path
when contacting the robot:
http://applicationURL/_wave/robot/jsonrpc
Each request for this URL from Wave may encapsulate more than one event about a single wavelet. Recent events may be bundled together. Once the robot receives an event, it can decide if (and how) to respond by encapsulating a response in an operation.
A web request from Wave includes information about one or more events. The robot can respond with instructions to update any wave on which it is a participant, or to create new wavelets through operations in the wave event system.
A robot can perform operations on any wavelet in which it is a participant, and can also create new wavelets and waves. Operations performed by a robot are not reported back to the robot that did them, though they are reported to other participants in the affected wavelets, including other robots.
Operations are handled in the order they are received, and robots do not have any special privileges over other users. Robot operations are sent to the Wave and performed asynchronously; there is no guarantee that other participants may not perform their own operations in the intervening time. As a result, it is best to keep your operations as atomic as possible, and to understand that operations which you apply to the wave may not be applied immediately. A wave is a historical entity, and the content of a wave consists of its original content plus the cumulative operations that occur on that data.
The Java and Python application client libraries provide a complete interface for handling events and performing operations. For example, the Java event handler uses a web servlet to respond to Wave requests by parsing the event data into objects, then calling a method on the servlet for each event. The method generates operations by manipulating objects that represent the Wave data model. When the method returns, the servlet sends all of the operations back to Wave to be applied to the data.
Note: The format of the incoming event data and outgoing operations data are part of the Wave robot wire protocol. During this developer preview release, the details of the wire protocol may change. Once the protocol is stable, we will publish a specification describing the message formats. In the meantime, you can use the Java and Python client libraries to parse events and generate operations.
The Google Wave document model supports tagging sections of text within a wavelet's Document elements via annotations. The Google Wave client uses some reserved annotations itself to denote textual styling issues, hyperlinks, and some metadata. You can also use your own annotations to tag certain strings of text for your own purposes. Many robots use annotations to perform operations on strings of text.
Note that these annotations, by themselves, are simply ways to mark selections of text. They may, or may not, have visible effects. How you use or process annotations is up to you. An annotation may simply contain meta-information about a text selection, or it may require additional processing by your robot to have some effect. (For an example of annotation processing, see Custom Annotations below.)
The Google Wave client uses annotations to style runs of text strings, defining each annotation with a start and end point (known as a range). For example, the following text string (as displayed to the user in the client) and its annotations are shown below:
The quick brown fox jumped over the lazy dog.
(4,19) : style/fontStyle=italic (10,15) : style/color=rgb(150,75,0) (36,40) : style/fontWeight=bold
The following table lists these reserved annotations:
| Annotation Name | namespace | Usage | Example |
|---|---|---|---|
| style/backgroundColor | Styling, Background (Highlight) color | style/backgroundColor=rgb(255,0,0) |
|
| style/color | Styling, Text color | style/color=rgb(150,75,0) |
|
| style/fontFamily | Styling, Font Name | style/fontFamily=arial |
|
| style/fontSize | Styling, Font Size (in Pts) | style/fontSize=18 |
|
| style/fontStyle | Styling (italic) | style/fontStyle=italic |
style/fontWeight | Styling, Font Weight (bold, italic) | style/fontWeight=bold |
| style/textDecoration | Styling | style/textDecoration=none |
|
| style/verticalAlign | Styling, Vertical Alignment | style/verticalAlign=center |
|
| link/manual | Hyperlink | lin/manual=http://www.google.com/ |
|
| link/wave | Wave ID | link/wave=googlewave.com!w+d7NJm4nWF |
|
| lang | Language of the wrapped text | lang=en |
|
| conv/title | Title of Wavelet (usually the first sentence unless set explicitly here) | conv/title=Introduction |
Note: These annotations are subject to change as we revise the Wave Federation data model.
You can view a Blip's annotations within Wave Sandbox by selecting Editor Debug from the right hand menu on a blip and then clicking on annotations in the Editor Debug dialog box.
You can also create your own annotations. Robots often use annotations to mark text and repurpose it for some other use. For example, a shopping robot might allow users to select items within a wavelet for a shopping list, extract those annotated items, and add them to a gadget.
Annotations should be tagged using unique identifiers. It's
good practice to preface your annotations using a namespace, so
that they don't collide with other annotations (or system
annotations). Using the robot's robotname.appspot.com
address as the annotation prefix neatly serves this purpose. (A typical
annotation in such as case would be
robotname.appspot.com/tagname.)
Annotations may additionally take on a value. In many cases, a value is not necessary; the annotation and its underlying text contains all information that is needed for designating the range of text. In other cases, an annotation requires a value. The system styling annotations take on values, for example, to denote font sizes, colors, families, and weights, for example.
Using annotations effectively within a robot generally requires one (or both) the following patterns (one active and one passive):
<annotateSelection>
actions within an extension installer, process the text, and remove
the annotations. This pattern is described below.Note that the first pattern is more computationally expensive.
If you wish to have a robot respond to new annotations, the following pattern is recommended:
<annotateSelection> action performs this
task nicely.document_changed events.document_changed
event, retrieve the annotations and store them in an array.The following extension installer annotates a selection
as a "band name" using band-name.appspot.com/name
as the annotation's key:
<extension
name="Band Name Tagger"
description="Tags selected text as a band name and adds it to a blip"
thumbnailUrl="http://band-name.appspot.com/preview.png">
<author name="Tom Manshreck"/>
<menuHook location="TOOLBAR" text="Tag Bandname"
iconUrl="http://band-name.appspot.com/toolbaricon.png">
<annotateSelection key="band-name.appspot.com/name" />
<addParticipants>
<participant id="band-name@appspot.com"/>
</addParticipants>
</menuHook>
</extension>
The following code will then monitor document_changed events
and process any annotations denoted with the
band-name.appspot.com/name key. Note that we delete
the annotation and then process it by passing it to an addBandName()
method.
def onDocumentChanged(properties, context):
# Get the text of the blip
blipId = properties['blipId']
blip = context.GetBlipById(blipId)
doc = blip.GetDocument()
text = doc.GetText()
# Set up our array to hold the retrieved annotations
bandnames = []
# Get the annotation start and end points and add
# them to the array
for ann in blip.annotations:
if ann.name == 'band-name.appspot.com/name':
bandnames.append((ann.range.start, ann.range.end))
# for each bandname, call addBandName to do any post processing
# Also make sure to delete the existing annotation
for start, end in bandnames:
bandname = text[start:end]
range = document.Range(start, end)
doc.DeleteAnnotationsInRange(range, 'band-name.appspot.com/name')
addBandName(context,bandname)
For more information about annotations, check out the Wave Linker Robot in the Wave Samples Gallery.
Robots within the Wave API are now versioned. This allows the Wave system to detect when robots have changed and/or their capabilities have been altered. If you modify a robot's capabilities (by adding or removing monitored events, for example), you should also change the version identifier of the Robot (which is currently just a text string).
Note that this version identifier is contained
within the Robot's capabilities.xml file (for Java) or indicated in
the Robot's constructor (for Python). This robot version identifier is not related
to App Engine's versioning system. (App Engine versions allow you to deploy multiple
versions of code to different clients.)
The Robot architecture is new and full debugging tools are not yet available. However, if you have trouble during development of your robot, the following tests may be helpful:
capabilities.xml file live? You can test whether
the file is properly deployed by accessing the robot at http://robotname.appspot.com/_wave/capabilities.xml.
If you receive an XML response, you know your robot has been properly deployed to App Engine.capabilities.xml file.)capabilities.xml, is your robot set up to receive the
correct events?https://appengine.google.com
for your robot deployment. If you receive an error, you likely have a coding error.We welcome your feedback during this developer preview! Please post your comments and suggestions to the Google Wave API group.