Google Contacts via ActiveSync
Synchronizing Google Contacts via SyncML works, but is limited quite a bit by Google's incomplete vCard support. For example, birthday information does not sync because BDAY is not supported by Google's SyncML implementation. Using ActiveSync as protocol works better. This time the protocol and not so much its implementation are the limiting factor: ActiveSync only supports one cell phone number per contact. It does not distinguish between work and private email addresses and only syncs a limited number of them.
SyncEvolution supports ActiveSync in combination with activesyncd. activesyncd can provide access to email, contacts and events. This HOWTO focuses on the usage for contact syncing with Google.
Binaries of activesyncd and the SyncEvolution backend using it are provided as separate packages on syncevolution.org. In contrast to the normal SyncEvolution bundle packages, a Linux distribution like Debian Wheezy with Evolution 3.4 is required to run these binaries.
To install the .deb packages, add the "experimental" repository and run
aptitude install activesyncd syncevolution-activesync
After installation, check that the new binaries work:
$ /usr/libexec/activesyncd (process:14379:0x1147e00): activesyncd-DEBUG:activesyncd Daemon Started (process:14379:0x1147e00): activesyncd-DEBUG:Creating eas_sync gobject. ... $ syncevolution --version SyncEvolution 220.127.116.11+20120713+SE+15f2d03+unclean+SYSYNC+3ba7cb8 (pre-release) using libedataserver-1.2.so.16 using libebook-1.2.so.13 using libebook-1.2.so.13 using libecal-1.2.so.11 using libecal-1.2.so.11 using libbluetooth.so.3 ... Loading backend library /usr/lib/syncevolution/backends/syncactivesync.so ... $ syncevolution backend=? 'backend=?' Specifies the SyncEvolution backend and thus the data which is synchronized by this source. ... Currently active:: ActiveSync Address Book = eas-contacts ActiveSync Events = eas-events ActiveSync Todos = eas-todos ActiveSync Memos = eas-memos ...
Todos and memos are mentioned, but do not work yet. If you don't get the expected output, then see the troubleshooting section below.
activesyncd needs to be configured separately from SyncEvolution. It's settings are stored in gconf under /apps/activesyncd. To configure Google, use the following commands:
$ firstname.lastname@example.org $ gconftool --type string --set /apps/activesyncd/accounts/$email/serverUri \ 'https://m.google.com/Microsoft-Server-ActiveSync' $ gconftool --type string --set /apps/activesyncd/accounts/$email/username \ $email
Replace "email@example.com" with your own email address at Google. It must be the main email address for the Google account, not some foreign email address added to it. Using the email address as account name in gconf is a convention in activesyncd; some other string could also be used.
activesyncd will run ssh-askpass to request a password the first time it needs it, then store the password in GNOME keyring for later use. If that password becomes invalid, activesyncd will ask again.
Here's how SyncEvolution is told about the Google ActiveSync service:
$ syncevolution --configure \ syncURL= \ username=$email \ backend=eas-contacts \ dumpData=0 \ printChanges=0 \ target-config@google-eas \ addressbook
This creates a so-called "target configuration" that can be used to access the data in Google in a local sync where the other side is a local database. See the command line documentation for an explanation of these concepts.
To synchronize contacts, a second configuration, called "sync configuration" is needed:
$ syncevolution --configure \ --template SyncEvolution_Client \ syncURL=local://@google-eas \ username= \ sync=two-way \ google-eas addressbook
This uses the default database for "addressbook" in the default context. See the KDE Wiki page for an explanation how that can be changed prior (or after) setting up this sync configuration. The name of the sync configuration ("google-eas") was chose so that it is identical to the context name in the target configuration. This is not required, the real link between the two configs is defined by the syncURL property.
Accessing and synchronizing data
To test the target-config@google-eas, one can show all contacts already on the server:
$ syncevolution --export - target-config@google-eas addressbook
This works without the sync configuration.
The command for running an actual sync is the same as for all sync configurations. The GTK UI can also be used to trigger the sync.
$ syncevolution google-eas
Google adds photo data to contacts that it recognizes. This photo data is sent to the client in future syncs.
The ActiveSync data model is limited to the following fields per contact:
- phone numbers: two home, two work, one cell, one home fax, one work fax, one car phone, one radio
- one home, one work, one other
- the "PO box" part of an address is not supported
- three email addresses without type information
- three instance messaging handles (without type, and activesyncd does not support that yet)
- birthday and anniversary (as UTC date + time, not just the date)
- web page
- role (aka title)
- manager, assistant, spouse
- company, department, office location
- "file as" string
ActiveSync does not have:
- explicit full name
- extended URL information:
- blog (X-EVOLUTION-BLOG-URL)
- calendar (CALURI)
- free-busy (FBURL)
- video chat (X-EVOLUTION-VIDEO-URL)
- flag whether recipient wants HTML email (X-MOZILLA-HTML)
- ordering of phone or email addresses (X-EVOLUTION-UI-SLOT)
Google's implementation has some restrictions not seen with Exchange:
- The "file as" string is overwritten.
- Photo data gets re-encoded on the server. Photos which are too large (for example, 640 pixels wide) can be stored, but are not shown by the Google web API.
- Categories are lost.
- Only the date part of a birthday or anniversary seems to be stored; this is similar to how Evolution works. ActiveSync forces both Google and SyncEvolution (resp. activesyncd) to add a time. SyncEvolution adds 00:00, as if the person was born on midnight UTC. It strips that time from incoming contacts and keeps other times. Google returns such contacts with a different time added to it, which can shift the date away from the right date.
Syncing will try to map all local data to these fields as good as it can. In some cases, for example phone numbers and addresses, this implies throwing away some type information. At the moment, SyncEvolution has no workaround for modified or lost information and will use the updated resp. cleared values when importing an updated contact from Google.
"refresh from local" and uploading many contacts is slow. The slowness is caused by inefficient use of the ActiveSync protocol (each change is a separate request) and will be addressed in future SyncEvolution releases (by batching changes in one request).
While talking to Google via ActiveSync, there is often no visible progress report. For example, a slow sync starts by downloading all contacts. That can take a while without even explaining that this operation is currently happening. Need to add more INFO messages to SyncEvolution.
In the Google web UI, deleted contacts (regardless whether they were deleted during an incremental or refresh sync) are still visible as "other contacts". They can be removed in the web UI.
Because a target config uses state information tied to the activesyncd account config, it is not possible to use multiple sync configurations with the same target. For the same reason, the command line --export operation on a target configuration breaks incremental syncing. Only use it when prepared to do a refresh or slow sync.
Dumping the entire content of the Google address book before and after a sync (dumpData and printChanges properties in the target config) is not possible. There are several reasons: during an incremental sync, the server only sends changes. It can be asked to start over and send all changes, but then the incremental sync no longer works. Requesting individual, unchanged contacts is supported by the ActiveSync protocol and activesyncd, but not implemented by Google.
If activesyncd fails to start, then missing libraries might be the reason. Check that "ldd /usr/libexec/activesyncd" does not mention any missing libraries.
To get a more complete log of events in activesyncd, run it with
EAS_SOUP_LOGGER=1 EAS_DEBUG=5 EAS_DEBUG_DETACHED_RECURRENCES=1 /usr/libexec/activesyncd
For similar reasons the SyncEvolution ActiveSync backend, syncactivesync.so, might fail to work. Check with
$ SYNCEVOLUTION_DEBUG=1 syncevolution --daemon=no --version
To check whether your data was uploaded correctly to the server and what kind of data might get lost when replacing local data with the server's copy, export the data to a file and run synccompare so that it ignores some known issues (like FN = full name and X-EVOLUTION-UI-SLOT):
Beware that this will break incremental syncing, be prepared for a slow or refresh sync.
$ syncevolution google-eas ... $ syncevolution --export /tmp/google.vcf target-config@google-eas addressbook $ syncevolution --export /tmp/local.vcf google-eas addressbook $ CLIENT_TEST_STRIP_PARAMETERS=X-EVOLUTION-UI-SLOT \ CLIENT_TEST_STRIP_PROPERTIES=FN \ synccompare /tmp/local.vcf /tmp/google.vcf ... $ syncevolution --sync slow google-eas