0

I'm on a google apps domain for education and I'm trying to use the Domain Shared Contacts API to access the shared contacts. I'm using the google php api client with a service account for which I have enabled the correct APIs and added the appropriate scopes similar to steps 1-5 of this answer: Is it possible to use "Domain-wide Delegation of Authority" with gdata-python-client?

Shared contacts are enabled; I can seem them using Gmail. Also, I am delegating to a super admin user. When I run my script, I get a 200 response, but no contacts or xml in the response body.

Here is my script:

<?php
require_once 'google-api-php-client/src/Google_Client.php';

const CLIENT_ID = 'xxxxxx.apps.googleusercontent.com';
const SERVICE_ACCOUNT_NAME = 'xxxxxx@developer.gserviceaccount.com';
const KEY_FILE = '/path/to/yyyyy-privatekey.p12';

$client = new Google_Client();
$client->setApplicationName('Directory');
$client->setUseObjects(true);
$client->setClientId(CLIENT_ID);

session_start();

if (isset($_SESSION['token'])) {
    $client->setAccessToken($_SESSION['token']);
}

// Load the key in PKCS 12 format
$key = file_get_contents(KEY_FILE);

$auth = new Google_AssertionCredentials(SERVICE_ACCOUNT_NAME, array('https://www.google.com/m8/feeds'), $key);
$auth->sub = 'superadmin@domain.com'; 

$client->setAssertionCredentials($auth);

$client->getAuth()->refreshTokenWithAssertion(); //normally would check if expired, but for dev refresh every time


$req = new Google_HttpRequest("https://www.google.com/m8/feeds/contacts/domain.com/full"); //shared contacts
$req->setRequestHeaders(array('GData-Version'=> '3.0','content-type'=>'application/atom+xml; charset=UTF-8; type=feed'));


$responseObj = $client->getIo()->authenticatedRequest($req);
var_dump($responseObj);

$responseXml =$responseObj->getResponseBody();

if ($client->getAccessToken()) {
    $_SESSION['token'] = $client->getAccessToken();
}

Here is the response:

object(Google_HttpRequest)#6 (10) {
    ["batchHeaders":"Google_HttpRequest":private]=>
        array(4) {
            ["Content-Type"]=> string(16) "application/http"
            ["Content-Transfer-Encoding"]=> string(6) "binary"
            ["MIME-Version"]=> string(3) "1.0"
            ["Content-Length"]=> string(0) ""
        }
    ["url":protected]=> string(55) "https://www.google.com/m8/feeds/contacts/domain.com/full"
    ["requestMethod":protected]=> string(3) "GET"
    ["requestHeaders":protected]=>
        array(3) {
            ["gdata-version"]=> string(3) "3.0"
            ["content-type"]=> string(46) "application/atom+xml; charset=UTF-8; type=feed"
            ["authorization"]=> string(138) "Bearer #a#a.#a#a#a#a-#-..."
        }
    ["postBody":protected]=>NULL
    ["userAgent":protected]=> string(37) "Directory google-api-php-client/0.6.5"
    ["responseHttpCode":protected]=> int(200)
    ["responseHeaders":protected]=>
        array(14) {
            ["content-type"]=> string(46) "application/atom+xml; charset=UTF-8; type=feed"
            ["expires"]=> string(29) "Tue, 22 Jul 2014 14:51:21 GMT"
            ["date"]=> string(29) "Tue, 22 Jul 2014 14:51:21 GMT"
            ["cache-control"]=> string(49) "private, max-age=0, must-revalidate, no-transform"
            ["vary"]=> string(44) "Accept, X-GData-Authorization, GData-Version"
            ["gdata-version"]=> string(3) "3.1"
            ["etag"]=> string(28) "W/"#a#a#a#a#a#a""
            ["last-modified"]=> string(29) "Tue, 22 Jul 2014 14:51:21 GMT"
            ["transfer-encoding"]=> string(7) "chunked"
            ["x-content-type-options"]=> string(7) "nosniff"
            ["x-frame-options"]=> string(10) "SAMEORIGIN"
            ["x-xss-protection"]=> string(13) "1; mode=block"
            ["server"]=> string(3) "GSE"
            ["alternate-protocol"]=> string(8) "443:quic"
        }
    ["responseBody":protected]=> string(1477) 
        "<?xml version='1.0' encoding='UTF-8'?>
            <feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/' xmlns:gContact='http://schemas.google.com/contact/2008' xmlns:batch='http://schemas.google.com/gdata/batch' xmlns:gd='http://schemas.google.com/g/2005' gd:etag='W/&quot;#a#a#a#a#a#a.&quot;'>
                <id>domain.com</id><updated>2014-07-22T14:51:21.805Z</updated><category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/contact/2008#contact'/>
                <title>domain.com's Contacts</title>
                <link rel='alternate' type='text/html' href='http://www.google.com/'/>
                <link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='https://www.google.com/m8/feeds/contacts/domain.com/full'/>
                <link rel='http://schemas.google.com/g/2005#post' type='application/atom+xml' href='https://www.google.com/m8/feeds/contacts/domain.com/full'/>
                <link rel='http://schemas.google.com/g/2005#batch' type='application/atom+xml' href='https://www.google.com/m8/feeds/contacts/domain.com/full/batch'/>
                <link rel='self' type='application/atom+xml' href='https://www.google.com/m8/feeds/contacts/domain.com/full?max-results=25'/>
                <author><name>(unknown)</name><email>domain.com</email></author>
                <generator version='1.0' uri='http://www.google.com/m8/feeds'>Contacts</generator>
                <openSearch:totalResults>0</openSearch:totalResults>    
                <openSearch:startIndex>1</openSearch:startIndex>
                <openSearch:itemsPerPage>25</openSearch:itemsPerPage>
            </feed>"
    ["accessKey"]=> NULL
}

As you can see the totalResults lists 0. I believe I am authenticating correctly as I have a 200 response, and if I change $auth->sub and the url in the Google_HttpRequest to a particular user, I can access their contacts. I'm not sure what I am missing.

Community
  • 1
  • 1
Marty
  • 582
  • 4
  • 17

1 Answers1

0

I am delegating to a super admin user

...but have you added any domain shared contacts? Note that this is different than contacts that are delegated (shared) from your account to other specific users (such as the super admin user you mention above).

My understanding is domain shared contacts are added by using the insert command on the /m8/feeds/contacts/domain.com/full URL, not via the GMail UI.

Blake O'Hare
  • 1,863
  • 12
  • 16
  • Hi Blake. I agree that domain shared contacts are not added via the GMail UI, but you can see them in GMail. I have not added domain shared contacts via the api, but they are enabled in the admin console (admin.google.com) under _Google Apps > Settings for Contacts > Advanced Settings_. I have enabled _Enable contact sharing_ and chosen _Show all email addresses_ and _Show only domain profiles_. I have not tried changing what is shown in the Contact Manager. – Marty Jul 23 '14 at 15:08
  • Blake, you are correct; I do not have any external domain shared contacts. Shared contacts that are internal to the domain have to be accessed via the Directory API. Shared contacts that are external to the domain have to accessed via the Domain Shared Contacts API. In my case all of my contacts are internal. Once I changed scopes and request URL to be directory specific, I was able to access the contacts. On https://developers.google.com/admin-sdk/domain-shared-contacts/ it specifies external contacts in bold, but I didn't understand that it meant external to the domain and not the user. – Marty Jul 23 '14 at 16:23