DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’» is a community of 963,673 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
Cover image for Import contacts from Google
Ahmed Yagoub
Ahmed Yagoub

Posted on

Import contacts from Google

Introduction

in this article, you will see how to add a feature to your app (I built mine in Vue) which allows users to import their contacts from their google account.

Google supports this functionality through their People's Api.

Prerequisites

The first step is to create a project in google cloud platform and get the key and client id to be used in the code. You might want to save them in .env file.

the second step is to load the script file for google api (gapi) to your entry html file.

<script src="https://apis.google.com/js/api.js"></script>
Enter fullscreen mode Exit fullscreen mode

after which gapi will be available in window

The code

I have dedicated a specific file for implementing the people api in my project that includes all the code below.

After following the steps in the prerequisite section, we can destructure gapi from window as well as the key and client id from process.env since they are saved in .env file.

const { gapi } = window;
const {
  PEOPLE_KEY: peopleApiKey,
  PEOPLE_CLIENT_ID: peopleClientId,
} = process.env;
Enter fullscreen mode Exit fullscreen mode

Now, we load the API client and auth2 library

export default function getGoogleContacts() {
  // Load the API client and auth2 library
  gapi.load('client:auth2', initClient);
}
Enter fullscreen mode Exit fullscreen mode

getGoogleContacts is exported as it will be called and used somewhere else in the project.

initClient is the function that is used to initialize the JS client library as shown:

function initClient() {
  // initialize the JS client library
  gapi.client
    .init({
      apiKey: peopleApiKey,
      clientId: peopleClientId,
      // scope is a space delimited string
      scope: 'https://www.googleapis.com/auth/contacts.readonly',
    })
    .then(() => {
// will show this code down πŸ‘‡
    })
    .catch((error) => console.error(error));
}
Enter fullscreen mode Exit fullscreen mode

the init function takes the apikey, clientId from the project you created in google cloud platform. As well as scope, and you can pass more than one, however, we are only interested in the contacts scope.
You can see the list of scopes πŸ‘‰ People Api scopes

the .then block that I skipped above includes this code

      var GoogleAuth = gapi.auth2.getAuthInstance();
      // Listen for sign-in state changes.
      GoogleAuth.isSignedIn.listen(updateSigninStatus);
      // Handle the initial sign-in state.
      updateSigninStatus(GoogleAuth.isSignedIn.get());
Enter fullscreen mode Exit fullscreen mode

It uses auth2 for authentication and to allow the user to sign in and agree to import their contacts

it first checks if the user is already signed in, otherwise it brings the sign in page.

function updateSigninStatus(isSignedIn) {
  if (isSignedIn) {
    makeApiCall();
  } else {
    GoogleAuth.signIn();
  }
}
Enter fullscreen mode Exit fullscreen mode

if the user is signed in, we make the api call

function makeApiCall() {
  // https://developers.google.com/people/api/rest/v1/people.connections/list
  gapi.client.people.people.connections
    .list({
      resourceName: 'people/me', // deprecated (required for now)
      personFields: 'emailAddresses,names,phoneNumbers',
    })
    .then((response) => {
      formatResults(response.result.connections);
    })
    .catch((error) => {
      return error.result.error.message;
    });
}
Enter fullscreen mode Exit fullscreen mode

we specify the resourceName which can only be people/me, but I realize it is deprecated (not sure of the alternative).
we also specify the fields we want back.

Bonus step

I have also chosen to format the response once I get it and before I commit it to the store and use it in the app.

You could potentially console.log the response to see how it looks like and format it however you want, but here is an example.

// [{first: '', last: '', email: [], phone: []}] that is the format I want!
function formatResults(arrayComingFromPeopleApi) {
  const resources = arrayComingFromPeopleApi.map((resource) => {
    // get multiple email addresses and phone numbers if applicable
    const { emailAddresses = [], names = [], phoneNumbers = [] } = resource;
    const email = emailAddresses.map((email = {}) => email.value || '');
    const phone = phoneNumbers.map((phone = {}) => phone.value || '');
    const lastName = names.map((name = {}) => name.familyName || '');
    const firstName = names.map((name = {}) => name.givenName || '');

    return {
      first: firstName[0],
      last: lastName[0],
      email,
      phone,
    };
  });
  // commit the resources to the store
}
Enter fullscreen mode Exit fullscreen mode

References

https://github.com/google/google-api-javascript-client

Top comments (0)

Visualizing Promises and Async/Await 🀯

async await

☝️ Check out this all-time classic DEV post