pythongoogle-apigoogle-directory-apiservice-accountsgoogle-email-settings-api

Enable mail forwarding using a Google Apps Service Account


On April 20, 2015, several Google Apps APIs are being discontinued, including the Provisioning API(gdata).
In my Python scripts, I am using a Service Account and OAuth 2.0, instead of ClientLogin, and the replacement API: Directory API.
However, I am unable to find a way to enable mail forwarding using the new API, and all of Google's Python documentation for mail forwarding explains how to do it using ClientLogin, which is also being discontinued on April 20th.

Relevant Info:
I have a service account and authorized it appropriately following this guide: https://developers.google.com/api-client-library/python/auth/service-accounts
All of my other functionality is working with the new API!
I have thoroughly searched the Directory API documentation(though I don't rule out the chance that I missed something): https://developers.google.com/resources/api-libraries/documentation/admin/directory_v1/python/latest/index.html
Google's only documentation(that I found) about implementing mail forwarding with Python suggests using ClientLogin as mentioned above: https://developers.google.com/admin-sdk/email-settings/#manage_forwarding_settings

My existing working code for mail forwarding(based on that documentation):

client = gdata.apps.emailsettings.client.EmailSettingsClient(domain='mydomain.co')
client.ClientLogin(email=adminEmail, password=adminPass, source='apps')
client.UpdateForwarding(username=username, enable=True, 
    forward_to=forwardTo, action='ARCHIVE')

My updated code based on Jay Lee's answer:

credentials = SignedJwtAssertionCredentials(serviceEmail, key, sub=adminEmail, 
    scope='https://apps-apis.google.com/a/feeds/emailsettings/2.0/ '+'other scopes')
client = gdata.apps.emailsettings.client.EmailSettingsClient(domain='mydomain.co')
client.additional_headers = {'Authorization': 'Bearer %s' % credentials.access_token}
client.UpdateForwarding(username=username, enable=True, 
    forward_to=forwardTo, action='ARCHIVE')

And I added the new scope to my service account in:
Admin Console->Security->Advanced Settings->Manage API Client Access(under Authentication)
*Note: If you are using other scopes, you need to type all of them because it replaces your previous settings.

Update:
I thought I had it was working, but I may have had a line commented out or ignored. When I tried my code later in the day, with everything line being executed properly, it was still giving me a gdata.client.Unauthorized error. I have tried restarting my server so the credentials would be created again, but it has not helped. The error occurs when I try to make the update forwarding call.
I confirmed that the access_token is the same as the one that is working for my Directory API calls, and that "client" is in fact a emailSettingsClient object.
The full error I receive is:

Unauthorized error message

Another attempt based on the following:
http://www.worldofchris.com/blog/2012/12/27/fun-with-oauth-gdata-google-apis-client-library-python/
https://groups.google.com/forum/m/#!msg/google-apps-developer-blog/1pGRCivuSUI/3EAIioKp0-wJ How do I authorize a gdata client without using the gdata oauth2 workflow?

credentials = SignedJwtAssertionCredentials(serviceEmail, key, sub=adminEmail, 
    scope='https://apps-apis.google.com/a/feeds/emailsettings/2.0/ '+'other scopes')
auth = gdata.gauth.OAuth2Token(serviceEmail, key, 
    scope='https://apps-apis.google.com/a/feeds/emailsettings/2.0/',
    access_token=credentials.access_token,
    refresh_token=credentials.refresh_token,
    user_agent='emailsettings/2.0')#I do not really understand this param
client = gdata.apps.emailsettings.client.EmailSettingsClient(domain='mydomain.co')
#Also tried with (domain='mydomain.co', auth_token = credentials.access_token)
client.additional_headers = {'Authorization': 'Bearer %s' % credentials.access_token}
auth.authorize(client)
client.UpdateForwarding(username=username, enable=True, 
    forward_to=forwardTo, action='ARCHIVE')

Solution

  • This should be the proper way to use the credentials object directly:

    import gdata.gauth
    
    credentials = SignedJwtAssertionCredentials(serviceEmail,
                                                key, 
                                                sub=adminEmail,
                                                scope=scopes)
    client = gdata.apps.emailsettings.client.EmailSettingsClient(domain='mydomain.co')
    client.auth_token = gdata.gauth.OAuth2TokenFromCredentials(credentials)
    client.UpdateForwarding(username=username, enable=True, 
    forward_to=forwardTo, action='ARCHIVE')