Dec 122006

We’ve rolled out another release of the Windows Live Contacts Control today, this time adding a write API that enables host web pages to programmatically add and delete contacts with the end user’s approval.  Earlier releases of the contacts control were strictly read-only; the host page could only receive the contact data that the user chose to send to the host page.  The new write API makes the contacts control read-write.

Here’s how it works:  The user logs into Windows Live via the Contacts Control’s login prompt.  The host page can then call createContacts() or deleteContacts() on the contactscontrol html element in the host page.  The host page can call createContacts() and deleteContacts() multiple times, accumulating a batch of operations to submit at the same time.  A transaction, if you will.

When the batch is ready, the host page calls commitContacts(), passing in a completion callback function.  The accumulated operations are transferred to the contacts control for review.  The contacts control displays all the changes to the end user in a popup browser window and asks them to accept or reject the changes.  If the end user accepts the changes, the contacts control sends the changes to the Windows Live Contacts server.

Data errors such as improperly formatted email addresses, duplicate collisions, or exceeding quota limits are reported back to the host page in the completion callback on a per-record basis.  One bad record in a batch of 100 will not abort the entire batch.

Programming errors such as submitting too many contacts in one call will raise an exception and abort the entire operation.  Bad programmer.  Bad!

You can submit up to 30 contacts per call to createContacts(), and up to 30 email addresses per call to deleteContacts().  Up to 1000 operations (adds and deletes combined) can be submitted in one call to commitContacts().  (Add 30 + Add 30 + Delete 10 = 70 operations)

If the user has not logged into the contacts control, all calls to the write API fail immediately.

Note that the write API never gives direct access to the contacts list.  All operations must be reviewed and approved by the end user.

This release of the write API supports only create and delete.  We plan to support updating existing contacts in the near future.

This release of the write API runs afoul of popup blockers because the JavaScript that opens the popup window is not directly executing in the context of a user click event.  We’re working on a fix for that, but we figured it would be better to make the write API available sooner with caveats than later.  To deal with the popup blockers, you can either select “Temporarily allow popups from this site” and resubmit your request or select “Always allow popups from this site” and be done with it.  The domain that needs forgiveness (that will appear in your Allow Popups list) is, not the third-party host page.

Navigating Away

When the host page submits a large batch of operations, there are two phases of data transfer.  The first phase is transferring the data from the host page browser context into the contacts control running in the browser context.  You’ll hear a few clicks from the IE browsers during this phase.  No data crosses the wire, we’re just moving the raw data from one part of browser memory to another so that we can examine the data without outside interference.

The control displays the confirmation window to the end user, and if accepted, the control begins the second phase of data transfer – transferring the data from the browser to the Windows Live server.  Phase 1 may take two or three seconds for a large batch, but phase 2 may take much longer because its actually going across the network wire and waiting for a response.  In my testing, on my local subnet accessing the Windows Live servers, I see a phase 2 data transfer rate around 10 contacts per second, with a non-trivial payload of contact information in each contact record.  This rate scales linearly – adding 581 contacts took about 60 seconds from user acceptance to completion callback, with no errors.

The good news is that the phase 2 transfer does not lock up the browser UI – the user can continue to smurf around with your host page and with the contacts control itself (you can even transfer contacts from the control to the host page while a different batch is being uploaded to the server).

The bad news is the user is not prevented from doing other things while that background transfer is in progress.  The worst thing they could do is navigate the browser to somewhere else.  The operation will abort in mid transfer.  Some of the adds and deletes in the batch will have completed.  Anything that has not completed yet will be lost.

So, if you are planning to add a large volume (hundreds) of contacts to the end user’s contact list, it would be a good idea for you to hook into the browser nav events to display a warning dialog if the user navs away from your page after starting a big transfer.  This is not something the contacts control should do for you.

New Sample App

We’ve also rolled out a new sample app, TryContactsControl.  It’s a derivative of a test harness we use internally to exercise all the facets of the contacts control.  It’s a bare-bones sample that shows you how to set the display language of the control, receive data from the control, as well as create and delete contacts using the new write API.  You can also use this app to experiment with different control sizes to see what size is needed for the display language you want to use with your app.

Picking Up Steam

Adoption of the contacts control is starting to pick up.  I don’t cherish the “battle stations” alarms going off on our servers, but it is pretty cool when they go off due to a spike in activity from a new legitimate app coming online.  It’s sort of like a 21 gun salute.

“Warning!  The contacts control had another 100,000 spike last night from site XYZ.”

“Acknowledged.  What’s the cause?”

“No abuse vectors detected.    Um…  I think they’re using it!”



This post was originally published on my MSDN blog while I was at Microsoft.