3

I have been using this API for 6 years with no problems, but since 3 days ago I experienced a series of strange behaviours, realizing my google contacts started duplicating without control. I figured it out it is related to a strange limit to 1.500 in retrieving contacts, even if I use max-results in GET query.

This is my code (PHP server):

$req = new Google_Http_Request("https://www.google.com/m8/feeds/contacts/".$user_email."/full?max-results=1000000");
$req->setRequestHeaders(array('GData-Version'=> '3.0','content-type'=>'application/atom+xml; charset=UTF-8; type=feed'));
$auth = $client->getAuth();
$val = $auth->authenticatedRequest($req);
$response = $val->getResponseBody();
$xml = simplexml_load_string($response);

The result is $xml->entry with only 1.500 elements even if contacts are 8.000.

Anyone knows what's happening?

1 Answers1

2

I reached out to the author of the contact sync script I'm using, seems there's another method that works - here's a link to current revision, and the recent commit that by Mr. Adler that seems to fix the issue. bear in mind, this is python, but I imagine a similar check could be done using PHP? https://github.com/michael-adler/sync-google-contacts https://github.com/michael-adler/sync-google-contacts/commit/4c5a8517e9da84d59769d8b513f5b637782aea14

MAX_RESULTS is a variable set earlier, 10000, but might as well be 1500 or less, since that's the max we're getting.

    query = gdc.ContactsQuery(max_results=MAX_RESULTS)
    feed = self.gd_client.GetContacts(q=query)
    while feed:

then, check for more contacts:

        next_link = feed.GetNextLink()
        if next_link:
            feed = self.gd_client.GetContacts(uri=next_link.href)
        else:
            feed = None

if you review the returned xml/json in oauth2 playground, you will see that the response contains some useful data you need to leverage to make this work now.

For example, if you send an (authorized) request https://www.google.com/m8/feeds/contacts/default/full?max_results=10

the response contains

<openSearch:totalResults>1234</openSearch:totalResults>

this contains the count of your contacts.

there are also a bunch of url links returned.

the one we need, which, if present, indicates there are more contacts available, is identified by

rel='next'

example:

 <link href='https://www.google.com/m8/feeds/contacts/username%40gmail.com/full?max-results=10' rel='self' type='application/atom+xml'/>
 <link href='https://www.google.com/m8/feeds/contacts/username%40gmail.com/full?start-index=11&amp;max-results=10' rel='next' type='application/atom+xml'/>

start-index is the contact number of the total, so if you set max_results to 1000, and you have 3500 contacts, you will need send your initial request, and then extract from the response, the "next" url for each of the subsequent (3 in this case) requests required, appending the subsequent data,to get all of the contacts added to your array.

your initial query might be

https://www.google.com/m8/feeds/contacts/username%40gmail.com/full?&max_results=1000

your subsequent requests would end with

https://www.google.com/m8/feeds/contacts/username%40gmail.com/full?start-index=1001&max_results=1000
https://www.google.com/m8/feeds/contacts/username%40gmail.com/full?start-index=2001&max_results=1000
https://www.google.com/m8/feeds/contacts/username%40gmail.com/full?start-index=3001&max_results=1000 (would not return XML containing a link with rel='next' as this is the last page)