问题
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
gmail_client.RetrieveSignature(username)
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_id,#serviceEmail
credentials.client_secret,#private key
scope='https://apps-apis.google.com/a/feeds/emailsettings/2.0/',
access_token=credentials.access_token,
refresh_token=credentials.refresh_token,
user_agent=credentials.user_agent)
auth.authorize(client)
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/"
回答1:
Email settings API requires you to authenticate as a super admin, regular users can't access the API. So your service account should be acting as the super admin and then the super admin making the change for the user specified in the API call.
回答2:
Please note: this answer is out of date and uses a deprecated API. This gist shows the new way of doing it (and in python3) https://gist.github.com/timrichardson/e6ee6640a8b7fe664f3a5a80406ca980
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.
- 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.
- 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)
auth2token.authorize(client)
r = client.retrieve_signature('tim')
print (client)
this is a richer example here: https://gist.github.com/timrichardson/a43462aedc0797ecb76c48deb9c96d36
来源:https://stackoverflow.com/questions/36613872/manage-gmail-signatures-with-python-service-account