I'm using Google App Script to try to update google contacts with data from google sheet, but I received Error 404. I wonder what have I missed?
Here below my code.
I first gather data from sheet to arrays, then feed values of arrays into "resource", then I update contact by contact (because I don't know how to use the batchupdate).
function updateContactsFromSheet() {
var sheetId = '[SheetID]';
var sheetName = '[SheetName]';
var sheet = SpreadsheetApp.openById(sheetId).getSheetByName(sheetName);
var dataRange = sheet.getDataRange();
var data = dataRange.getValues();
var headerRow = data[0];
var emailColumnIndex = headerRow.indexOf('Email');
var firstNameColumnIndex = headerRow.indexOf('First Name');
var middleNameColumnIndex = headerRow.indexOf('Middle Name');
var lastNameColumnIndex = headerRow.indexOf('Last Name');
var phoneColumnIndex = headerRow.indexOf('Mobile');
var resourceNameColumnIndex = headerRow.indexOf('resourceName');
var etagColumnIndex = headerRow.indexOf('etag');
for (var i = 1; i < data.length; i++) {
var resource = {
names: [],
emailAddresses: [],
phoneNumbers: [],
etag: []
};
var row = data[i];
var email = row[emailColumnIndex];
var firstName = row[firstNameColumnIndex];
var middleName = row[middleNameColumnIndex];
var lastName = row[lastNameColumnIndex];
var phone = row[phoneColumnIndex];
var resourceName = row[resourceNameColumnIndex];
var etag = row[etagColumnIndex];
if(resourceName != ''){
resource.names.push({
givenName: firstName,
middleName: middleName,
familyName: lastName
});
resource.emailAddresses.push({ value: email });
resource.phoneNumbers.push({ value: phone });
resource.etag.push(etag);
People.People.updateContact(resource, resource.resourceName);
}
}
}
Here's the error:
HttpResponseException: Response Code: 404. Message: <!DOCTYPE html>
<html lang=en>
<meta charset=utf-8>
<meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
<title>Error 404 (Not Found)!!1</title>
<style>
In this answer, if the values of resourceName
and etag
are invalid values, the script cannot be used. And, if you have no permission to update the contacts, this script cannot be used. Please be careful about this.
resource.resourceName
is undefined. I thought that this might be the reason for your current issue.updatePersonFields
.etag
is required to be a string instead of an array.When your showing script is modified with these modification points, it becomes as follows.
In this modification, your script is modified.
function updateContactsFromSheet() {
var sheetId = '[SheetID]';
var sheetName = '[SheetName]';
var sheet = SpreadsheetApp.openById(sheetId).getSheetByName(sheetName);
var dataRange = sheet.getDataRange();
var data = dataRange.getDisplayValues();
var headerRow = data[0];
var emailColumnIndex = headerRow.indexOf('Email');
var firstNameColumnIndex = headerRow.indexOf('First Name');
var middleNameColumnIndex = headerRow.indexOf('Middle Name');
var lastNameColumnIndex = headerRow.indexOf('Last Name');
var phoneColumnIndex = headerRow.indexOf('Mobile');
var resourceNameColumnIndex = headerRow.indexOf('resourceName');
var etagColumnIndex = headerRow.indexOf('etag');
for (var i = 1; i < data.length; i++) {
var resource = { names: [], emailAddresses: [], phoneNumbers: [] };
var row = data[i];
var email = row[emailColumnIndex];
var firstName = row[firstNameColumnIndex];
var middleName = row[middleNameColumnIndex];
var lastName = row[lastNameColumnIndex];
var phone = row[phoneColumnIndex];
var resourceName = row[resourceNameColumnIndex];
var etag = row[etagColumnIndex];
if (resourceName != '') {
resource.names.push({ givenName: firstName, middleName: middleName, familyName: lastName });
resource.emailAddresses.push({ value: email });
resource.phoneNumbers.push({ value: phone });
resource.etag = etag;
People.People.updateContact(resource, resourceName, { updatePersonFields: "names,emailAddresses,phoneNumbers" });
}
}
}
From because I don't know how to use the batchupdate
. if you wanted to use Method: people.batchUpdateContacts, it becomes as follows.
function updateContactsFromSheet() {
var sheetId = '[SheetID]';
var sheetName = '[SheetName]';
var sheet = SpreadsheetApp.openById(sheetId).getSheetByName(sheetName);
var dataRange = sheet.getDataRange();
var [headerRow, ...data] = dataRange.getDisplayValues();
var emailColumnIndex = headerRow.indexOf('Email');
var firstNameColumnIndex = headerRow.indexOf('First Name');
var middleNameColumnIndex = headerRow.indexOf('Middle Name');
var lastNameColumnIndex = headerRow.indexOf('Last Name');
var phoneColumnIndex = headerRow.indexOf('Mobile');
var resourceNameColumnIndex = headerRow.indexOf('resourceName');
var etagColumnIndex = headerRow.indexOf('etag');
var contacts = data.reduce((ar, row) => {
var resource = { names: [], emailAddresses: [], phoneNumbers: [] };
var email = row[emailColumnIndex];
var firstName = row[firstNameColumnIndex];
var middleName = row[middleNameColumnIndex];
var lastName = row[lastNameColumnIndex];
var phone = row[phoneColumnIndex];
var resourceName = row[resourceNameColumnIndex];
var etag = row[etagColumnIndex];
if (resourceName != '') {
resource.names.push({ givenName: firstName, middleName: middleName, familyName: lastName });
resource.emailAddresses.push({ value: email });
resource.phoneNumbers.push({ value: phone });
resource.etag = etag;
ar.push([resourceName, resource]);
}
return ar;
}, []);
if (contacts.length == 0) return;
const reqs = [...Array(Math.ceil(contacts.length / 200))].map(_ => contacts.splice(0, 200).reduce((o, [a, b]) => (o[a] = b, o), {}));
reqs.forEach(r => People.People.batchUpdateContacts({ contacts: r, updateMask: "names,emailAddresses,phoneNumbers" }));
}
People.People.batchUpdateContacts
, the maximum chunk size is 200 contacts for every request.resourceName
and etag
are valid values and you have permission to update the contacts, the script works fine.