Skip to content

Instantly share code, notes, and snippets.

@timrichardson
Last active November 23, 2023 12:51
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save timrichardson/e6ee6640a8b7fe664f3a5a80406ca980 to your computer and use it in GitHub Desktop.
Save timrichardson/e6ee6640a8b7fe664f3a5a80406ca980 to your computer and use it in GitHub Desktop.
Modern way to edit gmail signatures with python3 and the gmail API
from string import Template
import time
import pytest
from google.oauth2 import service_account
from googleapiclient.discovery import build
from googleapiclient.errors import *
from google.auth.exceptions import *
import easygui
import pandas as pd
def get_api_credentials(key_path):
API_scopes =['https://www.googleapis.com/auth/gmail.settings.basic',
'https://www.googleapis.com/auth/gmail.settings.sharing']
credentials = service_account.Credentials.from_service_account_file(key_path,scopes=API_scopes)
return credentials
def update_sig(full_name, job_title, telephone, username, sig_template, credentials,live=False):
sig = sig_template.substitute(full_name=full_name, job_title=job_title,
telephone=telephone)
print("Username: %s Fullname: %s Job title: %s" % (username, full_name, job_title))
if live:
credentials_delegated = credentials.with_subject(username)
gmail_service = build("gmail", "v1", credentials=credentials_delegated)
addresses = gmail_service.users().settings().sendAs().list(userId='me',
fields='sendAs(isPrimary,sendAsEmail)').execute().get('sendAs')
# this way of getting the primary address is copy & paste from google example
address = None
for address in addresses:
if address.get('isPrimary'):
break
if address:
rsp = gmail_service.users().settings().sendAs().patch(userId='me',
sendAsEmail=address['sendAsEmail'],
body={'signature':sig}).execute()
print(f"Signature changed for: {username}")
else:
print(f"Could not find primary address for: {username}")
def main():
excelfile = easygui.fileopenbox(msg="Please open the .xlsx file with signature",title="Choose signatures .xlsx file")
if not excelfile:
print("No signature .xlsx file selected, so stopping")
return
user_data = pd.ExcelFile(excelfile)
# df = user_data.parse("testsheet")
df = user_data.parse("livedata")
key_path = easygui.fileopenbox(msg="Please open the confidential Google secret .json file",
title="Choose Google json secrets")
credentials = get_api_credentials(key_path=key_path)
if not credentials:
print("No credential file selected, so stopping")
return
try:
sig_file = open("template.html", "r")
sig_template = Template(sig_file.read())
except (FileNotFoundError,IOError):
print("Could not open the template file")
raise
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"
retry_count = 0
while retry_count < 3:
try:
update_sig(full_name=full_name,job_title=job_title,username=username,telephone=telephone,
sig_template=sig_template,credentials=credentials,live=True)
break
except (RefreshError,TransportError) as e:
retry_count += 1
print(f"Error encountered for: {username}, retrying (attempt {retry_count}). Error was: {e}")
time.sleep(2)
continue
except Exception as e:
raise
else:
print(f"Failed to update {username}")
if __name__ == '__main__':
main()
@pytest.fixture
def get_test_api_credentials():
return get_api_credentials(key_path='private/gmailsignatureproject-86b504154ef1.json')
def test_fetch_user_info(credentials):
credentials_delegated = credentials.with_subject("tim@vci.com.au")
gmail_service = build("gmail","v1",credentials=credentials_delegated)
addresses = gmail_service.users().settings().sendAs().list(userId='me').execute()
assert gmail_service
def test_fetch_another_user(credentials):
credentials_delegated = credentials.with_subject("nadia@vci.com.au")
gmail_service = build("gmail", "v1", credentials=credentials_delegated)
addresses = gmail_service.users().settings().sendAs().list(userId='me').execute()
assert gmail_service
@ivan-arizto
Copy link

Thanks a lot. Used your example and my code is working now.

@alexmzirai
Copy link

alexmzirai commented Mar 28, 2021

hi guys...can anyone help me with email delegation using gmail api?
@timrichardson
This is my code so far:
https://dpaste.org/82GB

@rodrigoacastro
Copy link

Could you provide an example HTML file? I am trying to make my code work.

@ivan-arizto
Copy link

ivan-arizto commented Apr 7, 2021

Could you provide an example HTML file? I am trying to make my code work.

I think you can put the html as a string.

results = gmail.users().settings().sendAs().patch(userId='me', sendAsEmail=address['sendAsEmail'], body=signature).execute()

signature from above is signature = {'signature': '<div>something</div>' }

@ivan-arizto
Copy link

hi guys...can anyone help me with email delegation using gmail api?
@timrichardson
This is my code so far:
https://dpaste.org/82GB

404 from the link

@rodrigoacastro
Copy link

Could you provide an example HTML file? I am trying to make my code work.

I think you can put the html as a string.

results = gmail.users().settings().sendAs().patch(userId='me', sendAsEmail=address['sendAsEmail'], body=signature).execute()

signature from above is signature = {'signature': '<div>something</div>' }

Thanks, I will give another try!

@BigEHead
Copy link

BigEHead commented Feb 4, 2022

this is great. has anyone gotten it to work with information within workspace and not a separate Excel file?

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