import urllib
import oauth
import gdata.contacts
import gdata.contacts.service
CONSUMER_KEY = 'yourdomain.com'
CONSUMER_SECRET = 'YOUR_CONSUMER_SECRET'
CONTACTS_URL = 'http://www.google.com/m8/feeds/contacts/default/full'
# Setup 2 legged OAuth consumer based on our admin "credentials"
consumer = oauth.OAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET)
user = 'any.user@yourdomain.com'
params = {'max-results': 50, 'xoauth_requestor_id': user}
# Construct the request manually and sign it using HMAC-SHA1
# Note: The params dictionary needs to be passed in separately from the base URL
request = oauth.OAuthRequest.from_consumer_and_token(
consumer, http_method='GET', http_url=CONTACTS_URL, parameters=params)
request.sign_request(oauth.OAuthSignatureMethod_HMAC_SHA1(), consumer, None)
# See patch @ http://code.google.com/p/oauth/issues/detail?id=31
headers = request.to_header()
client = gdata.contacts.service.ContactsService()
# Query the user's contacts and print their name & email
uri = '%s?%s' % (request.http_url, urllib.urlencode(params))
feed = client.GetFeed(uri, extra_headers=headers, converter=gdata.contacts.ContactsFeedFromString)
for entry in feed.entry:
print '%s, %s' % (entry.title.text, entry.email[0].address)
2 Legged OAuth in Python
2 Legged OAuth in PHP
<?php
require_once('OAuth.php');
// Establish an OAuth consumer based on our admin 'credentials'
$CONSUMER_KEY = 'yourdomain.com';
$CONSUMER_SECRET = 'YOUR_CONSUMER_SECRET';
$consumer = new OAuthConsumer($CONSUMER_KEY, $CONSUMER_SECRET, NULL);
// Setup OAuth request based our previous credentials and query
$user= 'any.user@yourdomain.com';
$base_feed = 'http://www.google.com/m8/feeds/contacts/default/full/';
$params = array('max-results' => 10, 'xoauth_requestor_id' => $user);
$request = OAuthRequest::from_consumer_and_token($consumer, NULL, 'GET', $base_feed, $params);
// Sign the constructed OAuth request using HMAC-SHA1
$request->sign_request(new OAuthSignatureMethod_HMAC_SHA1(), $consumer, NULL);
// Make signed OAuth request to the Contacts API server
$url = $base_feed . '?' . implode_assoc('=', '&', $params);
echo send_request($request->get_normalized_http_method(), $url, $request->to_header());
/**
* Makes an HTTP request to the specified URL
* @param string $http_method The HTTP method (GET, POST, PUT, DELETE)
* @param string $url Full URL of the resource to access
* @param string $auth_header (optional) Authorization header
* @param string $postData (optional) POST/PUT request body
* @return string Response body from the server
*/
function send_request($http_method, $url, $auth_header=null, $postData=null) {
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_FAILONERROR, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
switch($http_method) {
case 'GET':
if ($auth_header) {
curl_setopt($curl, CURLOPT_HTTPHEADER, array($auth_header));
}
break;
case 'POST':
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/atom+xml',
$auth_header));
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
break;
case 'PUT':
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/atom+xml',
$auth_header));
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $http_method);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
break;
case 'DELETE':
curl_setopt($curl, CURLOPT_HTTPHEADER, array($auth_header));
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $http_method);
break;
}
$response = curl_exec($curl);
if (!$response) {
$response = curl_error($curl);
}
curl_close($curl);
return $response;
}
/**
* Joins key:value pairs by inner_glue and each pair together by outer_glue
* @param string $inner_glue The HTTP method (GET, POST, PUT, DELETE)
* @param string $outer_glue Full URL of the resource to access
* @param array $array Associative array of query parameters
* @return string Urlencoded string of query parameters
*/
function implode_assoc($inner_glue, $outer_glue, $array) {
$output = array();
foreach($array as $key => $item) {
$output[] = $key . $inner_glue . urlencode($item);
}
return implode($outer_glue, $output);
}
?>
Editing contact photos using curl
You can use curl to modify Contacts API contact photos from the command line.
To start, you'll need to get the photo edit link from the contacts feed. This is expressed in the feed as the following XML element:
<link rel="http://schemas.google.com/contacts/2008/rel#photo-edit type="image/*" href="http://www.google.com/m8/feeds/photos/media/user/id/version" />
The photo edit link is contained inside the href attribute. For this example, it would be http://www.google.com/m8/feeds/photos/media/user/id/version.
Once you have this, you can add or update a photo by running:
curl -H "Authorization: GoogleLogin ..." \ -H "Content-Type: image/jpeg" \ -X PUT \ --binary-data "@/path/to/image.jpg" \ http://www.google.com/m8/feeds/photos/media/user/id/version
Be sure to replace the Content-Type and file path with appropriate values for your new photo.
To delete a photo, run:
curl -H "Authorization: GoogleLogin ..." \ -X DELETE \ http://www.google.com/m8/feeds/photos/media/user/id/version
You'll need to make sure that the Authorization header contains a valid ClientLogin token, as explained in the tip "Perform ClientLogin using curl.
Deleting contact photos using .NET
If you want to delete a contact photo from the Contacts API using the .NET client library, you can just call ContactsService.Delete(photoURI), like so:
ContactsService service = new ContactsService("exampleCo-exampleApp-1");
service.setUserCredentials("user@example.com", "secretPassword");
ContactsQuery query = new ContactsQuery(ContactsQuery.CreateContactsUri("default"));
ContactsFeed feed = service.Query(query);
foreach (ContactEntry entry in feed.Entries)
{
service.Delete(entry.PhotoEditUri);
}
Be careful, the above code will delete every contact photo in your contact list. Run this against a test account only.
Edit contact phone numbers using Python
import gdata.contacts.service
import atom
import gdata.contacts
import getpass
client = gdata.contacts.service.ContactsService()
client.email = raw_input('Please enter your email address')
client.password = getpass.getpass()
client.source = 'Google-ContactsGetTest-1.0'
client.ProgrammaticLogin()
name = 'Fred'
notes = 'Test entry'
primary_email = 'test2903488769871632@example.com'
new_contact = gdata.contacts.ContactEntry(title=atom.Title(text=name))
new_contact.content = atom.Content(text=notes)
new_contact.email.append(gdata.contacts.Email(address=primary_email,
primary='true', rel=gdata.contacts.REL_WORK))
new_contact.phone_number.append(gdata.contacts.PhoneNumber(
rel=gdata.contacts.REL_OTHER, text='555-1212-3242'))
entry = client.CreateContact(new_contact)
if entry:
print 'Creation successful!'
print 'Edit link for the new contact:', entry.GetEditLink().href
else:
print 'Upload error.'
# Remove the phone number
del entry.phone_number[0]
updated = client.UpdateContact(entry.GetEditLink().href, entry)
if updated:
print 'Update successful!'
print 'Edit link for the updated contact:', updated.GetEditLink().href
else:
print 'Upload error.'
raw_input('enter to delete')
client.Delete(updated.GetEditLink().href)