I'm using the Google Contacts API and I'm able to extract names and email addresses but I'd like to also get profile pictures and phone numbers.
I'm using PHP and here's my code while authenticating:
//if authenticated successfully...
$req = new Google_HttpRequest("https://www.google.com/m8/feeds/contacts/default/full");
$val = $client->getIo()->authenticatedRequest($req);
$doc = new DOMDocument;
$doc->recover = true;
$doc->loadXML($val->getResponseBody());
$xpath = new DOMXPath($doc);
$xpath->registerNamespace('gd', 'http://schemas.google.com/g/2005');
$emails = $xpath->query('//gd:email');
foreach ( $emails as $email ){
echo $email->getAttribute('address'); //successfully gets person's email address
echo $email->parentNode->getElementsByTagName('title')->item(0)->textContent; //successfully gets person's name
}
PHONE NUMBER
This part getting the phone number doesn't work.
$phone = $xpath->query('//gd:phoneNumber');
foreach ( $phone as $row ){
print_r($row); // THIS PART DOESNT WORK
}
PROFILE PICTURE
Judging from the API link above, it looks like I can also grab the profile picture from the URL: https://www.google.com/m8/feeds/contacts/default/full
but I'm not sure how to find it within the DOMXPath
$xpath
object I generated.
Thoughts?
The Google Contacts API uses an Atom feed. The contacts are provided as entry
elements. So it makes more sense the iterate them. To do that you have to register a prefix for the atom namespace as well.
$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
$xpath->registerNamespace('atom', 'http://www.w3.org/2005/Atom');
$xpath->registerNamespace('gd', 'http://schemas.google.com/g/2005');
If you use DOMXpath::evaluate() you can use expressions that return scalars. The second argument is a context node for the expression.
foreach ($xpath->evaluate('/atom:feed/atom:entry') as $entry) {
$contact = [
'name' => $xpath->evaluate('string(atom:title)', $entry),
'image' => $xpath->evaluate('string(atom:link[@rel="http://schemas.google.com/contacts/2008/rel#photo"]/@href)', $entry),
'emails' => [],
'numbers' => []
];
foreach ($xpath->evaluate('gd:email', $entry) as $email) {
$contact['emails'][] = $email->getAttribute('address');
}
foreach ($xpath->evaluate('gd:phoneNumber', $entry) as $number) {
$contact['numbers'][] = trim($number->textContent);
}
var_dump($contact);
}
With the first example response from the Google Contacts API documentation this returns:
array(3) {
["name"]=>
string(17) "Fitzwilliam Darcy"
["image"]=>
string(64) "https://www.google.com/m8/feeds/photos/media/userEmail/contactId"
["email"]=>
string(0) ""
["numbers"]=>
array(1) {
[0]=>
string(3) "456"
}
}
The example does not include an email
element, so it is empty. A contact can have multiple email addresses and/or phone numbers or none at all. The rel
attribute is provided to classify them as home, work, ...
The image is provided as an Atom link
element with a specific rel
attribute.
atom:link[@rel="http://schemas.google.com/contacts/2008/rel#photo"]
This would return the link
node, but it is possible to fetch the href attribute directly:
atom:link[@rel="http://schemas.google.com/contacts/2008/rel#photo"]/@href
Cast the attribute node list into a string:
string(atom:link[@rel="http://schemas.google.com/contacts/2008/rel#photo"]/@href)