Skip to content

Instantly share code, notes, and snippets.

@timrichardson
Last active September 8, 2021 18:06
Show Gist options
  • Save timrichardson/a43462aedc0797ecb76c48deb9c96d36 to your computer and use it in GitHub Desktop.
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.
# 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
@topper59
Copy link

topper59 commented Sep 12, 2017

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment