Reputation: 6175
I'm making the transition from Contacts API to People API as required by Google. I'm very surprised by the lack of examples online but I can now create, delete and modify/update (thanks to the reply by @Tanaike's reply to Omar F. here: Cannot update contactusgin People api using Google Apps Script) a contact, with delete and modify via iterating through People.People.Connections.List(), with its max of 100 results (from the Apps Script sample here: https://developers.google.com/people/quickstart/apps-script).
But I have about 12,000 contacts and need to use (I assume) People.People.searchContacts()
. I haven't found any Apps Script examples and the documentation is all in Java, which I don't know how to translate to Apps Script:
...
// Send search request
SearchResponse response = peopleService.people().searchContacts()
.setQuery("query")
.setReadMask("names,emailAddresses")
.execute();
or "Protocol" which is similarly not useful (for me - I've tried!):
...
// Send search request after several seconds
GET /v1/people:searchContacts?query=query&readMask=names,emailAddresses HTTP/1.1
Host: people.googleapis.com
My best guess to date using Google Drive Query Parameter style since the People API link from this page (https://developers.google.com/people/v1/query-parameters) doesn't seem to help:
let searchResp = People.People.searchContacts(
"phoneNumbers contains 5632",
{ readMask: "names,phoneNumbers,addresses,emailAddresses" }
);
let personBob = searchResp.results.find(p =>
p.names[0].displayName.includes("Bob Q22222")
);
So after spending an embarrassing amount of time getting to this point, I'm throwing in the towel and hoping someone can give an example of getting a searchResponse via People.People.searchContacts()
to show what
I understand that the searchResponse.results
is just an array of People and should be fine from there.
Thank you and I hope this wasn't too waffly (baffled non-programmer for our little husband & wife business). ~
Modified from Rafi's reply, this works from a form-attached Appscript file, which is what I want but it's not retrieving all results, see further below):
function run() {
let query = "Q12755";
let found = People.People.searchContacts({
"query": query,
"readMask": "names,addresses,emailAddresses,phoneNumbers"
});
if (found.results) {
for (i = 0; i < found.results.length; i++) {
let thisResult = found.results[i];
Logger.log(`Result ${i}: ${thisResult.person.names[0].displayName}`);
}
} else {
Logger.log(`No results for ${query}`);
}
}
...but, it's not picking up all of the results.
The test function and result for "Q12755" query:
Two results for that string in Google Contacts:
And the same two results on my phone:
Any idea why not all results are being retrieved? I've tested several queries and it consistently misses results. All (I believe) of the Contacts tested have been created via an Appscript script via the deprecating Contacts API.
P.S. I might add that it's not an issue with it only retrieving one result. In other cases where there "should" be like 20 results, in has retrieved half a dozen or so.
P.P.S. A "warmup" of the cache is recommended/required, and I'm assuming the updated script below does that okay. There's no difference to the results:
function run() {
let blankQueryForWarmUp = "";
let found = People.People.searchContacts({
"query": blankQueryForWarmUp,
"readMask": "names,addresses,emailAddresses,phoneNumbers"
});
Utilities.sleep(5000);
let query = "Q12755";
found = People.People.searchContacts({
"query": query,
"readMask": "names,addresses,emailAddresses,phoneNumbers"
});
if (found.results) {
for (i = 0; i < found.results.length; i++) {
let thisResult = found.results[i];
Logger.log(`Result ${i}: ${thisResult.person.names[0].displayName}`);
}
} else {
Logger.log(`No results for ${query}`);
}
}
Upvotes: 1
Views: 1765
Reputation: 113
I ran into a similar issue, and it turned out the the problem was that they contacts I was expecting to show up in the results are actually in the "Other contacts" group that Google creates for "people you've interacted with in Google products, as well as any contacts you've hidden from your list."
It doesn't look from you screenshots as though this is the problem you're having, although it's possible that Google's UI has changed since this was originally posted in a way that makes the issue more visible.
The Other Contacts group can be searched exactly the same way as the primary contacts group. Here is the code I ended up with, a function that looks up a person's name based on an email address (and returns the email address if nothing is found):
function getNameFromEmail_(email) {
var name = email;
var response;
People.People.searchContacts({ //Warm up the cache
query: '',
readMask: 'names,emailAddresses',
});
response = People.People.searchContacts({
query: email,
readMask: 'names,emailAddresses'
});
// Check if the response contains contacts
if (response.results && response.results.length > 0) {
name = response.results[0].person.names[0].displayName;
} else {
People.OtherContacts.search({ //Warm up the cache
query: '',
readMask: 'names,emailAddresses',
});
response = People.OtherContacts.search({
query: email,
readMask: 'names,emailAddresses'
});
// Check if the response contains contacts
if (response.results && response.results.length > 0) {
name = response.results[0].person.names[0].displayName;
}
}
return name;
}
Upvotes: 0
Reputation: 1657
The reason you are not seeing all the results is that the search is being done on some google cache, and so, for refreshing it, according to the documentation at: https://developers.google.com/people/api/rest/v1/people/searchContacts
You must first send a "warmup" request, wait for a couple of seconds, and after that, send your request, yes, it is strange I know, but that is what the documentation says...
IMPORTANT: Before searching, clients should send a warmup request with an empty query to update the cache. See https://developers.google.com/people/v1/contacts#search_the_users_contacts
You can also see here how exactly it is being done (see the Java tab): https://developers.google.com/people/v1/contacts#search_the_users_contacts
CORRECTION: If you are searching by phone number, just know there is a bug on Google API See this thread - searchContacts with phone number query is broken Google say the bug was fixed and verified, but it wasn't at least while I'm writing this correction.
WORKAROUND: I just put the phone number also as one of the nickname field and so the search is working since this is one of the fields being searched at
Upvotes: 1
Reputation: 38160
Add pageSize property to the searchContacts parameter. The following example uses another resource but shows the use of pageSize (it's the same for many Google API's
function run() {
var response;
var options = {
pageSize:10,
personFields: 'names'
};
var callback = People.People.Connections.list
do{
response = callback('people/me',options)
response.connections.forEach(connection => console.log(connection.names ? connection.names[0].displayName : ''));
options.pageToken = response.nextPageToken
} while(options.pageToken)
}
Related
Upvotes: 2
Reputation: 15357
People API search queries only support partial string matches in contact names. The readMask
values must be concatenated as a comma-separated string.
People API Search Queries do not support the Drive syntax such as 'contains' keywords. From the documentation (emphasis my own):
query
The plain-text query for the request. The query is used to match prefix phrases of the fields on a person. For example, a person with name "foo name" matches queries such as "f", "fo", "foo", "foo n", "nam", etc., but not "oo n".
The readMask
can take any of the following values (taken from here), separated by commas:
A full JavaScript request example would look like:
function run() {
return gapi.client.people.people.searchContacts({
"query": "Rafa Guillermo",
"readMask": "names,emailAddresses,phoneNumbers"
}).then(function(response) {
console.log("Response", response)
}, function(err) {
console.error(err);
})
}
Upvotes: 1