Does the Gmail API support using OAuth service accounts?

I am trying to use the Gmail API with the Google Python client library.

I created a service account account via google developer console.

Then I try to use these credentials like sO:

from oauth2client.client import SignedJwtAssertionCredentials
client_email = '<sanitised>@developer.gserviceaccount.com'

with open("foobar-<sanitised>.p12") as f:
    private_key = f.read()
    credentials = SignedJwtAssertionCredentials(client_email, private_key, 'https://www.googleapis.com/auth/gmail.readonly')

from httplib2 import Http
http_auth = credentials.authorize(Http())
from apiclient.discovery import build
gmail_server = build('gmail', 'v1', http=http_auth)

      

However, when I try to use the actual Gmail API, I get an HTTP 500 error:

In [13]: threads = gmail_server.users().threads().list(userId='me').execute()
---------------------------------------------------------------------------
HttpError                                 Traceback (most recent call last)
<ipython-input-13-a74134635cc3> in <module>()
----> 1 threads = gmail_server.users().threads().list(userId='me').execute()

/Users/victorhooi/.virtualenvs/kenny/lib/python2.7/site-packages/oauth2client/util.pyc in positional_wrapper(*args, **kwargs)
    133         else: # IGNORE
    134           pass
--> 135       return wrapped(*args, **kwargs)
    136     return positional_wrapper
    137

/Users/victorhooi/.virtualenvs/kenny/lib/python2.7/site-packages/googleapiclient/http.pyc in execute(self, http, num_retries)
    721       callback(resp)
    722     if resp.status >= 300:
--> 723       raise HttpError(resp, content, uri=self.uri)
    724     return self.postproc(resp, content)
    725

HttpError: <HttpError 500 when requesting https://www.googleapis.com/gmail/v1/users/me/threads?alt=json returned "Backend Error">

      

User mentioned here that apparently "Service Accounts" doesn't support using the GMail API:

Stackoverflow

Can anyone confirm if this is the case, or if it's documented by Google anywhere?

My guess was that since the service account credentials were created through the custom Google Developer Console, would it just be associated with that user and should work fine?

EDIT

I also wanted to mention that I tried to explicitly add my client to the Client API Access Control page in the Google Apps Admin Console:

enter image description here

However, I am still getting HTTP 500 Backend error.

Also, the help links on this page go to the OAuth 1.0 page - I have a suspicion that this page is for OAuth 1.0 only, even though it is not explicitly mentioned there.

EDIT 2

Also, I should have mentioned that I tried to use Google API Explorer at:

https://developers.google.com/apis-explorer/#p/gmail/v1/gmail.users.messages.list?userId=me&_h=1&

using OAuth 2.0 and interactive user flow and it works great (i.e. contains email lists).

EDIT 3

I tried to add an argument sub

as Jay Lee suggested.

On my own Google Apps domain, it actually works:

from oauth2client.client import SignedJwtAssertionCredentials
client_email = '<sanitised>@developer.gserviceaccount.com'
with open('foo-bar-<sanitised>.p12') as f:
    private_key = f.read()
credentials = SignedJwtAssertionCredentials(client_email, private_key, 'https://www.googleapis.com/auth/gmail.readonly', sub='victorhooi@example.com')
from httplib2 import Http
http_auth = credentials.authorize(Http())
from apiclient.discovery import build
gmail_server = build('gmail', 'v1', http=http_auth)
threads = gmail_server.users().threads().list(userId='me').execute()

      

And then changes the thread:

In [12]: threads
Out[12]:
{u'nextPageToken': u'00058094761552980977',
 u'resultSizeEstimate': 178,
 u'threads': [{u'historyId': u'8942',
   u'id': u'14abc26f1893823b',
   u'snippet': u''},
  {u'historyId': u'8822', u'id': u'14a4ffc2724e9384', u'snippet': u''},
  {u'historyId': u'8769', u'id': u'14a36a9c6f552af3', u'snippet': u''},
  {u'historyId': u'8716', u'id': u'14a31822f19bb161', u'snippet': u''},
  {u'historyId': u'8671', u'id': u'14a2bee13eb87c07', u'snippet': u''},

      

However, when I try to use the helper argument in my corporate Google Apps domain, when I go to the next line:

gmail_server = build('gmail', 'v1', http=http_auth)

      

This gives me an error:

AccessTokenRefreshError: access_denied: Requested client not authorized.

      

I'm pretty sure the client exists in the google developer console and the Gmail API is enabled. I just don't know why the argument sub

is causing this error.

And then if I try to use the same code using a different account in the Google Apps corporate domain that has not been delegated, I get:

AccessTokenRefreshError: unauthorized_client: Unauthorized client or scope in request.

      

+3


source to share


1 answer


Try using:

credentials = SignedJwtAssertionCredentials(client_email, private_key,
  'https://www.googleapis.com/auth/gmail.readonly', sub='user@domain.com')

      



where user@domain.com is the user you want to impersonate.

+3


source







All Articles