ErtisAuth

Mail Hooks

Send templated emails on events.

A mail hook sends a templated email whenever a given event occurs in the membership: a welcome mail on UserCreated, a security notice on UserPasswordChanged, an alert to administrators on RoleUpdated.

Two mail hooks with reserved names also power the activation and password reset flows.

Before you start#

Mails are sent through one of the membership's mail providers (SMTP, SendGrid or Mailchimp Transactional), defined in its mail_providers field. See Memberships.

The mail hook object#

json
{
	"_id": "66f1c0d2a4b5c6d7e8f901b0",
	"name": "Welcome",
	"slug": "welcome",
	"description": "Sent to every new user",
	"event": "UserCreated",
	"status": "active",
	"mailProvider": "company-smtp",
	"fromName": "My Company",
	"fromAddress": "no-reply@example.com",
	"sendToUtilizer": false,
	"recipients": [
		{ "displayName": "{{document.firstname}} {{document.lastname}}", "emailAddress": "{{document.email_address}}" }
	],
	"mailSubject": "Welcome to My Company, {{document.firstname}}!",
	"mailTemplate": "<h1>Welcome, {{document.firstname}}!</h1><p>Your username is <b>{{document.username}}</b>.</p>",
	"membership_id": "66f1c0d2a4b5c6d7e8f90123"
}
FieldRequiredDescription
nameyesDisplay name. User Activation and Reset Password are special.
slugnoDerived from the name when omitted.
descriptionno
eventyesThe event type that triggers the mail.
statusyesactive or passive.
mailProvideryesThe slug of one of the membership's mail providers.
fromName, fromAddressThe sender. Use an address your mail provider is allowed to send from.
sendToUtilizertrue also sends the mail to the user who caused the event (for example the user who changed their password).
recipientsFixed or templated recipients, each { "displayName", "emailAddress" }.
mailSubjectThe subject. May contain placeholders.
mailTemplateThe HTML body with placeholders, or the Mailchimp template name (see below).
variablesMailchimp merge variables, see below.

Recipients are deduplicated by email address.

Templates#

Subjects, bodies and recipients use placeholders in double braces, filled in from the event:

PlaceholderValue
{{event_type}}, {{utilizer_id}}, {{event_time}}, {{membership_id}}Fields of the event
{{document.<field>}}A field of the resource after the change
{{prior.<field>}}A field of the resource before the change

For example, a notice on UserPasswordChanged sent to the user:

json
{
	"name": "Password Changed Notice",
	"event": "UserPasswordChanged",
	"status": "active",
	"mailProvider": "company-smtp",
	"fromName": "My Company Security",
	"fromAddress": "security@example.com",
	"recipients": [ { "displayName": "{{document.firstname}}", "emailAddress": "{{document.email_address}}" } ],
	"mailSubject": "Your password was changed",
	"mailTemplate": "<p>Hi {{document.firstname}},</p><p>The password of your account was changed on {{event_time}}. If this wasn't you, contact us immediately.</p>"
}

Values are inserted safely:

  • in the HTML body, every value is HTML-encoded, so a user who puts markup in their name can't inject it into your mails; the markup of your template itself is kept;
  • in the subject, line breaks in values are replaced with spaces;
  • placeholders that can't be resolved are left as they are.

Mailchimp templates#

With a MailChimp provider, ErtisAuth doesn't render the body itself: it asks Mailchimp Transactional to send one of your stored templates.

  • mailTemplate is the name of the template in Mailchimp.
  • variables are the merge variables passed to it; their values may contain placeholders:
json
"variables": [
	{ "key": "FIRST_NAME", "value": "{{document.firstname}}" },
	{ "key": "USERNAME", "value": "{{document.username}}" }
]

Activation and reset password mails#

Two mail hooks are found by their name and used by the account flows, with their own data:

NameEventUsed byPlaceholders
User ActivationUserCreatedAccount activation{{user.<field>}}, {{activationLink}}
Reset PasswordUserPasswordResetPassword reset{{user.<field>}}, {{resetPasswordLink}}

They must have the exact name, the event above and the status active. They are sent only by their flows, not as ordinary mail hooks of their event.

Delivery#

  • Mails are sent asynchronously, from a background queue; the request that caused the event doesn't wait for them.
  • Each mail records a MailhookMailSent or a MailhookMailFailed event with its recipients (and the error), which is the place to look when a mail doesn't arrive.
  • Mails are not retried.

Endpoints#

All routes are under /memberships/{membershipId}.

MethodRouteDescriptionPermission
GET/mailhooks/{id}Get a mail hookmailhooks.read.{id}
GET/mailhooksList mail hooksmailhooks.read
POST/mailhooks/_queryQuery mail hooksmailhooks.read
POST/mailhooksCreate a mail hookmailhooks.create
PUT/mailhooks/{id}Update a mail hookmailhooks.update.{id}
DELETE/mailhooks/{id}Delete a mail hookmailhooks.delete.{id}
DELETE/mailhooksDelete several mail hooksmailhooks.delete

Create answers 201 Created; 400 ModelValidationError when the name, the mail provider, the status (active / passive) or the event type is missing or invalid, and 409 MailHookAlreadyExists when the slug is taken. Update replaces the mail hook; an update without any change answers 409 IdenticalDocumentError. Delete answers 204 No Content.

Events#

MailhookCreated, MailhookUpdated, MailhookDeleted, and the delivery events MailhookMailSent and MailhookMailFailed. See Events.

Found a mistake in the docs? Open an issue