Developers Integration
From Sw
Contents |
[edit] Introduction
The developer section of the wiki is geared towards developers who want to integrate with ScheduleWorld. The developer API is robust and is being used by two products available in production: the ScheduleWorld Thunderbird add-on Thunderbird (Configuration) and the ScheduleWorld Web 2.0 contacts application.
The ScheduleWorld API was designed based on nearly a decade of lessons learned from implementing clients and servers that support vcard 2.1/3.0, vCalendar 1.0, iCalendar 2.0, RFC 2446 iTip, RFC 2447 iMip, LDAP, SyncML 1.1/1.2, and other related RFCs. The end result is a stateless XML/JSON document based protocol that is easily parsed and validated.
[edit] Executive Summary
The process of doing a sync is:
- Send a sync request to the server.
- Parse the sync response.
That's it. No state to manage between connections. Just a single HTTP post and you're done. Synchronization is completely controlled by the XML document you send. The response at this time is in JSON format.
[edit] Hello World Slow Contact Sync
This assumes the server has no contacts.
To do a slow sync with the server you'll need to HTTP POST a document something like this:
id19,<syncItems>
<clientInfo>
<array-item key="0">
<userAgent>sampleClient-CLIENT_VERSION</userAgent>
<appBuildID>1</appBuildID>
<appVersion>123</appVersion>
<appName>this app name</appName>
</array-item>
</clientInfo>
<syncMode>3</syncMode>
<password>3004352a0b78b0b4fa4c3bf7045e2ec7200b15908c439b913c02dd9c8247ff43</password>
<lastSyncAnchor>0</lastSyncAnchor>
<version>3</version>
</syncItems>
The HTTP response will contain a JSON object that looks something like this:
{"calUserIDFNM":{"id19":"test user"},"categoryGroupIDM":null,"categoryS":null,
"class":"class com.wss.calendar.server.ContactSyncItems$SyncResult",
"commandLM":null,"currentCalUserID":"id19","deletedGuidM":null,"failedI18nKey":null,
"fromServerContactsM":null,"groupIDCalUserIDSM":null,"groupIDNameM":null,
"inviteEmailGroupIDSM":null,"luidConflictM":null,"luidFailedM":null,
"luidGuidM":null,"luidSwIdM":null,
"nextSyncAnchor":1108666710000,"version":2}
In this simple example the server didn't have any items to return so there is little for you to do except to save the nextSyncAnchor.
[edit] Hello World Slow Sync Add A Contact
This assumes the server has no contacts.
If you insert the following XML into the above document after the <version> element you will cause this element to be added on the server if a duplicate item does not already exist.
<newContacts>
<array-item key="0">
<id>someLuid</id>
<telephoneNumber>555-1212</telephoneNumber>
<emailSlot1>email@localhost</emailSlot1>
<category>Work</category>
<displayName>First M. Last</displayName>
</array-item>
</newContacts>
The HTTP JSON response:
{"calUserIDFNM":{"id19":"test user"},"categoryGroupIDM":null,"categoryS":null,
"class":"class com.wss.calendar.server.ContactSyncItems$SyncResult",
"commandLM":null,"currentCalUserID":"id19","deletedGuidM":null,"failedI18nKey":null,
"fromServerContactsM":null,"groupIDCalUserIDSM":null,"groupIDNameM":null,
"inviteEmailGroupIDSM":null,"luidConflictM":null,"luidFailedM":null,
"luidGuidM":{"id19":{"someLuid":"19--1746476280"}},"luidSwIdM":null,
"nextSyncAnchor":1108666710000,"version":2}
Note the luidGuidM. If you are going to be doing syncs other than slow syncs you'll need to update your local uid (LUID) to Global uid (GUID) mapping file.
[edit] Hello World Slow Sync Add A Contact (Dupe)
This assumes the server has a single contact that is identical (duplicate) to the contact we are sending to the server.
<newContacts>
<array-item key="0">
<cn>first last</cn>
<id>someLuid</id>
<displayName>first last</displayName>
<givenName>first</givenName>
<sn>last</sn>
<emailSlot1>firstlast@home2.mark</emailSlot1>
</array-item>
</newContacts>
The HTTP JSON response:
{"calUserIDFNM":{"id19":"test user"},"categoryGroupIDM":null,"categoryS":null,
"class":"class com.wss.calendar.server.ContactSyncItems$SyncResult",
"commandLM":null,"currentCalUserID":"id19","deletedGuidM":null,"failedI18nKey":null,
"fromServerContactsM":{"id19":{"19--1746476280":{"id":"abook.mab,9631","sn":"last","cn":"first
last","givenName":"first","displayName":"first
last","emailSlot1":"firstlast@home2.mark"}}},"groupIDCalUserIDSM":null,"groupIDNameM":null,
"inviteEmailGroupIDSM":null,"luidConflictM":{"id19":{"someLuid":"19--1746476280"}},"luidFailedM":null,
"luidGuidM":{"id19":{"someLuid":"19--1746476280"}},"luidSwIdM":null,
"nextSyncAnchor":1108666710000,"version":2}
Note 1: luidConflictM tells you which items you sent (via the LUID) to the server were dupes.
Note 2: For all items in luidConflictM the fromServerContactsM contains a contact sent by the server. You may ignore this if you wish. All ScheduleWorld clients do not ignore this and replace the local value with the server value.
[edit] Hello World Slow Sync Receive A Contact
This assumes the server has a single contact and the client has no contacts.
Step 1: do a slow sync (example above)
Step 2: The HTTP JSON response:
{"calUserIDFNM":{"id19":"test user"},"categoryGroupIDM":null,"categoryS":null,
"class":"class com.wss.calendar.server.ContactSyncItems$SyncResult",
"commandLM":null,"currentCalUserID":"id19","deletedGuidM":null,"failedI18nKey":null,
"fromServerContactsM":{"id19":{"19--1746476280":{"sn":"last","cn":"first
last","givenName":"first","displayName":"first
last","emailSlot1":"firstlast@home2.mark"}}},"groupIDCalUserIDSM":null,"groupIDNameM":null,
"inviteEmailGroupIDSM":null,"luidConflictM":null,"luidFailedM":null,
"luidGuidM":{"id19":{"someLuid":"19--1746476280"}},"luidSwIdM":null,
"nextSyncAnchor":1108666710000,"version":2}
Note 1: fromServerContactsM contains all contacts sent by the server.
Note 2: fromServerContactsM can be defined like this: Map<String, Map<String, Map<String, Object>>>
- The first key (Map<String) is the user's ScheduleWorld ID prefixed with "id". You don't have to save this. If you know how to create the HTTP POST request you already know which user you are syncing.
- The second key (Map<String, Map<String) is the contact GUID. You don't need to do anything with this if you're just doing slow syncs.
- The last nested Map<String, Object> is the attribute value Map for the contact.
[edit] Supported Elements (Version 3)
This section contains a list of supported elements. These element names are the same names used in the LDAP schema. Most of these element names only contain a short description as they should be self-explanatory. Others that are non-obvious or are related to the sync process will have a longer explanation.
- Note: any element that can contain comma separated values means the text value will be split up by comma and handled as an array. For example:
<mobile>555-1212,555-1010</mobile>
- Note: all element text values are free-form text. You only have to escape the two XML entities & (&) and < (<).
- anniversary: 'Anniversary'
Format: yyyy-MM-dd
- assistantName: 'Assistant'
- assistantPhone: 'Assistant Phone'
- birthDate: 'Birthday'
Format: yyyy-MM-dd
- blogURL: 'Blog URL'
- businessRole: 'Profession'
- c: 'Work Country'
- category: 'Categories'
category can contain comma separated values.
- callbackPhone: 'Callback'
- carPhone: 'Car Phone'
- companyPhone: 'Company Phone'
- calCalURI: 'RFC 2739'
- calFBURL: 'RFC 2739'
- calCAPURI: 'RFC 2739'
- calCalAdrURI: 'RFC 2739'
- calOtherCalURIs: 'RFC 2739'
- calOtherFBURLs: 'RFC 2739'
- calOtherCAPURIs: 'RFC 2739'
- calOtherCalAdrURIs: 'RFC 2739'
- departmentNumber: 'Department'
- description: 'Description'
- dirserver: 'LdapServer'
- displayName: 'Name'
- emailSlot1: 'Email' emailSlot* elements are numbered so they retain their order no matter how they are packaged.
- emailSlot2: 'Email'
- emailSlot3: 'Email'
- emailSlot4: 'Email'
- emailSlot5: 'Email'
- emailSlot6: 'Email'
- emailSlot7: 'Email'
- emailSlot8: 'Email'
- facebookId: 'Facebook Id'
- facsimileTelephoneNumber: 'Work Fax'
- givenName: 'First'
- googletalk: 'Google Talk'
- groupwise: 'GroupWise'
- guid: 'guid'
The globally unique Id for this contact. If you are doing two-way syncs you must save this locally as you are required to provide this if you want to update or delete a contact on the server.
- homeFacsimileTelephoneNumber: 'Home Fax'
- homePhone: 'Home Phone'
homePhone can contain comma separated values.
- homePostalAddress: 'Home Street'
- homeurl: 'Home URL'
- icq: 'ICQ'
- id: 'Unique Local Identifier'
Sometimes referred to as the LUID (Locally Unique ID) This unique id is unique to your client. It will be (or will be part of) the primary key used to persist or remove a specific contact. When the server sends an update or delete request to your client it will include this id so your client knows exactly what contact to perform the operation on.
- IPPhone: 'VoIP'
- initials: 'Middle'
initials can contain comma separated values.
- internationaliSDNNumber: 'ISDN'
- jabber: 'Jabber Server'
- jpegPhoto: 'Photo'
- l: 'Work City'
- lastSync: 'Last Modified'
The server will ignore received lastSync values. The server may also not send this to your client.
- mail: 'Email'
- managerName: 'Manager'
- mobile: 'Mobile'
mobile can contain comma separated values.
- mozillaHomePostalAddress2: 'Home Street2'
- mozillaHomeLocalityName: 'Home City'
- mozillaHomeState: 'Home State'
- mozillaHomePostalCode: 'Home Postal'
- mozillaHomeCountryName: 'Home Country'
- msn: 'MSN Messenger'
- netmeeting: 'NetMeeting'
- nsAIMid: 'AIM'
- o: 'Company'
- otherFacsimileTelephoneNumber: 'Other Fax'
- otherPhone: 'Other Phone'
- otherPostalAddress: 'Other Street'
- otherPostOfficeBox: 'Other PO Box'
- otherCity: 'Other City'
- otherRegion: 'Other State'
- otherPostalCode: 'Other Postal'
- otherCountry: 'Other Country'
- pager: 'Pager'
- personalTitle: 'Prefix'
- physicalDeliveryOfficeName: 'Office'
- postalAddress: 'Work Street'
- postalCode: 'Work Postal'
- postOfficeBox: 'Home PO Box'
- primaryPhone: 'Primary Phone'
- radio: 'Radio'
- skype: 'Skype'
- sn: 'Last'
- spouseName: 'Spouse'
- st: 'Work State'
- suffix: 'Suffix'
- swId: 'ScheduleWorld unique Id'
If you receive a contact from ScheduleWorld that has a swId you can be sure this contact corresponds to a valid ScheduleWorld user, and this is the user's unique Id.
- telephoneNumber: 'Work Phone'
telephoneNumber can contain comma separated values.
- telex: 'Telex'
- title: 'Title'
- tty: 'TTY'
- videoURL: 'Video phone URL'
- workPostOfficeBox: 'Work PO Box'
- xmozillanickname: 'Nickname'
- yahoo: 'Yahoo'

