Search code examples
google-apps-scriptgoogle-people-api

searchContacts() email query: is it broken?


I've been working on a personal Apps Script lately for pulling contact info from a spreadsheet, checking if it exists in my contacts, and adding or modifying the contact based on whether it exists or not. I asked another question recently related to this script.

I've got pretty much the whole thing functional now. However... I keep getting inconsistent results when using the People API method .searchContacts(). I've checked the documentation here, as well as plenty of posts here on stackoverflow, but can't seem to get it working. I'm wondering if it's because I'm trying to query for an email address, since I saw that queries for phone numbers seem to be broken...

I have a function that takes an email address as input, and returns a person object, as follows:

function checkEmailExists(email) {
    var personObject = People.People.searchContacts({
      "query": email.toString(),
      "readMask": "emailAddresses,memberships"
    });
  return personObject;
}   

Since I'm pulling the email address from an object in an array that I've set up, I tried to stringify the email before running the query, just to make sure that wasn't the issue.

Per the documentation, I run this function twice, once with an empty set of double quotes as a "warmup," wait a few seconds, then again with the actual e-mail, as follows:

Logger.log('Email to check: ' + contact.email);
var personObjectByEmail = checkEmailExists("");
    Logger
      .log('Run warmup of checking for contact...')
      .log(personObjectByEmail);
    Utilities.sleep(5000);
var personObjectByEmail = checkEmailExists(contact.email);
    Logger
      .log('Check for actual contact e-mail.')
      .log(personObjectByEmail);
// If contact is not found, represented by empty braces "{}", the contact will be added with addToContacts(), a separate function that works as expected and adds the contact to my Google Contacts

But in this case, my returned value will more often than not produce two sets of empty brace results, even if the contact exists in my contacts already. So I keep getting duplicates whenever I run the script.

Log Results
1:25:23 PM Info Email to check: [email protected]
1:25:23 PM Info Check if email exists in contacts...
1:25:23 PM Info Run warmup of checking for contact...
1:25:23 PM Info {}
1:25:28 PM Info Check for actual contact e-mail.
1:25:28 PM Info {}

I don't know what exactly I'm doing wrong, or if it's just an issue with email queries being broken like phone number queries apparently are... I know I can use another method to just pull the whole contact list and search through that myself instead, but I was hoping to use this method to reduce the amount of code I'm having to type out and use on my end.

To clarify: The email I'm searching for is confirmed as already in my Google Contacts. Sometimes I receive an object as the function's output, but sometimes it's empty braces like above.


Solution

  • About your current issue of But in this case, my returned value will more often than not produce two sets of empty brace results, even if the contact exists in my contacts already., unfortunately, I couldn't replicate your situation. When I tested your showing script with a sample email address, the object of the search email was returned every run.

    From this situation, in this case, how about using a workaround using another approach? This workaround is as follows.

    1. Retrieve all email addresses in your contact as a list.
    2. Search the specific email address from the list.

    When this is reflected in a sample script, how about the following sample script?

    Sample script:

    function searchEmail_(email) {
      const values = new Set();
      let pageToken = "";
      do {
        const obj = People.People.Connections.list("people/me", { personFields: "emailAddresses", fields: "connections.emailAddresses.value", pageSize: 1000, pageToken });
        obj.connections.forEach(({ emailAddresses }) => emailAddresses.forEach(({ value }) => values.add(value)));
        pageToken = obj.nextPageToken;
      } while (pageToken);
    
      // If you want to include OtherContacts in the search object, please use the following script.
      // do {
      //   const obj = People.OtherContacts.list({ readMask: "emailAddresses", fields: "otherContacts.emailAddresses.value", pageSize: 1000, pageToken });
      //   obj.otherContacts.forEach(({ emailAddresses }) => emailAddresses.forEach(({ value }) => values.add(value)));
      //   pageToken = obj.nextPageToken;
      // } while (pageToken);
    
      return values.has(email);
    }
    
    // Please run this function.
    function sample() {
      const email = "###"; // Please set your search email address.
    
      const check = searchEmail_(email);
      if (check) {
        console.log("Email was found.");
      } else {
        console.log("Email was not found.");
      }
    }
    
    • In this sample script, when the search email address is included in "People.People.Connections.list", true is returned.

    Reference: