0
votes

I found the following code as a response to the same question at Check if contact exists under google contacts with "ContactsApp.getContact" but am having some trouble. I am trying to create a Google Script that checks to see if a respondent to a Google Survey already has a contact card in 'System Group: My Contacts' and if not, create a contact card and then add their phone number.

I've updated the following code to reference my fields, but am receiving an error for the line if(emailjson[email.toLowerCase()].id) - which is meant to check to see if that contact existed:

TypeError: Cannot read property "id" from undefined. (line 36, file "Code")

I thought that there was a problem with the IF statement, but I'm not completely familiar with Javascript (or JSON). As an Excel and Access person I'm accustomed to IF statements having a IF something is null, then do this, which so I tried adding === undefined, changing the code to if(emailjson[email.toLowerCase()].id === undefined) but that didn't solve the problem. In looking at the Execution Transcript, it hangs up as soon as it hits someone who doesn't have a contact card.

If I remove new contacts from the beginning of my spreadsheet and go back to the original code (without === undefined), then it creates duplicate contact cards for everyone who already had a card to start with until it reaches the next person who is new, and then it errors out again.

For the people who already have contact cards, I've also received an error on the next line if the phone number in the spreadsheet is just numbers, if(!emailjson[email.toLowerCase()]['phones'][phone.replace(/[_)(\s.-]/g,'')]) {.

TypeError: Cannot find function replace in object 2024313437. (line 37, file "Code")

If I add formatting to the phone number, then it doesn't throw an error (although as I mentioned before, it creates a duplicate contact). Oddly, I I run the function emailsasJSON afterwards, it only shows one contact card as opposed to a duplicate card, even though on the Google Contacts screen I see a contact card for every time I've attempted to run the script.

Thanks in advance for your thoughts.

function emailsasJSON() {
  
 var emailjson = {}
  var myContacts = ContactsApp.getContactGroup('System Group: My Contacts').getContacts();
  for (var i = 0; i < myContacts.length; i++) {
    var emails = myContacts[i].getEmails();
    var phonesobj = myContacts[i].getPhones();
    var phones = {}
    for (var j = 0; j < phonesobj.length; j++) {
       phones[phonesobj[j].getPhoneNumber().replace(/[_)(\s.-]/g,'')] = 1;
    }
    for (var j = 0; j < emails.length; j++) {
      emailjson[emails[j].getAddress().toLowerCase()] = {id: myContacts[i].getId(), phones:  phones};
      
    }
  }
  Logger.log(JSON.stringify(emailjson))
  return emailjson;
}

function addClient() {
 var ss = SpreadsheetApp.getActiveSpreadsheet();
 var sheetNew = ss.getActiveSheet(); 

 var clientsgroup = ContactsApp.getContactGroup('System Group: My Contacts')

//this is where we will insert the function from above to get the emailjson obj
 var emailjson = emailsasJSON()

 var contactarray = sheetNew.getDataRange().getValues();
 for (var i = 1 ; i < contactarray.length; i++){
   var name = contactarray[i][1]
   var email = contactarray[i][4]
   var phone = contactarray[i][3]
   
   if(emailjson[email.toLowerCase()].id) { //check if email exists
     if(!emailjson[email.toLowerCase()]['phones'][phone.replace(/[_)(\s.-]/g,'')]) { //if email exists but phone doesn't, add phone
         
     ContactsApp.getContactById(emailjson[email.toLowerCase()].id).addPhone(ContactsApp.Field.MOBILE_PHONE, phone)
     emailjson[email.toLowerCase()]['phones'][phone.replace(/[_)(\s.-]/g,'')] = 1; //add it to the emailjson object in case there are more iterations of this contact in the sheet
     } 
   } else { //add new contact if it doesn't exist
   
    var newcontact = ContactsApp.createContact(name.split(' ')[0],name.split(' ')[1], email)
    newcontact.addPhone(ContactsApp.Field.MOBILE_PHONE, phone)
    emailjson[email.toLowerCase()]['id'] = newcontact.getId();
    emailjson[email.toLowerCase()]['phones'][phone.toString().replace(/[_)(\s.-]/g,'')] = 1;
    clientsgroup.addContact(newcontact)
     }
  }
}

Sample Data:Contact Card

Spreadsheet

1
Can you add examples for the values in your google sheet and contacts group?Harshana Serasinghe
What do you get if you log both emailjson and the email array Logger.log(emailjson, emailjosn[email.toLowercase()].id)?Mateo Randwolf
@MateoRandwolf - Logger.log(emailjson,emailjson[emails.toLowerCase()].id) returns > TypeError: Cannot find function toLowerCase in object EmailField. If I remove .toLowerCase() then I get a > TypeError: Cannot read property "id" from undefined. (line 18, file "Code")Eric
@HarshanaSerasinghe - added sample data as requested.Eric

1 Answers

0
votes

Your main issue is that your function emailsasJSON() stringified the json object (i.e it was a string) and therefore you could not access successfully the key pair values of the JSON object. To solve this I just parsed the object to make sure it was consistent but as long as you wouldn't have converted it into a string it would have been ok.

The next change is in the first if condition. You don't actually need to check for the id to see if the element exists as just by checking the element itself would do the job (although checking the id would work too).

Finally the way you constructed your json object for the new contact was not done correctly so I have corrected it accordingly to add the appropriate key value pairs.

function emailsasJSON() {
  
 var emailjson = {}
  var myContacts = ContactsApp.getContactGroup('System Group: My Contacts').getContacts();
  for (var i = 0; i < myContacts.length; i++) {
    var emails = myContacts[i].getEmails();
    var phonesobj = myContacts[i].getPhones();
    var phones = {}
    for (var j = 0; j < phonesobj.length; j++) {
       phones[phonesobj[j].getPhoneNumber().replace(/[_)(\s.-]/g,'')] = 1;
    }
    for (var j = 0; j < emails.length; j++) {
      emailjson[emails[j].getAddress().toLowerCase()] = {id: myContacts[i].getId(), phones:  phones};
      
    }
  }
  emailjson = JSON.stringify(emailjson);
  emailjson = JSON.parse(emailjson);
  return emailjson;
}

function addClient() {
 var ss = SpreadsheetApp.getActiveSpreadsheet();
 var sheetNew = ss.getActiveSheet(); 

 var clientsgroup = ContactsApp.getContactGroup('System Group: My Contacts')

//this is where we will insert the function from above to get the emailjson obj
 var emailjson = emailsasJSON()

 var contactarray = sheetNew.getDataRange().getValues();
 for (var i = 1 ; i < contactarray.length; i++){
   var name = contactarray[i][1]
   var email = contactarray[i][4]
   var phone = contactarray[i][3]
   
   
   
   if(emailjson[email.toLowerCase()]) { //check if email exists
     if(!emailjson[email.toLowerCase()]['phones'][phone.toString().replace(/[_)(\s.-]/g,'')]) { //if email exists but phone doesn't, add phone
     ContactsApp.getContactById(emailjson[email.toLowerCase()].id).addPhone(ContactsApp.Field.MOBILE_PHONE, phone)
     emailjson[email.toLowerCase()]['phones'][phone.toString().replace(/[_)(\s.-]/g,'')] = 1; //add it to the emailjson object in case there are more iterations of this contact in the sheet
     }
   } else { //add new contact if it doesn't exist
    var newcontact = ContactsApp.createContact(name.split(' ')[0],name.split(' ')[1], email);
     var newContactId = newcontact.getId();
     var phoneNumber = phone.toString().replace(/[_)(\s.-]/g,'');
     ContactsApp.getContactById(newContactId).addPhone(ContactsApp.Field.MOBILE_PHONE, phone);
     emailjson[email.toLowerCase()] = {id:newContactId,phones:{phoneNumber : 1}}
     clientsgroup.addContact(newcontact)
     }
  }
}

Reference