Tim Richardson Tim Richardson - 6 months ago 121x
Python Question

Manage gmail signatures with python service account

I want to edit signatures of users in a google apps domain.
I plan to use a service account. The service account is delegated to the entire domain.
I have this working with the gmail API to send and retrieve email, but signatures are modified using a different api.
According to https://developers.google.com/admin-sdk/email-settings/ this api is the Admin SDK which I have enabled via Google Developer Console.

I am trying to use the library
gdata.apps.emailsettings.client (which doesn't have Python 3.x support)

Building the credentials works, but when I try to do


I get
gdata.client.Unauthorized: Unauthorized - Server responded with: 401.

# python 2.7 from macports
def setup_gmail_client_new_api():
client_email = '...3@developer.gserviceaccount.com'

key_path = 'VCI-EMAIL-INTEGRATION-f493528321ba.json'
sender = 'tim@vci.com.au'
API_scope = 'https://apps-apis.google.com/a/feeds/emailsettings/2.0/'
filename=key_path, scopes=API_scope)
credentials = ServiceAccountCredentials.from_json_keyfile_name(key_path, scopes=API_scope)
return credentials

if __name__ == "__main__":
credentials = setup_gmail_client_new_api()
client = gdata.apps.emailsettings.client.EmailSettingsClient(domain='vci.com.au')

auth = gdata.gauth.OAuth2Token(
credentials.client_secret,#private key

result = retrieve_sig(client,"tim")
print (result)

the attempt to retrieve the signature:

gdata.client.Unauthorized: Unauthorized - Server responded with: 401,

the service account has domain-wide delegation.
In the google apps domain security control panel (Manage API client access),
the service ID has permission for "Email Settings (Read/Write) https://apps-apis.google.com/a/feeds/emailsettings/2.0/"


Right. I hope this post saves hours of work.

Key missing point which was not documented very well (ok, not at all, but perhaps I missed it). You need to use delegated_credentials and authorise the email_settings_client with that object.

  1. Follow the oauth2 notes to make a service account and download a JSON private key as usual. You do that on the developer console. The service account is not linked to any domain, it is just a credential.
  2. In your google apps domain, go the security, advanced, api etc etc. Steps 1 & 2 are currently documented here: https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority

Now, the python code. I used 2.7 because I think gdata is not v3 compatible.

This is a minimal example.

from __future__ import print_function

import httplib2
from oauth2client.service_account import ServiceAccountCredentials
import gdata.apps.emailsettings.client
import gdata.gauth

def setup_credentials():
        key_path = '/Users/tim/Dropbox/pycharm_projects_27/gmail_admin/<blabla>.json'
        API_scopes =['https://apps-apis.google.com/a/feeds/emailsettings/2.0/']
        credentials = ServiceAccountCredentials.from_json_keyfile_name(key_path, scopes=API_scopes)
        return credentials

if __name__ == "__main__":
    credentials = setup_credentials()

    # pass the email address of a domain super-administrator
    delegated_credentials = credentials.create_delegated('tim@vci.com.au')
    http = httplib2.Http()
    #http = credentials.authorize(http)
    http = delegated_credentials.authorize(http)  #this is necessary

    url_get_sig = 'https://apps-apis.google.com/a/feeds/emailsettings/2.0/vci.com.au/tim/signature'
    r = http.request(url_get_sig,"GET")
    print (r)

    # now use the library
    client = gdata.apps.emailsettings.client.EmailSettingsClient(domain='vci.com.au')
    auth2token = gdata.gauth.OAuth2TokenFromCredentials(delegated_credentials)
    r = client.retrieve_signature('tim')
    print (client)

this is a richer example here: https://gist.github.com/timrichardson/a43462aedc0797ecb76c48deb9c96d36