Rivet Email
A simple to use templated email system as part of the Rivets Framework. Key things to using this:
Backend— this is what we use for the actual heavy lifting. For now, using Bamboo mailer.Mailer— the entrypoint/API used in other apps- templates — templates to handle messages
- config — where you specify the Mailer module
- data structs — uses Rivet.Ident.Email and Rivet.Ident.User, but anything can be subbed in
Usage steps (see examples that follow for more detail):
- Configure Rivet Email (see
config/config.exsfor an example of supported configurations). - Create Mailer and Email modules as well as one or more templates (see
lib/email/examples). - Send email, where
recipscan be a single or list ofuser_model,email_modelor an ID for auser_model:
MyEmail.send(recips, MyEmailTemplate)
Rivet Mailer and Email modules
defmodule MyEmailBackend do
use Rivet.Email.Mailer, otp_app: :app_name_here
end
defmodule MyEmail do
use Rivet.Email,
otp_app: :app_name_here,
backend: MyEmailBackend,
user_model: Ident.User, # optional; shown with default
email_model: Ident.Email # optional; shown with default
end
Config:
config :rivet_email,
enabled: true,
mailer: MyEmail
Template
The template defines a generate() function, which accepts the recipient as a UserEmailStruct, and attributes as a map. Attributes come from the configuration
defmodule Myapp.Email.AuthErrorTemplate do
@behaviour Rivet.Email.Template
@impl Rivet.Email.Template
def generate(recip, attrs) do
{:ok, "failed", "<p>Sorry #{recip.user.name}<p>This didn't work"}
end
# create a "send" function (optional), and then call it as:
# AuthErrorTemplate.send(recipients)
def send(recip) do
# gather attributes and do things here
# then send:
Rivet.Email.mailer().send(recip, __MODULE__, attrib1: value, ...)
end
end
Rivet User and Email structs
The included structures should at least support:
%UserStruct{
id: String.t(),
emails: list(UserEmailStruct.t()),
}
%UserEmailStruct{
id: String.t(),
address: String.t()
user: UserStruct.t()
}
And, each structure should have a one/1 function that accepts an id: ID
keyword pair, as well as a preload/2 function that accepts the relevant
struct and a list of atoms for fields to preload (per Ecto's preload).