Deleting a contact/person from Google Contacts by using its resourceName - retreived from a Cell in a Google Sheet

97 Views Asked by At
GOAL: 
What i want to achieve is that i can pick in a list of resourceNames a specific resourceName and when i run the function in the (special) menu of my GoogleSheet, the selected resourceName is used to delete the person in the Google Contacts

person in googlesheet

enter image description here

I have activated the Peopleapi as a service - in the code editor.

When i run the function i get this message: "person with the resourceName "xxx" does not exits in "

enter image description here I wrote these functions, i expected that the person with the corresponding resourceName woule be deleted from the GoogleContacts.

`function deletePerson() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var resourceNameColumn = 1;  // Column A
  var resourceNameRow = 2;     // Start row 2

  // get the resourceName form the cell in the sheet
  var resourceName = sheet.getRange(resourceNameRow, resourceNameColumn).getValue();
  // var resourceName = "person/c4736325340303186435"
  //"person/c4736325340303186435";

  // Search for the person with the given resourceName in the People API
  var contactPerson = searchContactPerson(resourceName);

  if (contactPerson) {
    // if the person is found, get the unstructuredName en delete the person 
    var unstructuredName = contactPerson.names[0].unstructuredName;
    deleteContactPersoon(contactPerson.resourceName);
    
    // Give a message to the user that the person is deleted
    Browser.msgBox('Succes', 'Person with unstructuredName "' + unstructuredName + '" is deleted.', Browser.Buttons.OK);
  } else {
    // Giver a message to the user if the person is not found
    Browser.msgBox('Not Okay', 'Person with the resourceName "' + resourceName + '" does not exists als contactperson.', Browser.Buttons.OK);
  }
}

// Function to find the contactperson by means of the resourceName
function searchContactPerson(resourceName) {
//  var contacten = People.People.Connections.list('people/me').connections;
  var contacts = People.People.Connections.list('people/me', {
      //personFields: 'names,emailAddresses,addresses,resourceName,birthdays,phoneNumbers,urls,organizations,biographies'
      personFields: 'names'});
  for (var i = 0; i < contacts.length; i++) {
    if (contacts[i].resourceName == resourceName) {
      return contacts[i];
    }
  }
  return null; // Return null if person is not found
}

// Function to delete the contactperson by means of the resourceName
function deleteContactPerson(resourceName) {
  People.People.Connections.deleteContact(resourceName);
}`
1

There are 1 best solutions below

19
Tanaike On

Modification points:

  • In the case of "Method: people.connections.list", the property of resourceName is in an array connections. So, in this case, your function searchContactPerson is required to be as follows. I guessed that the reason for your 1st issue is due to this.

    function searchContactPerson(resourceName) {
      var contacts = People.People.Connections.list('people/me', { personFields: 'names' });
      for (var i = 0; i < contacts.connections.length; i++) {
        if (contacts.connections[i].resourceName == resourceName) {
          return contacts.connections[i];
        }
      }
      return null;
    }
    
  • In your showing script, deleteContactPersoon of deleteContactPersoon(contactPerson.resourceName) is not declared. So, when your script is run, an error occurs at this line. I think that this is your 2nd issue.

  • In order to delete a contact, People.People.Connections.deleteContact(resourceName) is required to be modified to People.People.deleteContact(resourceName);. I think that this is your 3rd issue.

  • In order to search the contact using resourceName, I thought that "Method: people.getBatchGet" might be able to be used. In this case, it is not required to use a loop.

Modified script 1:

When your showing script is modified it becomes as follows.

function deletePerson() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var resourceNameColumn = 1;  // Column A
  var resourceNameRow = 2;     // Start row 2

  // get the resourceName form the cell in the sheet
  var resourceName = sheet.getRange(resourceNameRow, resourceNameColumn).getValue();

  // Search for the person with the given resourceName in the People API
  var contactPerson = searchContactPerson(resourceName);
  if (contactPerson) {
    // if the person is found, get the unstructuredName en delete the person 
    var unstructuredName = contactPerson.names[0].unstructuredName;
    deleteContactPerson(contactPerson.resourceName);

    // Give a message to the user that the person is deleted
    Browser.msgBox('Succes', 'Person with unstructuredName "' + unstructuredName + '" is deleted.', Browser.Buttons.OK);
  } else {
    // Giver a message to the user if the person is not found
    Browser.msgBox('Not Okay', 'Person with the resourceName "' + resourceName + '" does not exists als contactperson.', Browser.Buttons.OK);
  }
}

// Function to find the contactperson by means of the resourceName
function searchContactPerson(resourceName) {
  var contacts = People.People.Connections.list('people/me', { personFields: 'names' });
  for (var i = 0; i < contacts.connections.length; i++) {
    if (contacts.connections[i].resourceName == resourceName) {
      return contacts.connections[i];
    }
  }
  return null;
}

// Function to delete the contactperson by means of the resourceName
function deleteContactPerson(resourceName) {
  People.People.deleteContact(resourceName);
}
  • When this script is run, when resourceName is existing, the contact of resourceName is deleted. Please be careful about this.

Modified script 2:

As another approach, when the method for searching a contact using resourceName is changed, it becomes as follows.

function deletePerson() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var resourceNameColumn = 1;  // Column A
  var resourceNameRow = 2;     // Start row 2
  var resourceName = sheet.getRange(resourceNameRow, resourceNameColumn).getValue();
  var contactPerson = searchContactPerson(resourceName);
  if (contactPerson) {
    deleteContactPerson(resourceName);
    Browser.msgBox('Succes', 'Person with unstructuredName "' + contactPerson + '" is deleted.', Browser.Buttons.OK);
  } else {
    Browser.msgBox('Not Okay', 'Person with the resourceName "' + resourceName + '" does not exists als contactperson.', Browser.Buttons.OK);
  }
}

function searchContactPerson(resourceName) {
  var res = People.People.getBatchGet({ personFields: "names", resourceNames: [resourceName] }).responses[0];
  return res.httpStatusCode == 200 ? res.person?.names[0]?.unstructuredName : false;
}

function deleteContactPerson(resourceName) {
  People.People.deleteContact(resourceName);
}

References:

Added:

From the following reply,

You wrote "the value of the resourceName is required to be people/###" See: my remark at "Second try i changed the value of person" I obtained the value (contacts.google.com/person/cXXXXXXXXXXXXXXX ) from the Google Contacts.

I understood that your value of sheet.getRange(resourceNameRow, resourceNameColumn).getValue() is like person/c###. Unfortunately, this cannot be directly used with People API. I think that this is the reason for your current issue. In this case, it is required to convert person/c### to people/c###. When this is reflected in my 2nd script, it becomes as follows.

Sample script:

// ref: https://medium.com/google-cloud/convert-contact-url-to-resource-name-for-people-api-using-google-apps-script-96457e6f9597
function convertPersonToPeople_(person) {
  if (!(/^person\/c[\d]*$/).test(person)) {
    throw new Error("Invalid value.");
  }

  // ref: https://stackoverflow.com/a/21668344
  function dec2hex(str) { // .toString(16) only works up to 2^53
    var dec = str.toString().split(''), sum = [], hex = [], i, s
    while (dec.length) {
      s = 1 * dec.shift()
      for (i = 0; s || i < sum.length; i++) {
        s += (sum[i] || 0) * 10
        sum[i] = s % 16
        s = (s - sum[i]) / 16
      }
    }
    while (sum.length) {
      hex.push(sum.pop().toString(16))
    }
    return hex.join('')
  }

  // Convert decimal to hexadecimal.
  const hexadecimalValue = dec2hex(person.replace("person/c", ""));

  // Search contact.
  let res = null;
  let pageToken = "";
  do {
    const obj = People.People.Connections.list("people/me", { personFields: "emailAddresses", pageSize: 1000, pageToken });
    if (obj.connections.length > 0) {
      const t = obj.connections.find(c => c.emailAddresses.some(e => e.metadata.source.id == hexadecimalValue));
      if (t) {
        res = t;
        break;
      }
    }
    pageToken = obj.nextPageToken;
  } while (pageToken);
  if (!res) return;

  // Return resource name.
  const { resourceName } = res;
  return resourceName;
}

function deletePerson() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var resourceNameColumn = 1;  // Column A
  var resourceNameRow = 2;     // Start row 2
  var personValue = sheet.getRange(resourceNameRow, resourceNameColumn).getValue();

  // Convert from person/c### to people/c###
  var resourceName = convertPersonToPeople_(personValue);

  var contactPerson = searchContactPerson(resourceName);
  if (contactPerson) {
    deleteContactPerson(resourceName);
    Browser.msgBox('Succes', 'Person with unstructuredName "' + contactPerson + '" is deleted.', Browser.Buttons.OK);
  } else {
    Browser.msgBox('Not Okay', 'Person with the resourceName "' + resourceName + '" does not exists als contactperson.', Browser.Buttons.OK);
  }
}

function searchContactPerson(resourceName) {
  var res = People.People.getBatchGet({ personFields: "names", resourceNames: [resourceName] }).responses[0];
  return res.httpStatusCode == 200 ? res.person?.names[0]?.unstructuredName : false;
}

function deleteContactPerson(resourceName) {
  People.People.deleteContact(resourceName);
}

Please run the function deletePerson. When this script is run, person/c### is converted to people/c### and the contact is deleted using people/c###.