Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Developing gadgets for Google Wave

A gentle introduction

Thomas Myer, Principal, Triple Dog Dare Media
author
Thomas Myer is a consultant, author, and speaker based in Austin. He runs Triple Dog Dare Media and tweets as @myerman on Twitter. You can reach him at tom@tripledogs.com.

Summary:  Google Wave is here. And whether you plan to use, integrate with or compete against it, you're going to need to have some understanding of what it does. This article provides you with the basics, from building a simple gadget to the high points of gadget construction.

Date:  02 Mar 2010
Level:  Intermediate
Also available in:   Korean  Russian  Japanese  Portuguese

Activity:  15105 views
Comments:  

Early in 2009, Google introduced Google Wave, a different way of communicating and collaborating. Although there are many descriptions out there about what Google Wave is and what its capabilities are, I think of Google Wave as a union of various successful technologies: wikis, e-mail, and instant messaging (IM). At the end of the day, a wave is a real-time communication environment that can include multiple participants.

Frequently used acronyms

  • API: Application programming interface
  • HTML: Hypertext Markup Language
  • JSON: JavaScript Object Notation
  • XML: Extensible Markup Language

When you start a wave in Google Wave, you can add human and non-human participants to the discussion. Because "non-human participant" is a mouthful, it's easier to think of these "participants" as Google Wave extensions. There are basically two types of extensions: bots and gadgets. This article doesn't cover bots — suffice it to say that a bot is an automated participant in a wave. Think of a chatbot, for example, which can read the contents of a wave, respond in its own fashion, acknowledge new participants, etc.

The extension this article focuses on is the gadget. A gadget differs from a bot in that it's a specialized mini-application that helps you perform a focused task. Without further ado, let's jump in and figure out what they're all about.

What is a Google Wave gadget?

You've probably had some kind of experience with gadgets (or widgets) in the past. If you're using Mac OS X, you've probably used a dashboard widget (calculator, weather, Apple iPod controller) to complete some kind of specialized task. If you have a Google or My Yahoo! account, you've probably added widgets or gadgets to your customizable home page. Each widget or gadget offers a set of limited functionality in some area. For example, you might add a gadget that shows you what movies are playing at local theaters based on your ZIP code.

In short, a gadget or widget is any mini-application that's easy to build, easy to deploy, and easy to consume. So, what's the difference between a regular gadget/widget and a Google Wave gadget? A Google Wave gadget is designed to take advantage of the live, multi-user environment of a wave — in particular, the state object that's shared among participants.

For example, if you have 20 people participating in a wave, any gadget you add to the wave (such as allowing participants to vote Yes or No on a proposed motion à la Robert's Rules of Order) would need to interact with each participant. You might have a requirement that all participants must be able to see any vote cast by a single participant. In Google Wave parlance, a vote cast by a participant using this particular voting gadget would represent a state change, and it's the tracking of this state change that makes Google Wave gadgets different from the basic non-wave gadgets you've probably run across.

So far, nothing here is too difficult to understand. But what is a gadget physically? It's an XML file with certain instructions and an embedded content payload. This payload can be simple HTML, but most gadgets contain some kind of JavaScript logic, as well.

This may sound a bit scary if you're not familiar with XML or JavaScript. While fluency in (or at least comfort with) JavaScript coding is helpful, the XML portion of a gadget is so minimal that really what it amounts to is a simple wrapper for your code.

For example, Listing 1 provides an extremely simple gadget that says "Hello, Wave!" and nothing else. It doesn't even contain JavaScript — just HTML.


Listing 1. A simple gadget
	
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="Hello, Wave">
    <Require feature="wave" /> 
  </ModulePrefs>
  <Content type="html">
    <![CDATA[     
       Hello, Wave!
    ]]>
  </Content>
</Module>
            

Each Google Wave gadget has a root-level tag called <Module> that contains all the other elements of the gadget. Specifically, it contains a ModulePrefs section, which you can use to store information about the module and its author, and a Content section that contains the actual content of the gadget. So far, even if you don't know anything about XML, you're still on pretty solid ground.

In the case of the simple example, the ModulePrefs section contains a single Require line, to force the use of the wave feature. (There are other supported features, as well. See Resources.) The Content section contains a CDATA node with the content—in this case, a simple statement that says "Hello, Wave!"

When you've finalized your XML file, you need to save it to a public server of some kind. (You can use a Web server, a public folder service, such as Dropbox, or any other kind of resource). Take note of the URL (for example, http://example.com/path/to/hello.xml) because you'll need it once you're in Google Wave.

To use your new gadget, log in to Google Wave and start a new wave. On the far right side of the toolbar, there is a button that looks like an ellipsis (...). Click that button, then click the green jigsaw puzzle piece. You'll be prompted to enter the URL of your gadget.

When you enter that URL and click Add, Google Wave processes the gadget you've built. If everything is OK, it displays the content in your gadget. In this case, it displays "Hello, Wave!" and nothing else.

That's really all you need to know about creating and deploying a Google Wave gadget. However, because this first example was a bit too simple, let's walk through one more gadget — this time, something a bit more complex.


Building a more complex gadget

You now know what a gadget is and how to create its content. However, the content in the first gadget was merely simple text, and you need to know a bit more than that to actually create a working gadget. This section shows you how to create the basic building blocks for a gadget using JavaScript.

Begin by creating a simple gadget that generates a random number between 0 and 100. There may be some situations in which you need a random number that represents a probability (as in, 30 percent or 55 percent). In this gadget, you add some basic HTML (including a button to launch the random number generator and an empty HTML div to contain the generated number) and all the necessary components to make things work. Listing 2 shows the gadget with the Content section just roughed in.


Listing 2. A more complex gadget, part 1
	
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="Random Number Generator">
	<Require feature="wave" /> 
	<Require feature="dynamic-height" /> 
  </ModulePrefs>
  <Content type="html">
	<![CDATA[     
	  <!-- fill this in later -->
	]]>
  </Content>
</Module>
            

Next, enter the content (shown in Listing 3). This gadget will contain a bit of HTML and some JavaScript to make things work properly. First, create a simple bold header, an empty div to hold your generated number, and a button that will fire off the entire process. All of this will go inside the Content section.


Listing 3. The HTML portion of the content
	
<b>Generate a random number....</b>
<div id="content" style="height: 50px;"></div>
<input type=button value="Click Me!" id="btnCount" onClick="genRandomNumber()">
            

If you've had even superficial experience with HTML, you're not in unfamiliar territory. When a Google Wave participant clicks the button, the genRandomNumber() function runs. Next, add the JavaScript that will make your button work within Google Wave. Instead of showing it to you piecemeal, I'll show the entire JavaScript portion (see Listing 4), then walk you through it.


Listing 4. The JavaScript portion of the content
	
<script type="text/javascript">
var content = document.getElementById('content');
	   
function genRandomNumber(){
	var random_number = Math.floor(Math.random()*101);
	wave.getState().submitDelta({'random': random_number});
}


function stateUpdated() {
  if(!wave.getState().get('random')) {
	content.innerHTML = ""
  }
  else {
	content.innerHTML = wave.getState().get('random');
  } 
}

function init() {
  if (wave && wave.isInWaveContainer()) {
	wave.setStateCallback(stateUpdated);

  }
}
gadgets.util.registerOnLoadHandler(init);
</script>
            

First, you use the document.getElementById() function to select the content div; you'll need to access it later when you're ready to display the random number generated by the script.

The next step is to create the genRandomNumber() function. In this case, you're using some math functions to create a random number from 0 to 100. Save that number to a variable called random_number, but instead of immediately printing it to the content div, you're going to use the built-in wave functions getState() and submitDelta() to push the value you just generated into the overall wave state object. Notice that essentially, you're creating a JSON key-value pair; the key is random, and the value is whatever number the process generates.

The next function in line is stateUpdate(). Google Wave uses this callback function to display any changes in the state object. In this case, you're using a simple if . . . else block to see whether any value stored in the state is accessible via the random key. (In other words, has a number been generated via the genRandomNumber() function?) If there's no value, then keep the content div empty. If there is a value, then use the innerHTML function to display whatever value might be in the content div. Notice that you can easily retrieve this value by using the get() wave function.

Simple enough, but how do you make the stateUpdate() callback function work? You have to create an init() function that will set that callback function — appropriately enough, with a setStateCallback() function. Very straightforward.

Get the finished gadget

If you want to try this particular gadget, you can access it at http://www.tripledogs.com/downloads/randomnumber.xml.

Last but not least, you need to invoke gadgets.util.registerOnLoadHandler(init) to fire off the init() function. All that's left now is to save the file as randomnumber.xml to the Web server of your choice and add it to a wave.


Conclusion

You now know how to create a gadget that actually uses the Google Wave state object. From here, you can do all kinds of things on your own. Just remember, you can do anything inside the Content section that you can do in a regular HTML document. If you want to display images, then you have to add the absolute path to the src attribute. If you are more comfortable using jQuery or Scriptaculous instead of raw JavaScript, remember to include URLs to those tools before you start coding away.


Resources

Learn

Get products and technologies

Discuss

About the author

author

Thomas Myer is a consultant, author, and speaker based in Austin. He runs Triple Dog Dare Media and tweets as @myerman on Twitter. You can reach him at tom@tripledogs.com.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Open source
ArticleID=469442
ArticleTitle=Developing gadgets for Google Wave
publish-date=03022010
author1-email=tom@tripledogs.com
author1-email-cc=

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

For articles in technology zones (such as Java technology, Linux, Open source, XML), Popular tags shows the top tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), Popular tags shows the top tags for just that product zone.

For articles in technology zones (such as Java technology, Linux, Open source, XML), My tags shows your tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), My tags shows your tags for just that product zone.

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Try IBM PureSystems. No charge.

Special offers