Contact Collector deprecated
This article describes the contact collector feature.
Overview
The contact collector helps users find contacts more easily. It does two things:
- It collects addresses: whenever a user interacts with an email address that is not yet known as a contact, it stores that address as a new contact in a dedicated address book, "Collected addresses". The address can then be found again, for example in the auto-complete of the mail compose window, without the user having to create a contact by hand.
- It tracks usage: every interaction with a contact, group or resource increases that entity's use count, and auto-complete results are sorted by it. If a user has the contacts "John Doe" and "Jane Doe" and interacts more often with John, John is offered first when typing "Doe".
Both parts require the collectemailaddresses module permission (capability collect_email_addresses). Without it the collector does nothing for the user.
Details
Triggers
The collector runs whenever the user "uses" an email address or contact. This includes, but is not limited to:
- Sending or reading a mail, if the user has collection on mail transport or mail access switched on (see Configuration)
- Inviting an external attendee to an appointment
- Inviting an external participant to a task
- Sharing something (a file, a folder) with an email address
- Picking an address in a client, which reports it through the use count API (
PUT /usecount?action=increment)
Every run works on a set of email addresses. The user's own aliases are removed from that set first.
What a run does
For each address, the collector looks for an existing contact with that email address in all address books the user can see, including the global address book and the address books of other contact providers. Contacts in the contacts Trash folder are ignored.
- If a contact exists, its use count is increased. Nothing is stored. Where several contacts carry the same address, at most
com.openexchange.contactcollector.searchLimitof them, the most used ones, are increased. - If no contact exists, a new contact with the address as its email and the display name taken from the address is created in the "Collected addresses" folder, and its use count is increased.
Mail runs happen asynchronously in the background; the use count API runs the collector synchronously within the request.
The "Collected addresses" folder
The folder is a private address book below the user's default address book. Its name is predefined and shown localized in the language of the user who looks at it, for example "Collected addresses" or "Gesammelte Adressen". It carries the marker "__ccf#": true in its folder metadata and is flagged as a standard folder.
The folder is created on demand: the first time a run has an address to store and the user has no such folder yet, the folder is created and the address is stored in it. Until then the user has no "Collected addresses" folder, and the setting modules/mail/contactCollectFolder (io.ox/mail//contactCollectFolder in the JSlob) reports no folder. A run that only increases use counts of known contacts does not create the folder. With the default configuration the mail triggers are off, so many users get the folder only through an appointment, a task or a share with an external address, and users who never do any of that never get one.
Concurrent runs of the same user, for example from two devices, create the folder only once; a cluster-wide lock guards the creation. Earlier versions created the folder for every user at login. Folders created that way stay valid and are used as they are.
The folder the collector stores into is the one registered in the setting modules/mail/contactCollectFolder. A user may point that setting at another address book of theirs; the collector then stores into that folder and creates no "Collected addresses" folder. If the setting points at a folder that no longer exists, a new folder is created and registered.
Deleting the folder
Users can delete the "Collected addresses" folder like any other address book, unless com.openexchange.contactcollector.folder.deleteDenied forbids it. Deleting it clears the setting and switches off collection on mail access and on mail transport for that user, so that the next mail does not bring the folder straight back. Both switches can be re-enabled in the mail settings. Runs triggered outside of mail, an appointment with an external attendee for instance, are not affected by the switches and recreate the folder with the next unknown address.
Cleaning up collected contacts
Collected contacts can pile up. Two mechanisms keep them in check:
- Removal of unused collected contacts, controlled by
com.openexchange.contactcollector.cleanupUnusedAfter. Before each collector run, contacts in the collect folder that are older than the configured time span, have a use count below 2 and were never edited (only the initially set fields) are deleted. The clean-up runs per user as part of a collector run, not on a schedule. The default0switches it off. - Decay of use counts, controlled by
com.openexchange.objectusecount.cleanupTimespan. Once a day a job decreases the use count of every entity that has not been used for the configured time span by one, so that contacts from a short, intense burst of interaction do not overshadow more recently used ones for good. Decreasing the use count also touches the entity, so it is decreased again only after the time span has passed once more.
Notes for clients
- Do not assume the folder exists after login. The setting
modules/mail/contactCollectFolderis absent until the first address has been collected, and the folder can appear during a session as a side effect of sending a mail, inviting an attendee, or picking an address. There is no push notification for it; clients see the folder with their next folder listing. - Recognize the folder by the metadata marker
"__ccf#": truerather than by the setting read at login. Folders created before 2020 lack the marker; for those the setting is the fallback. - The use count API (
PUT /usecount?action=incrementwith amailaddress) runs the collector synchronously and creates the folder if needed, which makes it a deterministic way to provision the folder, for example in tests.
Configuration
All properties, with their defaults:
# Whether the contact collector is available at all. Not reloadable.
com.openexchange.contactcollector.enabled = true
# How many contacts carrying the same email address get their use count
# increased per run (the most used ones first). Not reloadable.
com.openexchange.contactcollector.searchLimit = 5
# Whether users are prevented from deleting their "Collected addresses"
# folder. Reloadable and config-cascade aware.
com.openexchange.contactcollector.folder.deleteDenied = false
# Time span after which unused, unchanged collected contacts are deleted
# before a collector run; 0 switches the clean-up off. Accepts units such
# as 30D or 4W. Config-cascade aware.
com.openexchange.contactcollector.cleanupUnusedAfter = 0
# Time span after which the use count of unused entities is decreased by
# one, once a day. Accepts units such as 30D or 4W.
com.openexchange.objectusecount.cleanupTimespan = 4W
# Whether reading and sending mails trigger the collector. Both are off by
# default, config-cascade aware, and users can change them for themselves
# in the mail settings (io.ox/mail//contactCollectOnMailAccess and
# io.ox/mail//contactCollectOnMailTransport).
com.openexchange.user.contactCollectOnMailAccess = false
com.openexchange.user.contactCollectOnMailTransport = false
# Look-ahead factor for external contact storages without a use count of
# their own: the contacts requested are multiplied by this factor to
# improve the sorting by use count.
com.openexchange.contacts.useCountLookAhead = 10