Last active
September 8, 2021 18:06
-
-
Save timrichardson/a43462aedc0797ecb76c48deb9c96d36 to your computer and use it in GitHub Desktop.
Use Python, OAuth2 and Google APIs to mass-update gmail signatures of a Google Apps for Work domain. Using a google service account for the credential.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# python 2.7 | |
# ********************************************************************************************************* | |
# | |
# | |
# | |
# Please see https://gist.github.com/timrichardson/e6ee6640a8b7fe664f3a5a80406ca980 | |
# | |
# for a modern way of doing this, using the current API and python 3 | |
# | |
# | |
# | |
# | |
# ********************************************************************************************************* | |
""" Read data from a spreadsheet to construct an HTML signature, and update users. | |
This is enough code to get you going. | |
You have a service account via a project setup on the Google Developer console. | |
Download the key in json format. | |
Next you need to go to the domain's Google admin to enable the correct google API. | |
The scope is API_scopes =['https://apps-apis.google.com/a/feeds/emailsettings/2.0/'] | |
In more detail: | |
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 | |
""" | |
from __future__ import print_function | |
import pandas as pd | |
import httplib2 | |
from oauth2client.service_account import ServiceAccountCredentials | |
import gdata.apps.emailsettings.client | |
import gdata.gauth | |
import ssl | |
from string import Template | |
excelfile = "email_list.xlsx" | |
# build a signature | |
sig_template = Template(""" | |
<html> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Email Signature</title> | |
</head> | |
<body style="margin:0px; padding:0px;"> | |
... | |
</body> | |
</html> | |
""") | |
def update_sig(full_name,job_title,telephone,username,sig_template,gmail_client=None): | |
sig = sig_template.substitute(full_name = full_name,job_title=job_title, | |
telephone=telephone) | |
if gmail_client.UpdateSignature(username=username,signature=sig): | |
return "Signature changed" | |
else: | |
return None | |
def setup_credentials(delegate_email = None): | |
#delegated credentials seem to be required for email_settings api | |
key_path = '/tmp/VCI-EMAIL-INTEGRATION-abacbcabc.json' | |
API_scopes =['https://apps-apis.google.com/a/feeds/emailsettings/2.0/'] | |
credentials = ServiceAccountCredentials.from_json_keyfile_name(key_path, scopes=API_scopes) | |
if delegate_email: | |
return credentials.create_delegated(delegate_email) | |
return credentials | |
def test_1(credentials,domain,user): | |
""" a low level test of something simple. If this works, you have the authentication working | |
User is the name of the user, not the full email address. e.g. tim """ | |
http = httplib2.Http() | |
# http = credentials.authorize(http) | |
http = credentials.authorize(http) # this is necessary | |
url_get_sig = 'https://apps-apis.google.com/a/feeds/emailsettings/2.0/{domain}/{user}/signature'.format(**locals()) | |
r = http.request(url_get_sig, "GET") | |
return r | |
if __name__ == "__main__": | |
delegated_credentials = setup_credentials('[email protected]') # this user is a super admin. | |
#test with a low level attempt | |
(res1,res2) = test_1(delegated_credentials) | |
assert(res1['status'] == '200') | |
# try with the EmailSettingsClient | |
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) | |
# now read a spreadsheet and bulk update | |
user_data = pd.ExcelFile(excelfile) | |
df = user_data.parse("Sheet1") | |
for r in df.values: | |
username = r[0] | |
first_name = "%s" % r[1] | |
if first_name == "nan": | |
first_name = '' | |
second_name = "%s" % r[2] | |
if second_name == "nan": | |
second_name = '' | |
full_name = "%s %s" % (first_name, second_name) | |
job_title = "%s" % r[3] | |
if job_title == 'nan': | |
job_title = '' | |
telephone = "%s" % r[4] | |
if telephone == 'nan': | |
telephone = "1300 863 824" | |
try: | |
print (update_sig(full_name=full_name,job_title=job_title,gmail_client=client, | |
telephone = telephone,username = username, sig_template=sig_template)) | |
except gdata.client.RequestError: | |
print ("Client Error (user not found probably) for {}".format(full_name)) | |
continue | |
except ssl.SSLEOFError: | |
print("SSL handshake Error for {}".format(full_name)) | |
continue | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for the script! I got this working, but how do we call the full_name and job_title in the HTML template? If I put full_name in the HTML section, it updates my signature with full_name instead of the actual name.
EDIT: Duh, you have to do $full_name