Skip to content

Send a Gmail

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.

  • 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.
Terminal window
python3 ~/apps/gmail-notify/send-email.py \
--to recipient@example.com \
--subject "Your subject here" \
--html /tmp/body.html

Or plaintext:

Terminal window
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.

RequirementWhere
Gmail OAuth token~/apps/gmail-notify/token.json (scope: gmail.send)
Python google-auth, google-api-python-clientinstalled in the gmail-notify repo venv
The HTML body in a file (not inline)encoding safety — use /tmp/body.html
  • Script: ~/apps/gmail-notify/send-email.py
  • Related scripts in the same repo:
    • ath-report.py — weekly analytics email for All Things Handy
    • ath-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.
Terminal window
# 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
# Send
python3 ~/apps/gmail-notify/send-email.py \
--to ojhurst@gmail.com \
--subject "Gmail API test" \
--html /tmp/body.html
  • 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.
  • No attachments flag yet. The script sends body-only. Adding --attach /path/to/file.pdf would be trivial but has not been needed.
  • No inline images. HTML <img> tags with external URLs work, but embedded cid: inline images do not.
  • No send-as aliases. Sends from ojhurst@gmail.com only. Brand Account / funnel-hoarder sends would need a different token.