Skip to main content

Microsoft Graph Contactsync

Auto-generated

This page is imported automatically from an external repository.

Source project: Open repository

This module is used for syncing ADITO contacts with exchange. It uses the microsoft graph api and therefore the microsoft-graph-api module for handling the communication.


Prerequisites

The permission Contacts.ReadWrite must be configured as an Application permission in the linked Microsoft Entra application. In addition to the permissions, an MicrosoftGraph Auth alias is also required.
Per default the alias, shipped by the microsoft-graph-api module is used. But you can also use a custom Auth Alias or other Authentication flows described later in this file.

info

This module cannot be used with the deprecated ews-sync module.

Project Preferences

In order to use this module, some project preferences are required.

KeyDescriptionExample
microsoftGraph.contactSync.activeControlls if the MicrosoftGraph contactSync is activated.false
microsoftGraph.contactSync.syncSizeDefines how big a filter for synchronizing to Outlook may be7200
microsoftGraph.contactSync.folderNameName of the folder in which contacts should get synced toADITO
note

The default of microsoftGraph.contactSync.active is false on purpose: customers usually have no test Exchange, so the sync would run against production. A default of true risks flooding Outlook with test contacts that are hard to remove.


About this module

Contacts are not synchronized individually but via filters according to exchange. Users can mark saved searches for synchronization. Those saved filters are then transfered to exchange.
Contacts which are syncronized are stored in the AB_SYNCCONTACT table.

In order for contacts to be synchronized, the processes manageContactSyncTable_serverProcess and GraphSyncToExchange_serverProcess has to be executed.
It's important that the process manageContactSyncTable_serverProcess has to run before the GraphSyncToExchange_serverProcess

manageContactSyncTable_serverProcess

Is used for processing the syncronization filter and writing the contactId into the AB_SYNCCONTACT table.
This process checks the filter which are in the SEARCHFILTER database table. Those filters are marked for synchronization by an user.
When a filter gets deleted by an user the Searchfilter will be also deleted. Contacts of the deleted filter are marked for deletion and will be removed from exchange within the next syncrhonization run.

Inserting contacts

If a user creates a new contact with the LASTNAME "mustermann" the contact will be automatically inserted by the process.

Updating contacts

In order to respond to updates and deletions, there is an audit layer (process_audit_service/graphContactSync_impl) that logs these changes and writes the update flag to the AB_SYNCCONTACT table.
The process AuditUpdateGraphSyncEntries() is used for that.
In this function, a service can be implemented to specify which columns the corresponding entries in the AB_SYNCCONTACT should be updated for if a change is made to the contact.

Check the documentation property of the auditUpdateGraphSyncEntriesAffectedDB_service for the correct usage of the service.

GraphSyncToExchange_serverProcess

This process is used for syncronizing contacts to Exchange.
This Process uses the default auth alias of the microsoft-graph-api module. You can set your own alias by implementing the graphSyncAuthConfig_service.
The implementation has to return the authentication config object, created by the auth.createConfigFor core methods.

note

There should only be one implementation of the graphSyncAuthConfig_service

Contacts are syncronized into a subfolder defined by project preferences. Its default is ADITO.
If the configured contact folder does not exist for a user, it is created automatically on the next sync run.

By default the sync runs for all Exchange users. To restrict it to a specific subset, implement the graphSyncUserIdList_service:
The implementation returns an array of ADITO user IDs. If multiple implementations are registered, their lists are combined and duplicate IDs are ignored. When no implementation returns any user IDs, the process falls back to all Exchange users.

tip

Check the documentation of the graphSyncUserIdList_service for implementation advice.

The process will insert / update / delete contacts for each user based on the entries in the AB_SYNCCONTACT table.
In the default variant of Contactsyncronization, we only syncronize to Exchange; no data is written back to ADITO.
Therefore, if a dataset is changed in Exchange — for example, if the phone number is changed — this change would not be written back to ADITO.
If a change to that specific dataset appears in ADITO, the contact will be synced again and the changes made in Exchange will be overwritten.

Insert

Entries which doesn't have an EXCHANGEID set are inserted to Exchange. While inserting the dataset to Exchange an ID is returned. This ID will be stored in the AB_SYNCCONTACT table.

Update

Entries with a filled EXCHANGEID column and the update flag in the column UPDATECONTACT are updated in Exchange.
The function GraphContactSyncUtils.updateExchangeContactsForUser selects the required contactIds and gets their contact data by the getAddressData method of the AddressFormatter_lib.
The loaded fields are defined in the getExchangeContactKeyConfig_service implementation of this module. It can be extended by additional implementations.

tip

Check the documentation of the getExchangeContactKeyConfig_service for implementation advice.

Some of the fields returned by this implementation have a prefix, which are used for a special handling.
The currently used prefix are:

  • Business
    • the address collection of the company
  • businessPhones
    • in exchange the business phones are combined in one single collection
  • emailAddresses
    • in exchange the email addresses are combined in an collection
  • technical
    • technical fields arent syncronized to exchange but are needed by the callback function

The requests to the graph api are made in batches. Instead of calling the endpoints individually, they are combined in a batching request.
Batching is described in the graph-api module
Therefore a batching blueprint was made in order to provide a cosistencyy accross the methods.

The Method GraphContactSyncUtils.processContactsBatch is used for the actual webservice call. It accepts a callback function in it's paramater values. This callback function can be used to process the response of the Microsoft Graph Api. There are 3 different callback functions:

  • GraphContactSyncUtils.handleInsertBatchResponse
  • GraphContactSyncUtils.handleUpdateBatchResponse
  • GraphContactSyncUtils.handleDeleteBatchResponse

Delete

Entries with a filled EXCHANGEID and DATE_DEL column are removed from exchange and the AB_SYNCCONTACT table.

Syncronized data

By default the following contact data is syncronized to Exchange.

ADITO KeyExchange Fieldname
PERSON.SALUTATIONtitle
PERSON.FIRSTNAMEgivenName
PERSON.LASTNAMEsurname
CONTACT.DEPARTMENTdepartment
CONTACT.CONTACTROLEjobTitle
ORGANISATION.NAMEcompanyName
ADDRESS & BuildingNoBusiness_street
ADDRESS.CITYBusiness_city
ADDRESS.ZIPBusiness_postalCode
ADDRESS.PROVINCEBusiness_state
NAME_LATINBusiness_countryOrregion
COMMINTERNET(Subsql)BusinessHomepage
CommUtil.getStandardSubSqlMail()emailAddresses_address
COMMPHONE(Subsql)businessPhones_BusinessPhone
COMMPHONE(Subsql)businessPhones_BusinessPhone2
COMMMOBIL(Subsql)businessPhones_MobilePhone
COMMMOBIL(Subsql)mobilePhone

The Ressource in microsoft graph supports following fields.

Contact Ressource

Additional fields can be transferred via a service implementation(getExchangeContactKeyConfig_service). Naturally, this only applies to fields that are supported by Exchange.

Throttling

Throttling occurs when too many requests are sent to Microsoft Graph. To deal with throttling during contact synchronisation, explicit handling must be implemented.

The synchronization process is designed to run automatically at configurable scheduled intervals.

If the Microsoft Graph API returns a retry indication (HTTP 429 with a Retry-After header), the following handling is intended:

  • If the Retry-After wait time exceeds the interval until the next scheduled process start, the current process run should be aborted completely. In this case, an immediate notification is sent to the administrator, and the process must be restarted manually.

  • If the Retry-After wait time is less than or equal to the time until the next scheduled run, the current process run should be interrupted, allowing the next scheduled run to start automatically as planned.