I have a script to get all contacts from Google Contacts to a spreadsheet in Google Sheets. Because the amount of contacts is too many to get in 6 minutes execution time limit, I use script trigger to continue the import after some time.
...
var contacts = ContactsApp.getContacts();
var last_index = parseInt(userProperties.getProperty('last_index'));
if(isNaN(last_index)) last_index = 0;
for(var i = last_index; i < contacts.length; ++i){
// register trigger if time is up
// ....
var name = contacts[i].getFullName();
sheet.appendRow([name]);
}
...
What works:
What doesn't work:
For example:
for(var i = last_row;i<contacts.length;++i){ // I've checked last_row is indeed not 0
var name = contacts[i].getFullName();
// append row
}
will yield the same result as:
for(var i = 0;i<contacts.length;++i){
var name = contacts[i].getFullName();
// append row
}
No matter what index I asked to start from, it will always start from the first index of contacts array unless it's executed from trigger chaining. Could anyone please tell me what's going on here? How do I fix this?
In your script, appendRow
is used in a loop. In this case, the process cost becomes high. Ref I guessed that this might be the reason for your process time. If my understanding of your issue was correct, how about the following modification?
var contacts = ContactsApp.getContacts();
var last_index = parseInt(userProperties.getProperty('last_index'));
if(isNaN(last_index)) last_index = 0;
for(var i = last_index; i < contacts.length; ++i){
// register trigger if time is up
// ....
var name = contacts[i].getFullName();
sheet.appendRow([name]);
}
var contacts = ContactsApp.getContacts();
var values = contacts.map(e => [e.getFullName()]);
sheet.getRange(sheet.getLastRow() + 1, 1, values.length).setValues(values);
setValues
. By this, I thought that this process might be run by one execution.As another approach, how about using People API? When People API is used, the sample script is as follows. If you use this script, please enable People API at Advanced Google services.
function myFunction() {
var sheet = SpreadsheetApp.getActiveSheet();
var values = [];
var pageToken = "";
do {
var o1 = People.People.Connections.list("people/me", { personFields: "names", fields: "connections.names.displayName,nextPageToken", pageSize: 1000, pageToken });
if (o1.connections.length > 0) {
values.push(...o1.connections.map(e => e.names ? e.names.map(f => [f.displayName]) : [[""]]));
}
pageToken = o1.nextPageToken;
} while (pageToken);
do {
var o2 = People.OtherContacts.list({ readMask: "names", fields: "otherContacts.names.displayName,nextPageToken", pageSize: 1000, pageToken });
if (o2.otherContacts.length > 0) {
values.push(...o2.otherContacts.flatMap(e => e.names ? e.names.map(f => [f.displayName]) : [[""]]));
}
pageToken = o2.nextPageToken;
} while (pageToken);
sheet.getRange(sheet.getLastRow() + 1, 1, values.length).setValues(values);
}