Notifications¶
Orchestra reaches people at points you define while modeling a workflow. You decide where to notify, who to notify, and what to send; a delivery channel decides how it is sent and in which medium. This page covers the modeling side. For the channels (email, Easy Email, SMS, a custom subscriber) and the event they consume, see Notification delivery.
Notifications never ride the audit event: the audit log is a
separate concern (OrchestraAuditableEvent), so recording history and reaching
people stay apart.
From the modeler's view¶
Defining notifications is part of building the workflow, not an afterthought. At each point where the workflow should reach someone, you decide three things in the model:
- Where to notify: on a task assignment, when a branch arrives at an interactive wait (notify on arrival), or at an explicit Notify node you place on a branch.
- Who to notify: an audience, the same plugin type a task uses to say who it reaches, from named users to "the user held in this variable" to a fixed external email address.
- What to send: a notification type (a template id). The wording lives in the channel, so the model stays channel-neutral and every recipient is rendered in their own language.
Everything below is how the where and who are expressed while modeling; the what and its rendering belong to delivery.
How a notification flows¶
flowchart LR
subgraph M["chosen while modeling"]
P1[task assigned<br/>or reassigned]
P2[branch parks on<br/>an interactive wait]
P3[Notify node<br/>on a branch]
end
P1 --> D["*_notification module<br/>resolves the audience"]
P2 --> D
P3 --> D
D --> EV["OrchestraNotificationEvent<br/>type + params + recipients"]
EV --> CH{delivery channel}
CH --> MAIL[orchestra_mail]
CH --> EE[Easy Email]
CH --> ECA[ECA model]
CH --> SMS[SMS / chat / push]
The where is a dispatch point, the who resolves to Recipient objects,
and the what is the type a channel templates on. The model never names a
channel, so enabling or swapping one (the right half of the diagram) changes
delivery without touching the workflow. That half is
Notification delivery.
Where: the notification points¶
Three points can notify, each provided by a *_notification submodule you
enable for the points you want:
| Submodule | Notification point | Type |
|---|---|---|
orchestra_inbox_notification |
a task is assigned / reassigned (the inbox WorkItemEvent), or times out (TaskTimedOutEvent) |
task_assigned, task_reminder |
orchestra_interaction_notification |
a branch parks on a bearer-interaction node with a "Notify on arrival" audience (TokenParkedEvent) |
interaction_link |
orchestra_notification (the Notify node) |
a token traverses a Notify node | the node's configured type (default generic) |
Each resolves its audience to recipients (audience plugins, shared through the
kernel NotificationAudience resolver, so "Users by variable" resolves the
original poster) and dispatches; none knows how the message is sent.
Who gets notified¶
Audiences are Audience plugins, the same plugin type a task uses to say who it
reaches (a staffing audience additionally implements AssignmentInterface):
| Audience | Notifies by default | Resolves to |
|---|---|---|
| Users | yes | the named users |
| Users by variable | yes | the user(s) whose uid is in a process variable |
| Roles | no (opt in) | the members of the roles |
| Roles by variable | no (opt in) | the members of the role(s) in a variable |
| Email address | yes | a fixed email address, with no Drupal account |
| Email by variable | yes | the email address(es) held in a process variable |
The last two are notify-only audiences: they resolve to an account-less recipient (an external address), so they never appear in the task assignment editor and cannot staff a task; they exist for the Notify node and on-arrival notifications.
For tasks, the per-assignment Notify this audience flag decides who is
mailed, so pooling a task to a broad role never mails its members by surprise; a
reassignment always notifies the new assignee. Whoever is
covering for a resolved recipient is added to the
audience, and that recipient drops out only if their own delegations
unanimously ask to be left alone, the one case where an audience narrows rather
than widens. For a Notify node, every
recipient row is notified (you placed the node deliberately). The authenticated
and anonymous pseudo-roles match nobody, so "notify all authenticated users"
never mass-mails the site.
The Notify node (visible, conditional)¶
A Notify node is a workflow node, so it shows on the chart and the flow routes to it conditionally: send the "approved" branch through a Notify node to mail people only then. It renders nothing itself, it resolves its Recipients (the audience-row editor, the same widget tasks use) and dispatches the neutral event with its notification type, carrying the process context, then advances immediately. The message content lives in the channel (a mail template, or an Easy Email template via ECA), not on the node.
Each recipient row also has a Delivery setting, To (default), Cc or
Bcc. It keeps the full audience-plugin range (users, roles, by-variable,
custom rules) and only tags which mail header the resolved people land in, so
you can say "poster in To, validator in Cc" without giving up the powerful
audience mechanism. It is a hint the channel interprets: the mail channel maps
it to headers (see Notification delivery),
and a channel with no such notion (SMS, chat) ignores it and reaches everyone.
To address the person who completed a task (a validator), set Store
completer in variable on the task node; the completer's uid is written there
on completion (and recorded as the audit actor), so a later Notify node names
them with "Users by variable". The submission-validation example closes with a
Notify node that mails both the original poster and the validator once the
request is processed.
Where a notification is rendered¶
A process is started in one place and advanced in another: someone submits on a public site, an operator acts from a back office, cron and queue workers run with no request at all. Anything a notification is built from would otherwise resolve against whichever request happens to be running, so links point at the wrong place and the site name, the mail settings and the theme are the wrong ones.
Orchestra therefore names two places, and they are not the same:
- The workspace, where people do the work. A task notification links to the inbox, and the inbox is the same place for everyone, whoever caused the task. A parked interaction step is work too, so its link goes there as well.
- The origin, where the process was started. A Notify node is author-composed content, normally addressed to whoever started the run, so it is rendered where they were. Each instance records its origin when it starts, since by the time the message goes out the run may be advancing anywhere; a subprocess belongs where its parent does. A run started with nothing to record, by cron or the command line, falls back to where its tenant receives people.
Orchestra itself knows nothing about sites or domains. The origin is an opaque
string and the shipped implementation of orchestra.notification_context
changes nothing at all, so a site with a single front end pays nothing for
this. Install Orchestra Domain on a Domain Access site to give
both places meaning. Each tenant says which domains it lives on, on its own
Domains form beside its retention settings: its public domain, where it
receives people, and its workspace domain, where its operators work. It is
said on the tenant rather than on the domain records because it is not the
inverse of the domain-to-tenant binding: several domains can point at one
tenant, and a domain can serve several tenants. A tenant naming neither
inherits the default tenant's, so a single-tenant site fills in one form.
Outbound only
This is for output built outside the request it belongs to. Never wrap the rendering of a page being served: on a Domain site the negotiated domain also drives routing and language negotiation for that page.