Architecture: ActionMailer Setup (Spike #47)
Architecture: ActionMailer Setup (Spike #47)
Purpose
Determine the right pattern for sending emails from westside-basketball. The spike evaluates three approaches and delivers
docs/email-sending.md documenting the chosen path.Existing State
app/services/gmail_client.rb— production-proven Gmail OAuth sender wrappingGoogle::Apis::GmailV1::GmailService. Sends viasend_user_message. Already works.app/mailers/application_mailer.rb— exists with defaults (from: "from@example.com"). No concrete mailers yet.Gemfileincludesgoogle-apis-gmail_v1- OAuth tokens already in DB
- PR #17 (closed, not merged) — prior attempt at ActionMailer + Gmail API delivery method
- Issue #14 — detailed spec for ActionMailer refactor with
GmailApiDeliveryMethod westside-emailsrepo — existing MJML email templates (branded, compiled to HTML)
Three Options
Option A: Continue with GmailClient directly
Keep calling
GmailClient from service objects. No ActionMailer.- Pro: Already works. Zero migration effort.
- Pro: Full Gmail API control (labels, threading, message IDs).
- Con: No Rails email conventions — no
/rails/mailers/previews, noActionMailer::TestHelper, no layout wrapping. - Con: Templates managed manually outside Rails view layer.
Option B: ActionMailer + SMTP
Use ActionMailer with standard SMTP delivery. Google supports SMTP with OAuth2 via XOAUTH2 SASL.
- Pro: Standard Rails pattern — maximum ecosystem compatibility.
- Pro: ActionMailer gives previews, test helpers, layouts, multipart MIME for free.
- Pro: Works with ERB views in
app/views/— standard Rails template pipeline. - Con: Different auth mechanism than existing
GmailClient— SMTP+XOAUTH2 vs REST API. - Con: Less control than Gmail API (no labels, threading, read receipts).
- Con: Need to evaluate whether existing OAuth tokens work for SMTP or need different scopes.
Option C: ActionMailer + Gmail API delivery method
Write a custom
ActionMailer::DeliveryMethod that wraps GmailClient. This is what issue #14 and PR #17 attempted.- Pro: Rails conventions (previews, test helpers, layouts) AND Gmail API control.
- Pro: Reuses existing
GmailClientOAuth logic — no new auth setup. - Con: Custom delivery method is non-standard — more code to maintain.
- Con: PR #17 tried this and didn't land — spike should investigate why.
Template Strategy (Orthogonal)
Regardless of delivery method, the spike must decide how to author email HTML:
- ERB views — Rails default. Templates in
app/views/. Simple but writing table-based email HTML by hand is painful. - MJML — markup language that compiles to email-safe table-based HTML.
westside-emailsrepo already has branded MJML templates. Can integrate viamjml-railsgem (compiles at render time) or pre-compile during docker build (current basketball-api pattern). - Port compiled HTML — take the already-compiled HTML from
westside-emailsand drop into ERB with{{placeholder}}→<%= %>conversion. One-time effort, no MJML dependency at runtime.
Decision Space
Spike Deliverables
docs/email-sending.md— documents chosen approach with rationaleApplicationMailerupdated with correctdefault from:(if ActionMailer chosen)- Production/development email config wired up (or documented what secrets are needed)
- #48 and #49 updated with refined scope based on findings
Time-box
2 hours / 1 session. If expired: close spike, document findings, escalate.
Related
arch-email— current email system architecture (basketball-api / Python)sop-email-send— email send approval workflowsop-gmail-oauth— OAuth token management SOParch-domain-westside-basketball— domain model (EmailLog entity)- Forgejo: westside-basketball #47, #14, PR #17
westside-emailsrepo — existing MJML branded templates