WHAT

A project in Java using Google App Engine (GAE) with the objective of having continuous syncing of multiple Google contacts across multiple Google IDs.

Note: Google Apps provides a somewhat weak implementation of Contacts Sharing within a domain (not with Gmail addresses).


WHY

Primarily to get familiar with the recently released GAE Java runtime, but also to allow me to fully use my private domain email address in Google Apps while having access to the same contacts in Picasa Web, Google Voice, Google Reader… All of those features being unsupported in Google Apps.


HOW

WORKING WITH GAE and the google apis


I’m using Eclipse with the GAE plug-in. This was a breeze to install, and makes deploying my application easy as can be.

For C-Sync, I dealt mostly with the Contacts Data API (Dev guide and Ref guide).

Developing an application within the GAE framework offers a lot of flexibility and allows the average developer to put out an app fairly quickly. The tools at your disposition for post-implementation management are helpful and easy to work with.


However, since close to 100% of my code has to do with handling Google contacts and groups, it meant working extensively with the dedicated API provided by Google to access their services. Although I was able to accomplish what I set out to do, it was not without much grumpiness and complaining about how some features felt, well, half-baked.


A few examples from my personal experience:


  1. It is impossible (as of this writing) to retrieve a contact record with its unique key. This means the only solution I found was to browse the entire feed until it is found.

  2. I tried to use an attribute (<updated>) that was supposed to be a DateTime representation of the last time the feed was updated but it seemed to return the current date every time the feed was requested.

  3. The JVM has to be started EVERY time one brings up the web site for the first time. This means an extra 15-25 seconds added to the load time of your first page.

  4. Some days, my batch process will crash every other time on “timeout while fetching the feed” or the mysterious “com.google.gdata.client.GoogleService$CaptchaRequiredException”. For no apparent reason, it will start working normally again.

  5. Okay, I’ll admit. My candor on the previous statement may be a bit disingenuous... The process is resource-intensive and it can take a while to sync 300+ contacts and groups... Which brings me to my next complaint. Google seems to limits the processing time of an HTTP request to 30 seconds. This is fine most times except when I run the initial syncing of a new Google account. You get a “com.google.apphosting.api.DeadlineExceededException”. Hence the convoluted code in my application to “recycle” the call (essentially splitting it in smaller chunks).


But, eh, it’s free!



The application consists of a simple front-end with 2 screens and a CRON job to provide continuous syncing. It is set-up to only be accessible to users within the bertranfamily.com domain.

Here, select which account to sync FROM and TO.

The checkbox enables syncing contacts that have been deleted from the source, thus also removing them from the destination.


Once both accounts have been selected, the arrow turns green and becomes clickable to start syncing.

WELCOME SCREEN

The list mirrors the table structure: contact name, source, unique ID on destination 1, 2, 3...

CONTACTS LIST

The GAE monitoring tools offer a wide variety of helpful information. Not the least of them is the daily quota, over which Google will ask you to pay or turn off your web app until the 24-hour period is over.

GAE DASHBOARD

This gives a high-level snapshot of the data you have stored in the datastore.

GAE DATASTORE STATISTICS

C-Sync