Reputation: 407
I've been successfully experimenting with the Gmail API on my personal Google account. For simplicity, consider the Python QuickStart example (which works fine). The problem is that I'm unable to access my work Gmail using the same approach.
If I simply replace my personal email address with my work email address in the code...
results = service.users().labels().list(userId='myworkemail%40myworkdomain.com').execute()
...I get the standard delegation denied error:
<HttpError 403 when requesting https://www.googleapis.com/gmail/v1/users/myworkemail%40myworkdomain.com/labels?alt=json returned "Delegation denied for [email protected]">
Following a few hints from previous StackExchange questions, I've tried working through the instructions to make a service account and an authorised API call, with the service account form my personal account's developer console...
credentials = ServiceAccountCredentials.from_json_keyfile_name('service_account.json', scopes=SCOPES)
delegated_credentials = credentials.create_delegated('myworkemail%40myworkdomain.com')
http_auth = delegated_credentials.authorize(httplib2.Http())
service = discovery.build('gmail', 'v1', http=http_auth)
results = service.users().labels().list(userId='myworkemail%40myworkdomain.com').execute()
...but get a different error instead:
File "qs.py", line 70, in main
results = service.users().labels().list(userId='myworkemail%40myworkdomain.com').execute()
File "/usr/local/lib/python2.7/site-packages/oauth2client/util.py", line 135, in positional_wrapper
return wrapped(*args, **kwargs)
File "/usr/local/lib/python2.7/site-packages/googleapiclient/http.py", line 755, in execute
method=str(self.method), body=self.body, headers=self.headers)
File "/usr/local/lib/python2.7/site-packages/googleapiclient/http.py", line 93, in _retry_request
resp, content = http.request(uri, method, *args, **kwargs)
File "/usr/local/lib/python2.7/site-packages/oauth2client/client.py", line 597, in new_request
self._refresh(request_orig)
File "/usr/local/lib/python2.7/site-packages/oauth2client/client.py", line 863, in _refresh
self._do_refresh_request(http_request)
File "/usr/local/lib/python2.7/site-packages/oauth2client/client.py", line 932, in _do_refresh_request
raise HttpAccessTokenRefreshError(error_msg, status=resp.status)
oauth2client.client.HttpAccessTokenRefreshError: unauthorized_client: Unauthorized client or scope in request.
One other point to note: the API explorer examples on the Gmail API reference page work fine with my work account, and show up as authorised in 'My Account'. All I want is the same behaviour: for any Gmail account (personal or work) to be accessible by the same code, following explicit authorisation.
Upvotes: 0
Views: 259
Reputation: 407
So the answer (for non-webapp Python) is easy, once you've found it.
This is the updated get_credentials()
code from the Python quick start app:
def get_credentials():
home_dir = os.path.expanduser('~')
credential_dir = os.path.join(home_dir, '.credentials')
if not os.path.exists(credential_dir):
os.makedirs(credential_dir)
credential_path = os.path.join(credential_dir, 'gmail-python-quickstart.json')
store = oauth2client.file.Storage(credential_path)
credentials = store.get()
if not credentials or credentials.invalid:
flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES, login_hint = '[email protected]')
flow.user_agent = APPLICATION_NAME
if flags:
credentials = tools.run_flow(flow, store, flags)
else: # Needed only for compatibility with Python 2.6
credentials = tools.run(flow, store)
print('Storing credentials to ' + credential_path)
return credentials
The important change is the addition of login_hint = '[email protected]' into flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES, login_hint = '[email protected]')
This is documented here in the oauth2client documentation although in typical Google fashion, it's not mentioned anywhere in the Python OAuth 2 API documentation, that I can see.
Upvotes: 0
Reputation: 8112
You'll likely to receive an HTTP status code response of 403 once you exceeded per user rate limit of 250 quota units per user per second for your project as given in Gmail API - Usage Limits.
It is recommended in Manage Delegation Settings that your client application has a delay between the creation of more than one delegate or between the retrieval of newly created delegate and also states that each user delegating Gmail access is allowed a maximum 25 delegates. You may check the documentation for more notes regarding Gmail delegation.
Upvotes: 2