Google Workspace has no bulk signature management. You can set a signature for one user at a time through Gmail settings — that's it. For a domain with hundreds of employees across multiple office locations, job titles, and phone numbers, that's not a workflow.
This toolkit manages email signatures at the domain level: define HTML templates, store each user's signature fields (title, location, phone, extension) in Google Directory's custom schema, and push rendered signatures to every user's Gmail account programmatically. When someone's phone number changes or a new template rolls out to a branch, one script run updates everyone.
| Script | Purpose |
|---|---|
scripts/email_templates.py |
Defines all HTML signature templates with dynamic field injection |
scripts/authenticator.py |
Google service account auth and API service builders |
scripts/google_api.py |
Shared helpers: bulk signature push, error reporting, user fetching |
scripts/all_user_download.py |
Downloads all user records from the Admin SDK to CSV |
scripts/get_all_signatures.py |
Exports every active user's live Gmail signature HTML to a shared Drive folder |
scripts/update_sig_info.py |
Patches multiple Signature_Info fields for a roster of users (dry-run by default) |
scripts/update_sig_field.py |
Bulk-sets a single field to the same value across a targeted user list |
scripts/update_single.py |
Updates the live signature for one user; generates a preview image |
scripts/sig_info_report.py |
Exports the Signature_Info custom schema for all users to CSV |
scripts/audit_template.py |
Audits which users have a specific template applied and flags mismatches |
scripts/verify_template.py |
Verifies a roster of users have the correct template and field values |
scripts/preview_template.py |
Renders a JPG preview for a roster of users without pushing to Gmail |
scripts/check_team_template.py |
Checks that all members of a group have a consistent template |
scripts/push_phone_updates.py |
Pushes phone number updates to a targeted user list |
scripts/lookup_orgunits.py |
Lists the org unit path for every user in the domain |
- Python 3.9+
- Google Cloud project with Gmail API and Admin SDK enabled
- Service account with domain-wide delegation and the following scopes:
https://www.googleapis.com/auth/admin.directory.userhttps://www.googleapis.com/auth/admin.directory.userschemahttps://www.googleapis.com/auth/gmail.settings.basichttps://www.googleapis.com/auth/gmail.settings.sharinghttps://www.googleapis.com/auth/drive(forget_all_signatures.py)
wkhtmltopdfinstalled and on PATH (forupdate_single.pypreview images)
pip install -r requirements.txtCopy .env.example to .env and fill in your values:
cp .env.example .envPlace your service account key JSON in a Keys/ folder (or set KEY_PATH in .env to its absolute path). The authenticator.py module searches several common locations and also respects KEY_PATH as an override.
- Auth — A service account with domain-wide delegation impersonates the admin user to call the Admin SDK, then impersonates each individual user to call the Gmail API on their behalf.
- Custom schema — Signature fields (title, location, extension, direct line, template key) are stored in a
Signature_Infocustom schema on each user's Google Directory profile. This makes them queryable and auditable without touching Gmail directly. - Pagination — The Admin SDK returns up to 500 users per page; scripts loop through all pages via
nextPageToken. - Template selection —
email_templates.pymaps aTemplatekey (e.g.branch_a,corp_hr) to a fully rendered HTML string. The key is stored in each user'sSignature_Infoschema and read at push time. - Application — Each user's signature is set via
users.settings.sendAs.patchtargeting their primary send-as address. - Dry-run safety —
update_sig_info.pyandupdate_sig_field.pydefault to dry-run mode and print diffs before writing. Pass--applyto commit changes.