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:
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:
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.
source to share