As more of our lives revolve around our calendars — when things are due, where we have to be right now — it's useful to see other information with our dates. This could mean seeing the weather forecast or not missing one of the Google Doodles. If you use Google Calendar, we've recently added support for Calendar Event Gadgets. This feature enables you to add just about any kind of content to your calendar and leverage the growing gadgets developer community. Intrigued? Read on! This article will go on to show you what they look like, what they can do, and how you can get in on the action.
This document is intended for anyone interested in learning more about Calendar Event Gadgets — what they are, how to use them, and how to write and adapt gadgets for Google Calendar.
Calendar Event Gadgets are special events that appear as icons above a day's events. When clicked, the icon can pop up with any image, webpage, or a gadget. Try it out below!
Let's go over the extra fields that make Calendar Event Gadgets different than a run of the mill "Lunch with Steve" appointment in your calendar.
Additionally, Calendar Event Gadgets are specified as all-day events. To specify all-day events, set the start time and end time one day apart. For example, if you want your Calendar Event Gadget to appear on 2007-03-14, then the start time is 2007-03-14 and the end time is 2007-03-15.
The only required field is the icon URL. In its most simple form, Calendar Event Gadget content can consist of just the icon above the day's events — like the Phases of the Moon calendar above. If you want to point to a webpage or image, the type, width, and height must also be provided. For example, the birthday reminder below pops up with an image (click the birthday hat).
For full gadgets to be included as Calendar Event Gadgets, user preferences may also be required. This document will focus on full gadgets, but for more information the simple form of Calendar Event Gadgets, see the protocol guide. The Labpixies my del.icio.us gadget takes a del.icio.us username as a user preference (click the del.icio.us logo).
Let's say that you want to have your favorite gadget - Word of the Day, added as a Calendar Event Gadget in your calendar. (All in the pursuit of personal edification, of course.) There are many ways to add a gadget and varying degrees of difficulty.
We'll go into more detail about using the "of the day" Calendar Event Gadget creator, the various ways to use the iCalendar format, and the Calendar data API. It's helpful to have programming knowledge and internet hosting in general, but there are many things you can do with minimal coding and no internet hosting. There is also a difference in how the Calendar Event Gadgets are added to users' calendars. Published iCalendar files and URLs generated by the "of the day" creator are maintained as separate calendars that users can add to their list of calendars. Importing an iCalendar file and using the Calendar data API actually inserts these events into the given calendar. If you just want to convert an existing gadget to a Calendar Event Gadget, the "of the day" Calendar Event Gadget creator is an easy way to do so without maintaining any additional files. If you want to provide a Calendar Event Gadget that pops up a picture on every US Holiday, publishing a static iCalendar file can be done without any coding - you could even use Google Pages to host the iCalendar file and photos.
Of course, doing more sophisticated things with the gadget itself may take expertise and hosting, but how to write gadgets is out of scope for this document. Please visit the gadgets documentation for a great starting place. We can even provide hosting for your gadget specification if you use the Google Gadget Editor.
You should peruse all the available methods and decide which works best for you.
If you already have a gadget specification, then you're almost done! A handy tool has been written to convert an existing specification into a Calendar Event Gadget. The tool is actually a gadget too — we've embedded it in this document over to the right. You can even add it to your iGoogle by clicking on the '+' icon in the bottom left.
Given a valid gadget spec, the "of the day" Calendar Event Gadget creator will fetch the user preferences, display them for editing, and then create a URL to add the gadget to your calendar. Try it for yourself!
Click on the "Load" button to the right to bring up the user preferences for our Word of the Day gadget. Edit any preferences - for example, try changing the icon URL from the default to "http://www.thefreedictionary.com/favicon.ico". Then, click "Create Calendar." Once the URL is generated, click on the link to add it to your Google Calendar. It will appear in the list of your calendars on the left hand side and display the gadget as an icon on the current day.
The "of the day" creator is easy to use, but since it only displays the gadget on the current day, it has limited flexibility.
For the next step up, there's the iCalendar format, a standard for calendar data exchange. See below for the Word of the Day example converted into iCalendar format.
BEGIN:VCALENDAR
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME;VALUE=TEXT:Word of the Day
VERSION:2.0
BEGIN:VEVENT
DTSTART;VALUE=DATE:20070720
DTEND;VALUE=DATE:20070721
SUMMARY:Word of the Day - with pronunciation audio!
X-GOOGLE-CALENDAR-CONTENT-TITLE:Word of the Day
X-GOOGLE-CALENDAR-CONTENT-ICON:http://www.thefreedictionary.com/favicon.ico
X-GOOGLE-CALENDAR-CONTENT-URL:http://www.thefreedictionary.com/_/WoD/wod-module.xml
X-GOOGLE-CALENDAR-CONTENT-TYPE:application/x-google-gadgets+xml
X-GOOGLE-CALENDAR-CONTENT-WIDTH:330
X-GOOGLE-CALENDAR-CONTENT-HEIGHT:100
X-GOOGLE-CALENDAR-CONTENT-GADGET-PREF;NAME=Format:0
X-GOOGLE-CALENDAR-CONTENT-GADGET-PREF;NAME=Days:1
END:VEVENT
END:VCALENDAR
There are two ways to add events using iCalendar:
Try importing the event above into your calendar by copying and pasting it into a text document. Save the document with an ".ics" extension, then upload it into your calendar. For instructions on how to import iCalendar files into your calendar, see here.
You can also provide the URL to a published iCalendar file - add the above event as a separate calendar by clicking here. Maintaining a published iCalendar file is a good way to add content programmatically. You can set up a script to periodically update content for anyone who's added your gadget to their calendar. The downside to this method is that updates may take a few hours for the new information to be parsed and viewable by your users.
Note: The uploaded file must be accessible publicly on the internet. It will not be indexed if located on, say, an intranet.
Google Calendar allows client applications to view and update calendar events in the form of Google Data API ("GData") feeds. Your client application can use the Google Calendar data API to create new events, edit or delete existing events, and query for events that match particular criteria. Requiring the most programming knowledge, the Calendar data API can be used to insert gadgets by specifying extra fields in a calendar event. Using the Google Data protocol, events are actually added to the user's calendar instead of included as an external calendar. Because write calls are being made to a user's calendar, user authentication has to be dealt with. For more information on authentication, please see the Account Authentication documentation and the developer guides.
A standard calendar event entry in the GData format looks something like this:
<entry xmlns='http://www.w3.org/2005/Atom'
xmlns:gd='http://schemas.google.com/g/2005'>
<category scheme='http://schemas.google.com/g/2005#kind'
term='http://schemas.google.com/g/2005#event'></category>
<title type='text'>Word of the Day</title>
<gd:when startTime='2007-07-17'
endTime='2007-07-18'></gd:when>
</entry>
The extra GData elements in a calendar event entry for a Calendar Event Gadget would look like this for the Word of the Day gadget:
<atom:link rel="http://schemas.google.com/gCal/2005/webContent"
title="Word of the Day"
href="http://www.thefreedictionary.com/favicon.ico"
type="application/x-google-gadgets+xml">
<gCal:webContent url="http://www.thefreedictionary.com/_/WoD/wod-module.xm"
width="300"
height="136">
<gCal:webContentGadgetPref name="Days" value="1" />
<gCal:webContentGadgetPref name="Format" value="0" />
</gCal:webContent>
</atom:link>
To make your lives easier, however, GData offers client libraries in many different languages. Inserting Calendar Event Gadgets using the Java and Python client libraries are covered below. More information on the raw XML involved can be found in the protocol section of the Google Calendar developer's guide.
The Java client library has a WebContent object and associated helper functions to help create Calendar Event Gadgets (formerly called Web Content Events) to insert.
First, however, a CalendarEventEntry is needed to hold the WebContent object. As mentioned before, a Calendar Event Gadget is just a fancy calendar event. The main thing that needs to be set here is the date. For more information on how to use the Java client library with Google Calendar, see the developer's guide for Java.
CalendarEventEntry myEvent = new CalendarEventEntry();
myEvent.setTitle(new PlainTextConstruct("Word of the Day"));
DateTime startTime = DateTime.parseDateTime("2007-03-14");
DateTime endTime = DateTime.parseDateTime("2006-03-15");
When eventTimes = new When();
eventTimes.setStartTime(startTime);
eventTimes.setEndTime(endTime);
myEvent.addTime(eventTimes);
Note: The title that is set in the event is not seen in the normal display. It will only be displayed to describe the event in Agenda view, e-mail, pop-up, or SMS alerts associated with the event.
Next, create a WebContent object and set all the familiar fields associated with our Word of the Day example. The gadget's user preferences are stored in a HashMap as name/value pairs. After the WebContent object is good to go, it can be added to the newly created event by using setWebContent.
WebContent wc = new WebContent();
wc.setTitle("Word of the Day");
wc.setType("application/x-google-gadgets+xml");
wc.setIcon("http://www.thefreedictionary.com/favicon.ico");
wc.setUrl("http://www.thefreedictionary.com/_/WoD/wod-module.xml");
wc.setWidth("300");
wc.setHeight("136");
Map prefs = new HashMap<String,String>();
prefs.put("Format", "0");
prefs.put("Days", "1");
wc.setGadgetPrefs(prefs);
myEvent.setWebContent(wc);
The Calendar Event Gadget can now be inserted by an authenticated CalendarService object. For more information about how to authenticate a service object, see the Java developer's guide.
CalendarEventEntry insertedEntry = myService.insert('/calendar/feeds/default/private/full', myEntry);
There are three classes that deal with Calendar Event Gadgets (formerly called Web Content Events) in the Python client library: WebContent, WebContentGadgetPrefs, and WebContentLink. These classes correspond heavily with the structure of the raw XML and it may be helpful to look at the protocol guide for more information on the XML structure.
To continue our Word of the Day example, a CalendarEventEntry is first created to enclose the WebContentLink object. A Calendar Event Gadget, as you'll remember, is just a special calendar event. The date, a When object, is the most important thing to set here. As mentioned earlier, Calendar Event Gadgets must be all-day events; specified by setting the start_time and end_time one day apart. For more general information about using the Python client library with Google Calendar, see the Python developer's guide.
event = gdata.calendar.CalendarEventEntry()
event.title = atom.Title(text='Word of the Day')
event.when.append(gdata.calendar.When(start_time='2007-03-14', end_time='2007-03-15'))
Note: The title that is set in the event is not seen in the normal display. It will only be displayed to describe the event in Agenda view, e-mail, pop-up, or SMS alerts associated with the event.
Now, the gadget-specific objects have to be created. The WebContent class holds the URL of the content (in this case, a gadget spec), the width and height of the popup box, and the name/value pairs for all the user preferences. The preferences are stored as WebContentGadgetPref objects, and appended to the gadget_pref array under the WebContent class. The WebContentLink object holds the title of the pop-up box, the location of the icon, the type of the content, and a WebContent object. The populated WebContentLink object is then added to the newly created event.
wc = gdata.calendar.WebContent()
wc.url = 'http://www.thefreedictionary.com/_/WoD/wod-module.xml'
wc.width = '300'
wc.height = '136'
wc.gadget_pref.append(gdata.calendar.WebContentGadgetPref(name='Days', value='1'))
wc.gadget_pref.append(gdata.calendar.WebContentGadgetPref(name='Format', value='0'))
wcl = gdata.calendar.WebContentLink()
wcl.title = 'Word of the Day'
wcl.href = 'http://www.thefreedictionary.com/favicon.ico'
wcl.link_type = 'application/x-google-gadgets+xml'
wcl.wc = wc
event.link.append(wcl)
The CalendarEventEntry can now be inserted by an authenticated CalendarService object. The Python developer guide for Google Calendar has further details on how to create and authenticate a Calendar client object.
client.InsertEvent(event, '/calendar/feeds/default/private/full')
Here are some things to keep in mind when planning out a Calendar Event Gadget.
Hopefully, you've been inspired to create useful and fun additions using Calendar Event Gadgets; whether it be a daily event that shows today's top Digg stories, or new videos from your favorite artists on YouTube. The possibilities are only limited by what can be shown on a webpage. Try it out and give us feedback in the Google Calendar discussion group. Happy coding!