Contact Importing

Mobile Address Book and Contact Picker API Integration

We are designing a new mobile contacts integration for our Contact Picker.


In my previous articles about the Contact Picker API, I summarized the Contact Picker API and detailed my hands on experience with it. Now I’m going to discuss how CloudSponge will add an integration to our product.

Why did we write a long article about this new integration? Because we aim to add the new source in the easiest possible way *for everyone else*. Our approach is to add it so the user experience is seamless and the developer experience is transparent.

After the Contact Picker API integration, we expect to ensure this new source will include all the benefits of all the other sources, the metrics, statistics, and external integrations with third-party tools. Below I’m describing the benefits we provide here in CloudSponge and when it is possible or not to be included in the new Contact Picker API source.


What to call the new source, code, and human-friendly name?

This is a light topic but must be decided too. We need a name for this new source that must be user-friendly and at the same time explain what the source is. Today we have the following names for each of our sources:

'gmail', 'yahoo', 'outlookcom', 'aol', 'icloud', 'office365', 'outlook', 'addressbook', 'mail126', 'mail163', 'bol', 'csv', 'gmx', 'mailcom', 'mail_ru', 'naver', 'o2_pl', 'qip_ru', 'qq_mail', 'rediff', 'sapo', 'terra', 'uol', 'web_de', 'mail_yeah_net', 'yandex_ru'

These are the names we use to refer to each source in our API and CloudSponge Contact Picker, they refer to the service they integrate with, and are a no-brainer to understand. With the Contact Picker API, we need to have the same result, and let’s face contact_picker_api would be a terrible name unless you are deeply familiar with the Web APIs, you will probably not understand this the first time you see it. So in this case I was thinking of something that resembles the mobile contacts, device native interface, like device_contacts or mobile_contacts or mobile_local. Of these three alternatives, after bringing the subject to our team, we have decided the better option would be device_contacts because it communicates the source of the contacts is the computer/smartphone the browser is running on.

CloudSponge Metrics

It is important for a service to provide the customers with some metrics so they can understand how their business is performing, this is why CloudSponge collects some information, so our customers can track and improve the usage of their users when interacting with their contacts. And with the new Contact Picker API source, we must ensure we can continue providing technically feasible information to our customers.

Listed below, I will explain the metrics we provide today to our customers with a brief description of the possibilities with the new Contact Picker API source.

Collected Metrics

We are proud of the metrics that we are able to display. I’ll describe what each of our metrics means and how we may collect it in the context of the new API.

Here’s our news article about the new metrics:

Let’s review what each of these metrics means. 

People who Loaded a Page

The number of people who visited a page that included the Contact Picker script. This metric is independent of source, we collect it to measure the number of integrations with CloudSponge in each customer page. We get it for free with new sources.

People who Engaged

The number of people who launched the Contact Picker or started an address book connection. This is another metric that will be included independently of the source, the only action we need to include the new source in our source list.

People who Connected

The number of people who successfully connected one or more address books using the Contact Picker. Similar to the People who Engaged, once we include the source, we will be able to collect this information, this is related to the user who starts the process of selecting contacts in their list.

People who Submitted

The number of people who selected and submitted one or more contacts using the Contact Picker. This metric is collected on the “afterSubmit” callback, we are also able to provide it with the new source.

Successful Connection Rate

The percentage of people who successfully connected their address book using the Contact Picker (Engagements / Connected Address Books). This metric is dependent on the Engage and Connected metrics, so if we have them, we have this metric too.

Total Contacts

Total number of contacts in all address books connected using the Contact Picker. This metric aims to show the total number of contacts in a user’s address book. However, for security reasons, the Contact Picker API doesn’t provide access to this information. While we can’t offer the true total, we can track the number of contacts a user actually selects and submits. This selected count can be used as a substitute for the “total accessible contacts” metric.

Submitted Contacts

The Total number of contacts that were selected and submitted to your app using the Contact Picker. Submitted contacts are provided after the user selects and submits the contacts. We have access to this number and can provide it.

Average Submitted Contacts

The average number of contacts submitted using the Contact Picker. This is another metric based on another metric already provided, this is why we can calculate this.

Total Address Books

The number of address books connected using the API. We can say if the user connected with the Contact Picker if they select one or more contacts, so we can provide this information.

Address Books by Provider

The distribution of address books by source using the API. This lets us know if the user successfully imports the contacts, for the Contact Picker API, we can assume success as submitting one or more contacts and abandoned when the user doesn’t submit contacts.

New metric

One extra metric that can make sense to us after integrating this new source is a count of devices/OS so our customers can identify the user profile using their apps. So this could be an additional metric we will add in the future, we already collect this information, but there is not a trivial way to display it to customers, we need to extract it and group in a way it will make sense to our customers.


Finally, we get into how we will use this, we want the device_contacts source to work the same way or close enough to the sources we already have, so here is a list of what we have now, and how we could integrate the new source to it.

Launching the Source

We have three link options for CloudSponge Contact Picker, we can have the select sources listed as a Menu Link, as a Deep Link, or Launch for Javascript.

Menu Link

This I believe is the easy way to have the sources available for user interaction, here is a print screen of how it looks like on smartphones and desktops:

For this case, it is just as easy as adding a new item for the device_contacts, in the list of the image, easy peasy. Oops that is not so simple, the device_contacts does not work for desktops, it is exclusive for mobile devices, and even so it is for mobile, not all devices will support that, so we need to account for these situations. Again options, we have some here, first we could simply display the source all the time, and let the user find it doesn’t work once he clicks on it, I don’t like this alternative, it can lead the user to think there is something wrong with the CloudSponge Contact Picker, or with his device. The second alternative would be to hide the source in all situations where it is not supported, this is much better in my opinion than the first option. The third is to show the source but in a disabled state, which communicates to the users we support it but for some reason, it is not available at the moment, we could even show a message explaining why it is not available. There is also an extra option that would be to let the developer who integrates decide, that it requires adding some extra configurations in the CloudSponge Contact Picker API, it is not out of the question, but I don’t think it would be something for the initial integration.

Deep Link

Deep links are simple hypertext links you add the CloudSponge Contact Picker integration, so once the user clicks this deep link, it will open the source specifically selected then, it will skip the Menu to select the source.

In this case, since the user will have a Contacts link on the page if the new source is not supported it will not trigger the action to open the Contact Picker, we can add the option to immediately hide the link, which is a risk since we do not control the Customer interface, it could lead to a blank page, or a page without a point to the user interacts with.

This makes me think, that the best way to deal with deep links is to display them anyway, maybe disable them, maybe show an unsupported message like the image below, or in the last scenario which I think is the best one in this case, let the developer integrating it, decides how to communicate with the user about this.

Launch from Javascript

This is the option that gives the developer integration with CloudSponge Contact Picker the bigger control, it consists of a javascript function, which triggers the CloudSponge Contact Picker whenever the developer thinks it is convenient.

For this case there is not much to decide, we would let the developer integrating decide how to trigger the launcher. The only point here is the Contact Picker API requires user interaction to trigger the Contact Picker, so we need to be clear to developers that we need the user to click, focus, or interact somehow with the page to open it. It would not be possible to load the Contact Picker with a page load, or some other non-user interaction.

Receiving Contacts

The CloudSponge Contact Picker will populate the selected contacts into any HTML element that is decorated with the cloudsponge-contacts class name. This still applies to our new sources.

Additionally, we have many callbacks that happen in specific steps of our Contact Picker execution, due to the behavior of our new device_contacts, there are two in special that will have to accommodate the differences it has over the other sources, they are beforeDisplayContacts and afterSubmitContacts callbacks.
The beforeDisplayContacts is called before we display the contact list for the users, it will receive the array of contacts, the source name, and the owner information.

The afterSubmitContacs is called just after the user selects the contacts, and clicks on the next button, it receives the same parameters, array of contacts, source name, and owner, and it allows the developer to transform the contacts, before displaying the result to the users.

Because the Contact Picker API only returns the contacts after the user selects them, it is not possible to get an array of all contacts beforehand, so it defeats the purpose of beforeDisplayContacts callback.

So in this case with the new device_contacts, we don’t create different callbacks for different sources, the solution is to allow the developers to still use both callbacks, but both will be called at the same time and will receive the same parameter and values. This way we don’t create differences in our API, which will make the integration easier.

    participant User
    participant App
    participant ContactJS as Contact JS
    participant Events

    User ->> App: request
    App ->> User: response

    User ->> App: load js
    App ->> ContactJS: initializes after load
    App ->> ContactJS: onLoad

    User ->> App: clicks to launch
    App ->> ContactJS: launch
    ContactJS ->> Events: launch

    User ->> ContactJS: pick a source
    ContactJS ->> Events: launch (source)

    User ->> ContactJS: authorize / grant consent
    ContactJS ->> ContactJS: gather contacts
    ContactJS ->> Events: importComplete (source, count)

    ContactJS ->> App: render contacts
    App ->> User: contacts rendered
    ContactJS ->> Events: select (source)

    User ->> ContactJS: pick contacts
    ContactJS ->> Events: pick (source)

    User ->> ContactJS: submit contact picker
    ContactJS ->> Events: submitted (source, count)
    ContactJS ->> App: contacts delivered
    ContactJS ->> Events: close


There are many points we should consider for our integration, the device_contacts source will have some particularities I described above that will require some customization to fit in our current API, we like to keep the changes to a minimum, to keep the compatibility with our other sources, and avoid special cases for different sources, this leads to extra complexity when developer have to integrate their products, and we want to keep CloudSponge as easy as possible to integrate with.

Overall, the Contact Picker API is pretty straightforward to integrate with. Support for it is pretty limited at this time, so it’s not going to replace the online contact sources soon. Using CloudSponge’s Contact Picker ensures that you get the best user experience today, and as these APIs evolve into the future.

We may face some other internal challenges when the integration starts, but with this document, we have a detailed overview of the principal points in our structure we have to consider when touching our code.

I hope shortly we can communicate to our customers the good news that device_contacts is ready to use.

This is the third article in a series about the Contact Picker API. Read the first article about our experiment with the Contact Picker API and the second article about the results of the experiment.

Alfredo Ribeiro, Senior Software Engineer at CloudSponge

Follow @aribeiro


Try CloudSponge for free in your
testing environment

Get Started

Have a questions or prefer a guided tour?
Schedule a consultation with our Founder.