RSS feed
<< Planning Your Build with Maven 2.1-SNAPSHOT | Home | Google This! >>

Synchronize iCal (or Sunbird) with Google Calendar Bidirectionally!

WOW! I never thought I'd find a way to do this elegantly, but after much searching, here it is!

I found a way to synchronize my Sunbird client (yes, I'm a die-hard linux user) to my Google Calendar. In principle, this shouldn't be difficult - Google publishes a Java API for working with the Calendar, and iCal is a pretty well-established standard, after all - but somehow it just didn't seem to exist. Also, though it's a subject that intrigued me, I didn't have the spare cycles to get into that sort of implementation, particularly with my Maven commitments. But enough of the suspense, let me tell you how my setup looks.

The key component of this system is the GCALDaemon (@SourceForge), which is a Java Servlet (I assume, I haven't looked yet) that can run in either standalone mode, or inside of an existing application server like Tomcat. This servlet can handle HTTP- or file-based ics data, and act as a two-way proxy for shuttling it back and forth to Google Calendar. It also seems to have functions for calendar notifications and sending invitation emails when you create a meeting with others...though I haven't tried out these features yet. For me, it's amazing enough to finally have this working solution to the gCal<->iCal problem.

Anyway, you can follow the directions on their website to setup a simple proof-of-concept on your localhost. All you really have to do is some minimal configuration to the gcal-daemon.cfg file (in GCALDaemon/conf). Then, change the paths in the GCALDaemon/bin/standalone-start.sh and GCALDaemon/conf/logger-config.cfg files to reflect the location of your install (this was a very subtle GOTCHA for me), and you're ready to launch! The simplest way to launch is to simply call the standalone-start.sh script directly from a command line. This will create a foreground process that you can watch for stack traces (to give hints about failing authentication, etc.).

However, once I saw how well this daemon worked, manually-launched, foreground processes were never going to be enough for me. I wanted it to be infrastructural, dammit, just like my imap server! So, I looked into installing GCALDaemon on my OS X mail server.

The biggest PITA with this is the launchd/launchctl mess that OS X uses instead of the typical *nix/BSD startup scripts. I've read quite a few blogs and other articles about why launchd is soooo much better, but until it's documented, it's an arcane and very hairy bitch IMO. (Point taken, I'll slink off and work some more on Maven doco soon enough.) Anyhow, the key to this setup is understanding that you have to specify the JAVA_HOME environment variable in the .plist file. I'll save you some time for this, and just list the whole file below.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC 
    "-//Apple Computer//DTD PLIST 1.0//EN"
    "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>EnvironmentVariables</key>
	<dict>
		<key>JAVA_HOME</key>
		<string>/System/Frameworks/JavaVM.framework/Versions/1.5</string>
	</dict>
	<key>Label</key>
	<string>net.sf.gcald</string>
	<key>OnDemand</key>
	<false/>
	<key>ProgramArguments</key>
	<array>
		<string>/opt/local/apps/GCALDaemon/bin/standalone-start.sh</string>
	</array>
	<key>RunAtLoad</key>
	<true/>
	<key>ServiceDescription</key>
	<string>GCALDaemon</string>
	<key>StandardErrorPath</key>
	<string>/opt/local/apps/GCALDaemon/log/launchd.stderr</string>
	<key>StandardOutPath</key>
	<string>/opt/local/apps/GCALDaemon/log/launchd.stdout</string>
</dict>
</plist>

Simply copy this into your /Library/LaunchDaemons directory, to a file called something like net.sf.gcald.plist. Then, you can use launchctl to load GCALDaemon using the following command:

sudo launchctl load -w /Library/LaunchDaemons/net.sf.gcald.plist

NOTE: I should mention that there is a tool called Lingon that makes this stuff a breeze (also @SourceForge)...at least, until something goes wrong, as in my case with the missing JAVA_HOME definition. Then, you're stuck scrambling for a terminal, the tail command, and the /var/log/system.log file...and pray to your chosen diety that you don't have to look online for documentation, because it's scarce.

Once I had this up and running, it was a simple matter of setting up my autossh configuration - another really nice tool, that I got through Ubuntu and apt-get - to tunnel the port so I can get to it from the coffee shop. Then, I setup my Sunbird instance by using the private ICAL URL for the Google Calendar I wanted (In Google Calendar, Click the down arrow next to the calendar name, then choose Calendar Settings, and scroll to the bottom)...I just created a new Network calendar on Sunbird, paste in the private ICAL URL, substitute the hostname running GCALDaemon in place of www.google.com, and I was up and running. In Sunbird, it won't actually ask you to login to Google Calendar until you try to modify the calendar.

That's pretty much it! Oh, and if you happen to enter the wrong password for your gmail account, you'll see an error on the GCALDaemon output talking about needing Captcha input. If you're using Sunbird, this could mean that you have to erase your profile (under .mozilla/sunbird) and start over...I was unable to determine which file contains the password info, so I couldn't attempt a more surgical strike.

Good luck!

Technorati Tags:



Re: Synchronize iCal (or Sunbird) with Google Calendar Bidirectionally!

Hey!

Thank you so much for this explanation, that’s the first time I got GCALDaemon run… It also seems to work, the iCal -> gCal sync works fine (haven’t tested the gCal -> iCal sync yet, because my gCals were all empty and now I’m not at home so I can’ test it), but I have got one serious problem … now most of my events are doubled!!! Not the whole-day events, but the others .. they appear two times, once with the right time, and once 2 hours earlier … seems like GCALDaemon messes up with time zones or something like that … any ideas how to solve that?

regards

(Mac OS Leopard & iCal User)

Add a comment Send a TrackBack