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

Google People API with AppScript: Add People of Directory to a group


I have a mail adress of someone in my company/domain and want to assign them a google contact label.

This is my current code:

function main() {
  var labelName = "Test"
  var group = getContactGroup(labelName)
  var emailAddress = "[email protected]"
  var person = getPersonByEmailAdress(emailAddress)

  addPersonToGroup(person, group)
}

function getContactGroup(labelName) {
  const people = People.ContactGroups.list();
  const group = people['contactGroups'].find((group) => group['name'] === labelName);
  return group
}

function getPersonByEmailAdress(emailAddress) {
  let request = People.People.searchDirectoryPeople({
    "query": emailAddress,
    "readMask": "emailAddresses",
    sources: ['DIRECTORY_SOURCE_TYPE_DOMAIN_PROFILE']
  });
  return request.people[0]
}

function addPersonToGroup(person, group) {
  var personResourceName = person["resourceName"];
  var groupResourceName = group["resourceName"];

  var membersResource = {
    "resourceNamesToAdd": [
      personResourceName
    ]
  }
  People.ContactGroups.Members.modify(membersResource, groupResourceName); //Error here
}

For the last statement I get the following error message:

GoogleJsonResponseException: API call to people.contactGroups.members.modify failed with error: Resource name "people/xxxxxxxxxxxxxxxxx" is not a valid contact person resource.

Where is the mistake? Do I somehow need to add the person to contacts before? And also the code look a bot too complex for such an easy problem. Is there some way of optimizing it?

Bigger picture: I have a list of mail adresses of directory contacts and want to add them to a group/assign the respective label. Only people from the list should be in the group. people who are not in the list should be removed from the group.

Thanks for your help!


Solution

  • ----UPDATE----

    As pointed out by luisa the issue might be related to the contact not actually existing, to fix this a contact can be added by the getPersonByEmailAdress() function like so:

    function getPersonByEmailAdress() {
      let request = People.People.searchDirectoryPeople({
        "query": emailAddress,
        "readMask": "emailAddresses,names",
        sources: ['DIRECTORY_SOURCE_TYPE_DOMAIN_PROFILE']
      });
      delete request.people[0]["metadata"]
      delete request.people[0]["resourceName"]
      delete request.people[0]["source"]
      delete request.people[0]["etag"]
      delete request.people[0].emailAddresses[0]["metadata"]
      delete request.people[0].names[0]["metadata"]
    
     People.People.createContact(request.people[0])
    
     return request.people[0]
    
    }
    

    The delete operator is in there because the information stored in request contains data that conflicts with the creation of a new contact such as a resourceName which is sort of a unique ID that should never be sent as a parameter for a createContact request.

    ----ORIGINAL ANSWER---- I was able to make this work by modifying the lines in

     var personResourceName = person["resourceName"];
     var groupResourceName = group["resourceName"];
    

    with

      var groupResourceName = ["resourceName"]
      var membersResource = {
        "resourceNamesToAdd": ["resourceName"]
    

    it seems like the membersResource variable requires an extra bit of data to be recognized as a resource name.

    To reach that conclussion I used the try this method option in the documentation and selected the option to expand the view:

    Try this method

    There you can select "Javascript" as such:

    enter image description here

    Once there you can fill the information to the left where the "resourceName" (group resource) and the "resourceNamesToAdd" (person resource) can be filled in, doing so will add some lines to the code. From there the function we are looking for is:

    
    function execute() {
        return gapi.client.people.contactGroups.members.modify({
          "resourceName": "resourceName",
          "resource": {
            "resourceNamesToAdd": [
              "resourceName"
            ]
          }
        })
            .then(function(response) {
                    // Handle the results here (response.result has the parsed body).
                    console.log("Response", response);
                  },
                  function(err) { console.error("Execute error", err); });
      }
    

    Where you can notice how "resourceNamesToAdd" actually has more information when referring to the person resource name.

    Hope this helps!