Dimrok
Dimrok

Reputation: 51

Google Contact API - Auth2.0

I'm looking for a good way to retrieve every emails address of my contacts from a google account for a "desktop" application in Python.

In a first time, I created an app via Google Code. I toggled Google Plus API, retrieving most of my user data, but not any of my contacts.

I started investigate, and I found a lot of stuff, but most of them was outdated.

I found a good way to retrieve my contacts, using gdata library but granting me a full read/write access on it, via https://www.google.com/m8/feeds with no feedback.

self.gd_client = gdata.contacts.client.ContactsClient(source='MyAppliName')
self.gd_client.ClientLogin(email, password, self.gd_client.source)

According to the official 'google contact api' google group, which migrated to stackoverflow, read only access is broken.

By the way, I'm not a huge fan of 'Trust my application, I use read only access, I swear."

I found the google api playground at https://developers.google.com/oauthplayground in which they use OAuth2.0 token with most of apis, including contact, toggling a webpage:

Google OAuth 2.0 Playground is requesting permission to:

  • Manage your contacts

According to this playground, it's possible to use OAuth2.0 with google contact api, but I have no idea how to add https:// www.google.com/m8/feeds to my scope, which doesn't appear on the list.

Is there an other way to do that ?

Upvotes: 4

Views: 1539

Answers (2)

Paul
Paul

Reputation: 5781

If this question is still open for you, here is some sample code how to use oauth2 and Google Contact API v3:

import gdata.contacts.client
from gdata.gauth import AuthSubToken
from oauth2client import tools
from oauth2client.client import flow_from_clientsecrets
from oauth2client.file import Storage


def oauth2_authorize_application(client_secret_file, scope, credential_cache_file='credentials_cache.json'):
    """
    authorize an application to the requested scope by asking the user in a browser.

    :param client_secret_file: json file containing the client secret for an offline application
    :param scope: scope(s) to authorize the application for
    :param credential_cache_file: if provided or not None, the credenials will be cached in a file.
        The user does not need to be reauthenticated
    :return OAuth2Credentials object
    """
    FLOW = flow_from_clientsecrets(client_secret_file,
                                   scope=scope)

    storage = Storage(credential_cache_file)
    credentials = storage.get()

    if credentials is None or credentials.invalid:
        # Run oauth2 flow with default arguments.
        credentials = tools.run_flow(FLOW, storage, tools.argparser.parse_args([]))

    return credentials

SCOPES = ['https://www.google.com/m8/feeds/', 'https://www.googleapis.com/auth/userinfo.email']

credentials = oauth2_authorize_application('client-secret.json', scope=SCOPES)
token_string = credentials.get_access_token().access_token

# deprecated!
# auth_token = AuthSubToken(token_string, SCOPES)

with open('client-secret.json') as f:
    oauth2_client_secret = json.load(f)

auth_token = gdata.gauth.OAuth2Token(
    client_id=oauth2_client_secret['web']['client_id'],
    client_secret=oauth2_client_secret['web']['client_secret'],
    scope=SCOPES,
    user_agent='MyUserAgent/1.0',
    access_token=credentials.get_access_token().access_token,
    refresh_token=credentials.refresh_token)


client = gdata.contacts.client.ContactsClient(auth_token=auth_token)

query = gdata.contacts.client.ContactsQuery()

Upvotes: 4

Mark S.
Mark S.

Reputation: 4017

The request should look like:

https://accounts.google.com/o/oauth2/auth?
scope=https%3A%2F%2Fwww.google.com%2Fm8%2Ffeeds&
state=<myState>&
redirect_uri=<Redirect URI>&
response_type=code&
client_id=<my Client ID>&approval_prompt=force

This will obtain read/write access to the user's contacts.

Upvotes: 1

Related Questions