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#
{
"_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"
}| Field | Required | Description |
|---|---|---|
name | yes | Display name. User Activation and Reset Password are special. |
slug | no | Derived from the name when omitted. |
description | no | |
event | yes | The event type that triggers the mail. |
status | yes | active or passive. |
mailProvider | yes | The slug of one of the membership's mail providers. |
fromName, fromAddress | The sender. Use an address your mail provider is allowed to send from. | |
sendToUtilizer | true also sends the mail to the user who caused the event (for example the user who changed their password). | |
recipients | Fixed or templated recipients, each { "displayName", "emailAddress" }. | |
mailSubject | The subject. May contain placeholders. | |
mailTemplate | The HTML body with placeholders, or the Mailchimp template name (see below). | |
variables | Mailchimp 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:
| Placeholder | Value |
|---|---|
{{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:
{
"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.
mailTemplateis the name of the template in Mailchimp.variablesare the merge variables passed to it; their values may contain placeholders:
"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:
| Name | Event | Used by | Placeholders |
|---|---|---|---|
User Activation | UserCreated | Account activation | {{user.<field>}}, {{activationLink}} |
Reset Password | UserPasswordReset | Password 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
MailhookMailSentor aMailhookMailFailedevent 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}.
| Method | Route | Description | Permission |
|---|---|---|---|
GET | /mailhooks/{id} | Get a mail hook | mailhooks.read.{id} |
GET | /mailhooks | List mail hooks | mailhooks.read |
POST | /mailhooks/_query | Query mail hooks | mailhooks.read |
POST | /mailhooks | Create a mail hook | mailhooks.create |
PUT | /mailhooks/{id} | Update a mail hook | mailhooks.update.{id} |
DELETE | /mailhooks/{id} | Delete a mail hook | mailhooks.delete.{id} |
DELETE | /mailhooks | Delete several mail hooks | mailhooks.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