Skip to content

Email templates

Every email Damvia sends is plain text rendered from a template with LiquidJS. The templates live in one JSON document, either the file server/mailconfig.json or the MAILCONFIG environment variable holding the same JSON encoded in base64.

{
"email-verification": {
"from": "\"Acme DAM\" <[email protected]>",
"subject": "Please Verify Your Email Address",
"body": "Hello,\n\nPlease verify your email address by clicking the link below:\n\n{{ url }}"
},
"login": { "from": "...", "subject": "...", "body": "..." }
}

Each key is a template name; each template has from, subject and body. subject and body are Liquid templates; from is used as is. Bodies are plain text (\n for new lines), not HTML. All seven keys must be present: the sender reads mailConfig()[name] without a fallback and would fail the job otherwise.

KeySent whenRecipientVariables
email-verificationA user signs up, or asks to resend the verificationThe userurl: APP_URL/?verificationCode=...
loginLogin in passwordless mode, or with the magic-link optionThe userurl: APP_URL/login?token=... (a 180-day session token)
reset-password“Forgot password”The userurl: APP_URL/password-update?email=...&token=...
request-approvalA user verifies their email while still unapprovedEvery admin and manager of the user’s region, in one messagerequester.name; url: APP_URL/admin/users/{id}/edit. requester.name is also available in subject. The client defines no /admin/users/{id}/edit route today, so the link opens the app but not the user directly; approvers use /admin/users.
user-approvedAn admin or manager approves the userThe useruser.name; url: APP_URL/login?token=...
download-readyAn “email” download’s archive is builtThe requesting userlink: a presigned S3 URL to the archive (not the /v1/downloads/ link)
invitationA guest is invited to a collectionThe invited emailurl: APP_URL/collections/{id}?dam_token=... (logs the guest in)

Only the variables listed are available; any other {{ name }} renders empty.

  1. If MAILCONFIG is set, it is base64-decoded and JSON-parsed synchronously at startup. A decoding error crashes the process immediately.
  2. Otherwise the server reads mailconfig.json from the parent directory of the compiled env.js, which is server/ both in development (src/env.ts) and in the Docker image (dist/env.js). If the read fails, it logs Failed to read mailconfig.json and exits.

To produce the variable from a file:

Terminal window
base64 -i mailconfig.json | tr -d '\n'

On Linux, base64 -w0 mailconfig.json. Paste the result as MAILCONFIG=....

Templates are read once at startup. Restart the server after changing the file or the variable. Because emails are sent by the worker, the process that must restart is the one with ENABLE_WORKER=true.

from should be an address your SMTP provider is allowed to send for; with Postmark, a verified sender signature or domain. The server adds X-PM-Message-Stream: outbound to every message so Postmark routes it through the transactional stream. See SMTP.