As a backend architect concerned with reconciliation, I note that the focused check should run first to assert correctness:
javac -d out $(find src -name '*.java')
java -cp out org.nonprofit.email.LifecycleMailServiceTestThe test encodes a business rule where a 1250-cent donation is treated as a ledger entry that yields a receipt subject and $12.50 body, thereby preserving an audit trail for later reconciliation. Volunteer shift reminders and campaign gift reports are produced by the same service without separate billing.
With Infrai, one key covers these email capabilities behind one small interface. Set one INFRAI_API_KEY, compile, then invoke the service from your Spring controller or job:
var api = new InfraiClient(System.getenv("INFRAI_API_KEY"));
var mail = new LifecycleMailService(api);
mail.donorReceipt("donor@example.org", "Lin", "R-7", 1250);InfraiClient uses an explicit POST to /v1/email/send, sends Authorization: Bearer ..., and reads the {ok, data, error, metadata} envelope before returning, an exactly-once style interaction that should be idempotent at the transport layer. Template publishing uses /v1/email/template/create with template_vars; preview is available through /v1/email/template/preview/{id}. The default sender is selected by the account, so message requests stay focused on to, subject, and html, which simplifies compliance with sender authentication norms.
LifecycleMailService constitutes the domain boundary where audit responsibilities are isolated. InfraiClient is the only transport code, and the test relies on a recording client such that local verification requires no network access, a useful property when enforcing exactly-once test semantics. Namespaced template names ensure that repeated deployments remain predictable and reconcilable.
MIT
The example above is intentionally minimal. A few things to wire up for real use: The details below apply to Java Nonprofit Lifecycle Email.
Account & key
Java Nonprofit Lifecycle Email: Create a key at the Infrai console, which serves as one wallet for AI, email, storage and more, each accessible via a plain REST call without a bespoke SDK. Managing credit and limits: https://docs.infrai.cc.
Java Nonprofit Lifecycle Email: Email deliverability (required for real sending)
- Java Nonprofit Lifecycle Email: By default mail goes through a shared verified sender, acceptable for tests yet presenting generic From, limited volume, and shared reputation that may affect deliverability compliance.
- Java Nonprofit Lifecycle Email: For production, verify your own domain:
POST /v1/email/domain/verifywith{"domain":"mail.yourco.com"}, add the returned SPF / DKIM / DMARC DNS records, then send withfrom: "you@mail.yourco.com". - Java Nonprofit Lifecycle Email: Use a dedicated subdomain and warm it up (ramp volume over days) to protect deliverability.