{site} and {site_name} everywhere; a state mail adds {self_link} (the
submitter's own page, when their record's state allows a move there),
{desk_link} and {link}, which picks by who the mail is to. gullberg's
{link} mails went out blank until now. Documented in docs/mail.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MznPTC31w5mSUK4XMehcpi
60 lines
2.9 KiB
Markdown
60 lines
2.9 KiB
Markdown
# Mail
|
|
|
|
Portal writes every mail itself and hands it to gdo to deliver
|
|
(`portal.mail.send`); a reply comes back as a note beside the record
|
|
(`portal.mail.received`). A mail is a subject and a markdown body with
|
|
`{placeholders}`, sent as text with an HTML alternative. The kinds of
|
|
mail are the ones content declares on a state (see
|
|
[State machines](state-machines.md#mail)), the invite and its
|
|
rewording (`invite: { group, mail }`, `mail.invite` in site.yaml), the
|
|
note to a person named responsible for a question, and the answers to
|
|
a suggested change.
|
|
|
|
## Variables
|
|
|
|
A placeholder is `{` letters, digits, `_`, `-` or `.` `}`. One that
|
|
names nothing renders as nothing; a brace that opens no name stays a
|
|
brace. The variables come in layers, so a template written for one
|
|
kind of mail reads the same in another.
|
|
|
|
**On every mail**
|
|
|
|
| | |
|
|
|---|---|
|
|
| `{site}` | the instance's public URL, no trailing slash |
|
|
| `{site_name}` | site.yaml's `title` |
|
|
|
|
**On a mail about a record** (every state mail)
|
|
|
|
| | |
|
|
|---|---|
|
|
| `{field}` | any field of the record, as the form sent it |
|
|
| `{chain}` | the record's id |
|
|
| `{email}` | the record's `email` field, trimmed |
|
|
| `{bucket}`, `{state}` | where it is and the state it just entered |
|
|
| `{notice.field}` | a field of the record this one belongs to, through its `type: record` field `notice` |
|
|
| `{self_link}` | the record's own page for the person it belongs to: a page offering a self-service move (`self_transition`) on the bucket from the state the record is in, with the `?chain=&email=` that lets them act without signing in. Empty when there is no such page or no address |
|
|
| `{desk_link}` | the desk that moves the record: the page whose list over the bucket has `transitions`, else one that reads it. Empty when no page reads the bucket |
|
|
| `{link}` | where this reader acts: `{self_link}` in a mail `to: submitter`, `{desk_link}` in one to anyone else, and `{site}` when that link is empty |
|
|
|
|
`{link}` is the one to reach for. "Se meldingen og avtal befaring:
|
|
{link}" sent to the caretaker opens the desk the report is on; "Feilen
|
|
du meldte om er utbedret. {link}" sent to the tenant opens their own
|
|
case where they can still act on it, or the site when there is
|
|
nothing left for them to do.
|
|
|
|
**On an invite and the note to someone responsible**, beside every
|
|
field of the invite's form: `{name}`, `{username}`, `{email}`,
|
|
`{group}` (invite), `{questions}` (responsible), `{expires}`, and
|
|
`{link}`, which here is the one-time sign-in link.
|
|
|
|
## What the lint holds a mail to
|
|
|
|
A state mail that sends from a state no record reaches warns; one that
|
|
names a field no form recording into the bucket collects fails, since
|
|
it would go out with a blank where the field should be. The lint
|
|
knows every variable above, so `{link}` and the rest are never
|
|
flagged. `to: submitter` requires a required `email` on every form
|
|
filling the bucket, and `to: "{notice.email}"` requires the `notice`
|
|
field.
|