Skip to content

Email Management

Under Administration > Email (/v2/admin/email), the email system of calServer v2 is configured. Mail management is fully ported from v1: actions (scheduled bulk mails to recipient groups) with templates that generate reports from the report management as attachments, plus queue and send log.

Email Management

Master switch: pausing outbound mail

The top of the page states whether mail is going out at all — with the button that changes it. Pause sending stops every send immediately, without touching a configuration or disabling an action.

This is the emergency stop for when something goes wrong: an action addressed to the wrong distribution list, a mail server producing bounces, an import that triggered a thousand reminders. Until now that would have meant touching the container or breaking each configuration by hand — neither of which an operator has without a service agreement.

What a paused send does:

  • New mails are not sent. They land in the log with status "not sent" and the reason "sending is switched off in administration". No entry claims a send that never happened.
  • Nothing is caught up. Switching back on does not redeliver the mails suppressed in the meantime; they sit in the log and have to be resent manually if needed.
  • Entries already in the queue stay there and are processed normally once sending is on again.

The state lives in the database and survives restarts and cache:clear. The default is on — an update never switches anyone's mail off.

Changing it requires email_management_edit, seeing it email_management_view.

Sections

Configurations

SMTP configurations (multiple possible, exactly one default):

Setting Description
Transport SMTP, PHP mail() or sendmail
SMTP host / port Mail server (25, 465, 587)
Encryption TLS / STARTTLS / SSL / none
Username / password SMTP authentication
Default Use as default configuration
Sendmail path Path to the sendmail binary (transport sendmail only)

If no configuration is flagged as default, sending uses the oldest configuration (lowest ID, as in V1) — not the alphabetically first one in the list.

Transport inside the container

Sending runs through exactly this configuration — no MAIL_* environment variables required. Two transports need something the API container does not ship, though: sendmail expects the sendmail binary inside the container, and PHP mail() hands over to the deployment's platform transport (MAIL_MAILER; if that is log, nothing is delivered). SMTP is the recommended transport — it works without further prerequisites. Failed attempts appear with the real error message in the log.

Unlike V1, V2 verifies the mail server's TLS certificate. An internal relay with a self-signed certificate that worked under V1 will then fail with a certificate error in the log — MAILER_VERIFY_PEER=false in the server environment restores the old behaviour (applies to the whole installation).

Templates

Templates define sender, subject and HTML body — with placeholders ([FULLNAME], [FIRSTNAME], [LASTNAME], [EMAIL], [FIRM], [DOMAIN], also lowercase) resolved per recipient.

Report attachment (report management): a template can configure a master report as attachment. On send, the report is generated per recipient through the report engine (incl. letterhead overlay) and attached as PDF. The due-date filter (due, overdue, critical 1–3) parameterises the report with the periods from the rules (due_date_period, critical_date_period_1..3).

System templates and action templates

There are two kinds of template, and the difference is not cosmetic:

System templates carry a fixed key (hide_name) and are looked up by the program when a specific event occurs. Their placeholders come from that trigger — a task template gets [TASK_URL], a ticket template [TICKET_ID] — so they are not usable in a mailer action.

Key Trigger Placeholders
task_create Task created [TITLE] [DESCRIPTION] [SUBJECT] [INFO] [CREATOR] [TASK_URL]
task_update Task changed [TITLE] [DESCRIPTION] [SUBJECT] [CHANGES] [UPDATER] [TASK_URL]
reminder_repair Maintenance date passed [TITLE] [SUBJECT] [DESCRIPTION] [CREATOR] [TASK_URL]
location_create Loan entry created (loan receipt) [TITLE] [DESCRIPTION] [SUBJECT] [INFO] [CREATOR] [LOCATION_URL]
location_update Loan entry changed [TITLE] [DESCRIPTION] [SUBJECT] [CHANGES] [UPDATER] [LOCATION_URL]
support_create_ticket Ticket created [TICKET_ID] [TITLE] [DESCRIPTION] [CREATOR] [ASSIGNEE] [PRIORITY]
support_update_ticket Ticket changed [TICKET_ID] [TITLE] [DESCRIPTION] [UPDATER] [ASSIGNEE] [PRIORITY]
support_comment_ticket Ticket commented on [TICKET_ID] [TITLE] [COMMENT] [UPDATER]
password_reset Password reset requested [FULLNAME] [FIRSTNAME] [LASTNAME] [EMAIL] [RESET_URL] [VALID_HOURS] [DOMAIN]

When a system template is missing, the corresponding mail is silently skipped — the notification then looks switched off. php artisan mailer:seed-templates adds the missing ones (see below).

Action templates have no key and are freely selectable in an action or under "Compose mail". Their placeholders come from the recipient expansion: [FULLNAME], [FIRSTNAME], [LASTNAME], [EMAIL], [FIRM], [DOMAIN] — each also lowercase. Shipped are "Kalibrierung fällig", "Kalibrierung überfällig" and "Geräteübersicht"; a report attachment still has to be assigned.

Language variants

System templates ship in two versions: the base row is German, the English one lives under the key {hide_name}.en (name with an "(EN)" suffix). Which one is used is decided by the default language in the general settings — without a variant the base row applies.

Both versions are editable in the template list like any other. The key itself is not: it is the contract with the calling part of the program, and a typo in it would silently switch the notification off. A third language therefore currently needs an entry in the catalogue (MailerTemplateCatalog), not just a click in the UI.

This does not apply to action templates: they have no key and therefore no variant. There you pick the language by picking that language's template in the action. The language field on the action is a label, not a switch.

Actions

Scheduled bulk mails (v1 mailer actions):

Field Meaning
Template / configuration Which template over which SMTP transport
Recipient group The group's users (with per-user opt-out) and the group's customers via the configured customer e-mail field
Start / end Window in which the action is active
Weekdays / months / days of month Crontab-style fine control (comma lists, empty = all)
Send without attachment Send even when no report was generated
Archive attachments Keep generated reports permanently

Row actions: test send to the system address (shield icon) and send to the recipient group now. A duplicate guard prevents more than one successful send per action, recipient and day on automatic runs.

Queue

The queue shows every generated e-mail with its status:

Status Description
Pending Waiting for the next processing run
Sending Currently being sent
Sent Delivered successfully
Failed Delivery failed (with error message)
Not_Send No attachment generated and "send without attachment" disabled

Log

Every send (success and failure) is recorded in the send log (mailer_message) with recipient, subject, error message and record link.

The sign-in mails are in here too — password reset, registration confirmation, welcome mail, each with link_table = user. This is where the most common question gets answered ("I never got a password link").

Processing

The run php artisan mailer:process (scheduler: every 5 minutes) executes due actions and processes the queue in batches — the v2 counterpart of the four v1 crons (Mailer, ExportReport, SendEmailQueue, DeleteReport). Temporary report attachments are deleted after the send; archived ones remain under storage/app/mailer/archive/.

Adding missing templates

As of 5.65 the container start creates whatever is missing. An update therefore brings the factory defaults along by itself, on an existing installation too — and even when the migration run of that same start fails.

Up to 5.64: existing installations got no templates

Before that, the factory defaults were written only by php artisan db:install — the setup run of a fresh installation. Anyone updating via migrate saw a permanent "0 templates" in the template list, and every feature looking up a system template fell back to its hard-coded text.

If the list is still empty after updating to 5.65, the reason is in the startup log (docker logs calserver-api-v2, line Ensuring factory mail templates). If the table itself is missing there, the schema is incomplete — see Operations → Database schema state.

Adding them by hand still works:

docker exec calserver-api-v2 php artisan mailer:seed-templates

The command only creates what is missing — existing templates stay untouched, including the ones carried over from v1 and the ones edited on site. System templates are matched by their key, action templates by their name.

--update-existing additionally resets subject, body and description of existing templates to the factory default, discarding edited texts — hence the confirmation prompt. Name, sender, Cc/Bcc and the attachment configuration are kept even then; those are site setup, not factory defaults.

Permissions

Reading requires email_management_view; changing and manual runs require email_management_edit.