Posts Tagged address book

gContactSync 0.3.0 Beta 1 Available

I’ve just released the first beta version of 0.3.0. I feel it is ready to be in a beta as there are no known bugs other than some quirks with postal addresses in Google’s API.  For now postal address synchronization is disabled by default, but you can enable it in the Advanced tab of the Preferences dialog.

This version adds support for importing friends from Facebook, including photos.  It can also import contacts from Plaxo and usernames/photos from your friends on MySpace.  Right now the import does not attempt to match contacts that it finds with existing contacts and imports from Facebook and MySpace do not include e-mail addresses.

As a recap, here’s a quick list of the features.  Download link at the bottom.


  • Can synchronize your Google Contacts (external link) (Gmail, Google Apps, etc.) with Mozilla Thunderbird (external link).
  • Supports multiple Google Accounts and Address Books
  • Groups in Google can be synchronized with individual Address Books or mailing lists in one AB
  • Each Address Book can be synchronized with one of the following:
    • All contacts and all groups with mailing lists
    • One specific group
    • All contacts
  • Every synchronized AB can have its own custom settings
  • You can choose to complete synchronize your contacts (so Thunderbird matches Google), to only read changes from Google but never apply TB’s changes, or to only write to Google and never apply changes made remotely.
  • Contact photos are synchronized (only visible in Thunderbird 3 & Seamonkey 2)
  • Supports importing contacts/friends from Facebook, MySpace, and Plaxo, including photos.

Changes from 0.2:

  • The Accounts section of the Preferences dialog has been moved to its own dialog
  • Each Address Book now can have its own preferences (defaulting to their previous value in 0.2) and synchronization settings
  • New fields (“People”) and types for existing fields (many more phone number types)
  • Contact photos are synchronized (only visible in Thunderbird 3 & Seamonkey 2)
  • The birthday field in Thunderbird 3 is synchronized
  • More links in the gContactSync menu
  • The Sync button can now be customized like a normal toolbar button in Thunderbird. However, you must go to View -> Toolbars -> Customize and add the button to the toolbar yourself
  • You can synchronize from the main Thunderbird window
  • The import functionality is new.

You can download the latest version of 0.3 here.

, , , , , ,


gContactSync available for download

The first–and possibly only–alpha version of my extension is available for download.  You can watch a flash tutorial on basic use and download it herePlease watch the tutorial before using it or you might run into problems. Remember that it is an alpha version, so there might be bugs, and I might add more features.

You can read about the extension on my website.  I also have a mozdev project for it where you can view the source and download the extension.

Reporting Bugs and Suggesting Enhancements

I welcome any sort of feedback, enhancement request, or bug report.  If you encounter an error, please e-mail me with the details and the log file after removing any personal information from it.  There are several e-mail addresses you can use to do it.  gcontactsync at is probably easiest.  You can also use the contact form on my blog or website.

If you encounter an error, you can find the log file in the extensions’s folder.  Read this to get to the profile directory, then go to the extensions folder and the folder named gcontactsync at  It is the file named log.txt, and you will probably want to remove any personal information in it before sending it.

Keep you eyes open for updates.  I’ll try to get a new version out soon after I receive some feedback.  Updates will have to be done manually, for now.

, , , , ,

No Comments

More Address Book Card Attributes Synced

After a little bit of programming last night (early this morning, actually) and this afternoon, I can now sync every attribute of an Address Book card that is visible in the Edit Card Dialog and then some.

So, here is the most recent list of attributes synced from Address Book cards (excludes attributes added by my extension).  2 of the following marked with asterisks cannot be synced.

  • First*, last*, display, and nick* names
  • Primary and second Email addresses
  • Screen Name (_AimScreenName)
  • Home and work phone number
  • Preferred e-mail format*
  • Allow remote content*
  • Work phone number
  • Fax number
  • Pager
  • Mobile number
  • Home & Work: Address, Address Line 2, City, State, Zip, Country, and webpage
  • Title
  • Department*
  • Organization
  • Custom1*, Custom2*, Custom3*, Custom4*
  • Notes

Attributes marked with an asterisk (*) are not visible using Google Contacts.

, , ,

1 Comment

Offline Support Finished

Well, I finally finished adding offline support, so it will should work well offline.  It just sets text in the status bar to let the user know the sync cannot be completed while offline.  Once the user is back online it works like normal.  Any changes made while offline are synced since the listener still adds the last modified date to the custom4 property.  My next goals are to handle errors more smoothly, get some refactoring and additional commenting, and to add support for locales in the scripts.  Once these are done it might be ready for an alpha release.  Let me know if you are interested.

I have been busy the last few days and will be busy for the next day or two because there is a wedding in my family.

, , ,

No Comments

May 27, 2008

I was attempting to change my sync process today when I opened the Address Book and was greeted with 925 new Address Books.  In the end, cleaning obj directory and rebuilding fixed the problem.  Strange, but at least my extension wasn’t the direct cause of the problem.

I found and fixed an error that would sometimes occur when trying to sync after adding several new contacts.

After fixing that error, I re-defined what two cards must have in common for the sync function to consider them identical.  Since Google only allows one contact/e-mail address, it first checks if the cards have any e-mail address in common (primaryEmail or secondEmail).  If there aren’t any e-mail addresses (which is allowed in Thunderbird and Google) it checks the name.

I rewrote my old method to sync individual cards now that I use custom4 for the last modified date.  It checks to see first if both have changed (and will eventually have a preference that can ask the user what to do in this case or pick one to always update) and then checks to see which (if any) changed and updates it.  Unfortunately, updating a Thunderbird card isn’t as efficient as it could be.  I kept getting NS_NOINTERFACE errors while trying to call the modifyCard function in the address book, so I have to actually delete the card and then add the card from Google…  Updating a Google contact needs to be re-done soon, too.

In my casual tests I didn’t find any other errors.  It now works well offline and syncs every 30 minutes by default or manually.  Out of the 11 average contacts I added on one computer, every one synced perfectly with Google and with my other computer.

The only catch so far is that it has to use the card’s custom4 property to store the lastModifiedDate.

, , , ,

No Comments

An overview of my extension

The extension that I am working on for GSoC synchronizes an Address Book in Mozilla Thunderbird with Google Contacts. This is going to be a quick overview of how it works so far. This post assumes some basic knowledge of the Hypertext Transfer Protocol (HTTP), Thunderbird, and programming.

Basically, my extension adds an overlay to the Thunderbird Address Book, so when the Address Book opens, it starts going.

Authentication Check

When it starts, it registers a preferences observer (so it can modify behavior as preferences change) and obtains the current preferences. I will explain preferences in more detail later. It then checks to see if there is a valid authentication token in the extension directory. If not, it shows a login prompt. When OK is pressed, it attempts to authenticate the user using Google’s Client Login method of authentication. So, it sends an HTTPS POST request to Google which then returns an authentication token that can be used repeatedly and does not expire. This token (not the username and password) is stored in a textfile in the extension directory.


Once it gets or finds a valid authentication token, adds a listener (nsIAbListener) to the Address Book Manager (nsIAbManager), sets up the file that stores the date and time of the last synchronization, and begins the synchronization process.

Preparing for Synchronization

The sync process is the longest and the one that I change most often. Right now, it gets the Address Book first (does this every time in case it was deleted, changed, etc.). Then, it gets the time of the last sync (if any) to be used later and sends an HTTP GET request to Google using the authentication token to obtain all of the user’s contacts. Once it has these, it also obtains all contacts in the specified Address Book.


Right now this process is costly in terms of asymptotic analysis (or Big O notation) with a nested for loop.

The outer for loop iterates through every contact from Google while the inner for loop iterates through every unmatched card in the address book. When it finds two cards that it considers “identical,” if the current card from Google hasn’t been matched then it sets the TB card to null (so the loop knows it was ‘matched’ and calls a method that checks the cards’ last modified date to see if any of them is new since the last sync.  If so, it replaces the old card with the new one.

If the card from Google was already matched, however, that means that the card from the Address Book is a duplicate and my current implementation removes the card. In the future I may add a prompt asking the user what to do about it.

Once the inner loop is finished, if the card from Google wasn’t matched it means one of two things. Either the card is new and should be added to Thunderbird (the card’s last modified date is more recent than the last sync) or it was deleted from Thunderbird and should be removed from Google.

Once that is done, it checks any unmatched cards from Thunderbird and figures out if they should be deleted from TB or added to Google, and then does that. Due to some timing issues with HTTP Requests, there are three helper methods. There are three global arrays treated as queues for cards to delete, update, and remove.  The sync method adds cards to the arrays as necessary.  When the sync method is done, it calls the delete method, which then calls the add method, which in turn calls the update method.

Finishing up the sync

When the hard part is over, it writes the current date/time to a file (the last sync time), schedules another sync after the preferred interval and sets a synced boolean to true (which is checked by the listener to make sure it doesn’t act during synchronization)

Address Book Listener

Since TB 3 doesn’t have the lastModifiedDate property, I made my own rough version with an Address Book Listener. The address book listener updates the card’s ‘custom2’ property whenver a contact is modified or added to the Google Contacts address book. Using this approach, my extension should work offline.  I am working on adding last modified date to Thunderbird 3, so soon an address book listener and some of the booleans required by it may become unnecessary.

, , , , , , ,

No Comments