Send a Gmail
What It Does
Section titled “What It Does”Sends an email from your Gmail account, but started by a script instead of by you typing in Gmail. You give it the recipient, the subject, and the body (either plain text or a fancy HTML version), and it sends the email from ojhurst@gmail.com just like you did. Useful for reports, digests, and one-off messages that need to come from your real inbox instead of a robot-sender address.
When To Use
Section titled “When To Use”- Sending a report (e.g., the daily ATH digest, the GSC health report, invoice follow-ups).
- Programmatic outreach where the content is too custom for a template platform.
- One-off messages that need to come from James’s real inbox, not a transactional sender like Postmark or Resend.
How To Invoke
Section titled “How To Invoke”python3 ~/apps/gmail-notify/send-email.py \ --to recipient@example.com \ --subject "Your subject here" \ --html /tmp/body.htmlOr plaintext:
python3 ~/apps/gmail-notify/send-email.py \ --to recipient@example.com \ --subject "Your subject here" \ --text "Plain body text"Multiple recipients: comma-separated in --to.
Prerequisites
Section titled “Prerequisites”| Requirement | Where |
|---|---|
| Gmail OAuth token | ~/apps/gmail-notify/token.json (scope: gmail.send) |
Python google-auth, google-api-python-client | installed in the gmail-notify repo venv |
| The HTML body in a file (not inline) | encoding safety — use /tmp/body.html |
Where It Lives
Section titled “Where It Lives”- Script:
~/apps/gmail-notify/send-email.py - Related scripts in the same repo:
ath-report.py— weekly analytics email for All Things Handyath-daily-digest.py— daily digest with CRM + Cloudflare stats (runs on VPS cron at 9 AM)
- Token auto-refresh: handled by
~/apps/cc/token-keepalive.py— do not re-auth manually unless something is broken.
Example Session
Section titled “Example Session”# Write the body to a temp file (encoding safety for complex HTML)cat > /tmp/body.html <<'EOF'<h1>Test email</h1><p>This is a test from the Gmail API.</p>EOF
# Sendpython3 ~/apps/gmail-notify/send-email.py \ --to ojhurst@gmail.com \ --subject "Gmail API test" \ --html /tmp/body.htmlSafety
Section titled “Safety”- Claude will never send a message to a real person without showing the exact text first and getting explicit approval. This is enforced by rule, not by the script.
- Always draft → present → wait → send. No “I sent this” surprises.
Known Gaps / TODOs
Section titled “Known Gaps / TODOs”- No attachments flag yet. The script sends body-only. Adding
--attach /path/to/file.pdfwould be trivial but has not been needed. - No inline images. HTML
<img>tags with external URLs work, but embeddedcid:inline images do not. - No send-as aliases. Sends from
ojhurst@gmail.comonly. Brand Account / funnel-hoarder sends would need a different token.