Cryptographically-verified email export from multiple Gmail accounts with PDF generation, dual-hash integrity (SHA-256 + Blake3), and structured forensic manifests.
Gmail Forensic Exporter (GFE) is a single-file Python tool designed for individuals who need to extract, preserve, and verify email communications from multiple Gmail accounts — particularly for legal, archival, or evidentiary purposes. The tool filters emails by specific sender/recipient addresses (e.g., family members, legal contacts), generates individual PDF exports with embedded metadata, computes SHA-256 and Blake3 cryptographic hashes for every file, and produces machine-readable manifests in Markdown, JSON, and CSV formats.
Built with forensic rigor: every export is tamper-evident, timestamped, and includes a chain-of-custody block within each PDF.
From, To, Cc, and Bcc fieldsafter:, before:).py file handles everythingblake3, reportlab) are missinggit clone https://github.com/declanosullivan/gmail-forensic-exporter.git
cd gmail-forensic-exporter
python3 -m venv venv
source venv/bin/activate # Linux/macOS
# venv\Scripts\activate # Windows
pip install -r requirements.txt
credentials_account_1.json)Note: Enable the Gmail API under APIs & Services > Library before creating credentials.
python gmail_forensic_exporter.py --sample-config
Edit gfe_config.json:
{
"accounts": [
{
"name": "personal",
"credentials_file": "credentials_personal.json",
"token_file": "token_personal.json"
},
{
"name": "work",
"credentials_file": "credentials_work.json",
"token_file": "token_work.json"
}
],
"target_emails": [
"parent1@example.com",
"parent2@example.com",
"sibling@example.com"
],
"output_dir": "./gmail_forensic_export",
"date_range": {
"after": "2024-01-01",
"before": null
},
"max_results_per_account": 500,
"include_attachments": false,
"pdf_page_size": "A4"
}
python gmail_forensic_exporter.py --config gfe_config.json
Or use CLI overrides:
python gmail_forensic_exporter.py \
--accounts personal,work \
--targets parent1@example.com,parent2@example.com \
--after 2024-01-01 \
--max-results 200
gmail_forensic_export/
├── pdfs/
│ ├── personal_20240115_093022_18a3f7..._Subject_Line.pdf
│ ├── personal_20240116_142511_9b2e1d..._Re_Meeting.pdf
│ ├── work_20240120_081134_3c5a8f..._Contract_Draft.pdf
│ └── ...
├── manifest.md # Human-readable markdown table
├── manifest.json # Full machine-readable manifest with hashes
└── manifest.csv # Spreadsheet-compatible CSV
# SHA-256
sha256sum gmail_forensic_export/pdfs/personal_20240115_093022_*.pdf
# Blake3 (requires b3sum)
b3sum gmail_forensic_export/pdfs/personal_20240115_093022_*.pdf
sha256sum gmail_forensic_export/manifest.json
# Compare against manifest.json -> manifest_sha256 field
| Dependency | Purpose | Required |
|---|---|---|
google-api-python-client |
Gmail API access | Yes |
google-auth-httplib2 |
HTTP transport for auth | Yes |
google-auth-oauthlib |
OAuth2 flow | Yes |
reportlab |
PDF generation | No (recommended) |
blake3 |
Blake3 hashing | No (recommended) |
beautifulsoup4 |
HTML-to-text conversion | No (recommended) |
See requirements.txt for pinned versions.
usage: gmail_forensic_exporter.py [-h] [--config CONFIG] [--sample-config]
[--accounts ACCOUNTS] [--targets TARGETS]
[--output OUTPUT] [--after AFTER]
[--before BEFORE] [--max-results MAX_RESULTS]
[--no-pdf]
Gmail Forensic Exporter
optional arguments:
-h, --help show this help message and exit
--config CONFIG, -c CONFIG
Path to configuration JSON file (default: gfe_config.json)
--sample-config Create a sample configuration file and exit
--accounts ACCOUNTS Comma-separated account names (override config)
--targets TARGETS Comma-separated target email addresses (override config)
--output OUTPUT, -o OUTPUT
Output directory (override config)
--after AFTER Only emails after YYYY-MM-DD
--before BEFORE Only emails before YYYY-MM-DD
--max-results MAX_RESULTS
Maximum emails per account (default: 500)
--no-pdf Skip PDF generation, export metadata only
threadId into consolidated thread PDFsINBOX, exclude SPAM)libpff)gmail.readonly OAuth scope; never modifies, deletes, or sends emailstoken_*.json files as sensitiveMIT License — see LICENSE for details.
Contributions welcome. Please open an issue for bug reports or feature requests, or submit a pull request with a clear description of changes.