Email sending with SMTP support, validation, and optional async processing via the jobs library. Supports sync, async (future-based), and queued (jobs library) sending modes.
Key namespaces
| Namespace | Purpose |
|---|---|
|
Pure functions: prepare, validate, add headers, summarize |
|
Protocols: |
|
Malli schemas: |
|
SMTP adapter — delegates to |
|
Optional integration with |
Transport layer
boundary-email delegates raw SMTP transport to boundary-external:
boundary-email (application layer) → boundary-external (transport layer)
Email {id, created-at, metadata} → OutboundEmail {to, from, subject, body}
EmailSenderProtocol → ISmtpProvider (javax.mail)
Sending email
(require '[boundary.email.core.email :as email]
'[boundary.email.ports :as ports]
'[boundary.email.shell.adapters.smtp :as smtp])
;; 1. Create sender
(def sender (smtp/create-smtp-sender
{:host "smtp.gmail.com"
:port 587
:username "user@gmail.com"
:password "app-password"
:tls? true}))
;; 2. Prepare email (pure — normalizes :to to vector, adds UUID + timestamp)
(def prepared (email/prepare-email
{:to "alice@example.com"
:from "no-reply@myapp.com"
:subject "Welcome!"
:body "Thanks for signing up!"}))
;; 3. Send
(ports/send-email! sender prepared)
Sending modes
| Mode | When to use |
|---|---|
Sync (default) |
Transactional emails where failure should block the request |
Async ( |
Non-critical emails where a short delay is acceptable |
Queued ( |
High volume or when retry logic is needed |
Testing
clojure -M:test:db/h2 :email