gmail-statement-fetcher

star 18

Automatically download bank/financial statement PDFs from Gmail via IMAP or OAuth. Config-driven bank rules, UID dedup, ZIP extraction, PDF decryption.

notoriouslab By notoriouslab schedule Updated 4/2/2026

name: gmail-statement-fetcher description: Automatically download bank/financial statement PDFs from Gmail via IMAP or OAuth. Config-driven bank rules, UID dedup, ZIP extraction, PDF decryption. metadata: {"openclaw":{"emoji":"๐Ÿ“ฌ","version":"1.0.2","homepage":"https://github.com/notoriouslab/gmail-statement-fetcher","requires":{"bins":["python3"],"env_via_dotenv":["GMAIL_USER","GMAIL_APP_PASSWORD"]}}}

gmail-statement-fetcher

Automatically download bank/financial statement PDFs from Gmail.

When to use

  • User asks to download bank statements from Gmail
  • User wants to set up automated statement fetching
  • User asks to fetch encrypted/password-protected PDF statements
  • User wants to extract PDFs from ZIP attachments in email

Credential setup

Credentials MUST be loaded from environment or secrets file โ€” NEVER inline passwords in shell commands.

# Option A: .env file in the project directory (recommended)
# Create {baseDir}/.env with:
#   GMAIL_USER=user@gmail.com
#   GMAIL_APP_PASSWORD=your-app-password
# The fetcher loads .env automatically via python-dotenv.

# Option B: export from secrets file
export GMAIL_USER=$(python3 -c "import json; print(json.load(open('$HOME/.paiop_secrets.json'))['gmail_user'])")
export GMAIL_APP_PASSWORD=$(python3 -c "import json; print(json.load(open('$HOME/.paiop_secrets.json'))['gmail_app_password'])")

Bank PDF/ZIP passwords follow the same pattern โ€” use env vars or .env, never inline:

# In .env:
#   SINOPAC_PDF_PASSWORD=xxx
#   CTBC_ZIP_PASSWORD=xxx

Commands

Fetch statements (IMAP mode, default)

python3 {baseDir}/fetcher.py

Dry run โ€” preview matches without downloading

python3 {baseDir}/fetcher.py --dry-run --verbose

Custom config and output directory

python3 {baseDir}/fetcher.py --config "{{config_path}}" --output-dir "{{output_dir}}"

OAuth mode

AUTH_METHOD=oauth python3 {baseDir}/fetcher.py

Options

Flag Description
--config Path to config JSON (default: <script dir>/config.json)
--output-dir Directory to save PDFs (default: <script dir>/downloads)
--state-file Path to UID dedup store (default: <output-dir>/.processed_uids.json)
--auth imap or oauth (overrides AUTH_METHOD env var)
--dry-run Preview matched emails without downloading
--verbose Enable debug logging

Environment variables

Variable Mode Description
GMAIL_USER IMAP Gmail address
GMAIL_APP_PASSWORD IMAP Gmail App Password
AUTH_METHOD Both imap (default) or oauth
OAUTH_CREDENTIALS OAuth Path to credentials.json from GCP Console
OAUTH_TOKEN OAuth Path to token.json (auto-generated)
{BANKID}_PDF_PASSWORD Both PDF decryption password for a specific bank (e.g. SINOPAC_PDF_PASSWORD). Takes precedence over pdf_password in config.json.
{BANKID}_ZIP_PASSWORD Both ZIP extraction password for a specific bank (e.g. CTBC_ZIP_PASSWORD). Takes precedence over zip_password in config.json.

Exit codes

Code Meaning
0 Completed successfully
1 Runtime error (IMAP/OAuth failure, config missing)

Notes

  • IMAP mode uses Python stdlib only โ€” no pip install needed
  • Bank matching rules are config-driven โ€” add banks via config.json, no code changes
  • UID dedup prevents re-downloading already-processed emails across runs
  • Supports password-protected PDFs (via pikepdf) and ZIP attachments
  • ZIP extraction includes streaming bomb guard (100 MB cap)
  • .processed_uids.json stores hashed subjects only (no PII)
Install via CLI
npx skills add https://github.com/notoriouslab/gmail-statement-fetcher --skill gmail-statement-fetcher
Repository Details
star Stars 18
call_split Forks 4
navigation Branch main
article Path SKILL.md
More from Creator
notoriouslab
notoriouslab Explore all skills →