Read Phone Contacts with JavaScript

WBOY
Release: 2024-08-19 18:33:25
Original
710 people have browsed it

Author's note: The technologies and processes described in this article areexperimental and will only work in a few browsers. At the moment of writing, the Contact Picker API was only supported by Android Chrome (from version 80) and iOS Safari (from version 14.5, but only behind a flag). If you want to review the functionality, you can check a running demo on my website.


Reading entries from the contact list on a phone or tablet has traditionally been limited to native apps. But with the Contact Picker API, we can do just that using JavaScript.

This feature can be interesting in apps that need contact information like phone numbers or VoIP, social networks where we want to discover known people, or apps that require filling in form information without swapping applications to view the data.

The API and the device will limit which properties will be available. There are five standard ones that developers can select:

  • Names
  • Phones
  • Emails
  • Addresses
  • Icons

The plurals here are important, as a contact can have more than one phone, email, or multiple addresses. The returned data will always be inside arrays for consistency, even if it is a single value. More on that later.


Privacy and Security

The contact information stored on a phone can contain sensitive information that we must treat carefully. Because of that, there are privacy and security considerations that we must take into account:

  • The Contact Picker API code must run in the top-level browsing context. It prevents external code, like ads or third-party plugins, from reading the contacts list on your phone.
  • The Contact Picker API code can only run after a user gesture. Thus, developers cannot fully automate the process. The user must act to trigger the contact reading.
  • The person must allow access to the contact list. This restriction is imposed by the phone and not by JS. The user must grant the browser permission to access the contacts (if it doesn't already have it).

The first time that they use a website that uses the Contact Picker API, they may get a message like this:

Read Phone Contacts with JavaScript

Some people may find this pop-up "scary."

The phone will display this pop-up every time until the user taps "Allow." The Contact Picker API won't run until that happens. Which is good; we want to ensure users grant the proper permissions. It's also good that it's a one-time thing; granting authorization each time the page runs the Contact Picker API code would be a pain in the neck.


The API and Code

The Contact Picker API only defines two methods:

  • getProperties(): returns a list of the properties available to read on the device. In the definition, there are only five: "address", "email", "icon" (this may not be the contact picture), "name", "tel" (telephone), but the device may not allow access to all of them.
  • select(): opens the contact pop-up and returns the selection once the user completes the action. It takes two parameters: a list of the properties to read and an optional object with options.

Both methods return promises, but taking into account that the actions that they trigger block the regular flow of the app, we should use async / await when handling them.

It may be tempting to ignore getProperties() and request all the properties directly. But beware if you do that: it will likely work, but if any of the specified properties is unavailable, the select() method will throw an exception.

Example

A demo of the Contact Picker API is in action (run it online here or watch this video). If the API is supported, it shows a button that reads the contact's telephone number, name, and email to display it.

First, we need the button. As detailed earlier in the Privacy and Security section, a user action is required before we can call the API, so we cannot trigger anything without user interaction:

Copy after login

The main code will be in the getContactData() function. But before that, what would be the point of showing the button if the Contact Picker API is unavailable? Let's hide the button if it is not available. Or even better, let's hide the button by default (adding the hidden attribute) and only show it if the API is available.

// only show the button if browser supports Contact Picker API if ("contacts" in navigator) { document.querySelector("button").removeAttribute("hidden"); }
Copy after login

Now that the button logic is in place let's focus on getContactData(). Here's a commented version of the function:

// it is asynchronous because we'll wait for the modal selection async function getContactData() { // indicate what contact values will be read const props = ["tel", "name", "email"]; // wrap everything in a try...catch, just in case try { // open the native contact selector (after permission is granted) const contacts = await navigator.contacts.select(props); // this will execute after the native contact selector is closed if (contacts.length) { // if there's data, show it alert("Selected data: " + JSON.stringify(contacts)); } else { // ...if not, indicate nothing was selected alert("No selection done"); } } catch (ex) { // if something fails, show the error message alert(ex.message) } }
Copy after login

Once the button triggers this function, and if the browser has permissions (see screenshot in the previous section), the contact modal will show up, indicating essential information: the URL reading the data, what data it will return, and the list of contacts to pick from.

Read Phone Contacts with JavaScript

The Contact Picker shows what information will be shared

After closing the modal, thecontacts variable will store the data in JSONas an array with an object containing the information requested (it may be empty if it is not available in the contact card).

For example, this is the result after selecting myself as a contact (fake data):

[ { "address": [], "email": [ "alvarosemail@gmail.com" ], "icon": [], "name": [ "Alvaro Montoro" ], "tel": [ "555-555-5555", "555-123-4567" ] } ]
Copy after login

If the data includes an icon, it will be a blob with the image. If the data includes an address, it will be a more complex object with street, city, country, ZIP code, etc. You can check the returned values in the specification.

But why an array if we only selected one contact? Because there's an option to choose more than one contact!

Selecting Multiple Contacts

It is possible to select more than one contact. If we want to do that, we need to pass a second parameter to the navigator.contacts.select() method indicating this option.

const props = ["tel", "address", "icon", "name", "email"]; // only one option available: read multiple or only one (default) const options = { multiple: true }; try { const contacts = await navigator.contacts.select(props, options); // ...
Copy after login

The result is an array of contacts, so the rest of the code could remain the same for this example.


The code above can be intimidating, mainly because of all the comments I added. Here's a lightly commented version of the code above. As you may notice, it is pretty simple:

async function getContactData() { if ("contacts" in navigator) { const props = await navigator.contacts.getProperties(); const options = { multiple: true }; try { const contacts = await navigator.contacts.select(props, options); if (contacts.length) { // code managing the selected data } else { // code when nothing was selected } } catch (ex) { // code if there was an error } } }
Copy after login

You can check out a running demo on my website. Don't worry, I don't do any with the contact information beyond writing it on the screen. But review the code before if you don't trust me.


Conclusion: Privacy Over Piracy

Contact information is PII (Personally Identifiable Information), and we must treat it with all the care and security that sensitive data requires.

Apart from possible legal requirements that I am not going to go through (because I don't know them, and they change from country to country), here are some basic guidelines when dealing with sensitive data:

  • Respect people's privacy. Don't force them to share information they don't want to share.
  • Treat the data with care and in a safe way. Would you be comfortable if the data you are processing were yours?
  • Don't store data if you don't need to. Read it, use it, forget it. Don't store data that you are not using.
  • Only get the data that you need. Don't be sneaky or shady. Get just what's required to build credibility and trust.

Suppose a web app tries to read addresses, names, or emails while selecting a phone number. If that happened to me, I would automatically reject the permission and leave the website.

So, explore JavaScript and the Contact Picker API, but always remember that there's a person behind the screen and that the data they share could be risky if it falls into the wrong hands. Don't be reckless.



If you enjoyed this article about JavaScript and like to test Web APIs and different things with JS, check out this other article:


Develop a Rock Band game with HTML and JavaScript
Read Phone Contacts with JavaScript

The above is the detailed content of Read Phone Contacts with JavaScript. For more information, please follow other related articles on the PHP Chinese website!

source:dev.to
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!