fix(engagement): a trigger-bound template may reference the unsubscribe link
Found building module-uo's sixteen in-universe bodies, which are the first
trigger-bound templates in the system to carry an unsubscribe line of their own.
`emailChannel.deliver` computes an unsubscribe token per recipient and merges it
LAST over the projection, so `{{unsubscribeUrl}}` has always RENDERED correctly.
But `variablesFor` takes a trigger-bound template's variable list from the
trigger's declaration, and a trigger has no business declaring a fact about how
the mail was delivered — so the token was undeclared, and the save-time
undeclared-variable check would have refused the first operator who tried to EDIT
one of those bodies. Rendering right and then refusing the edit is the worst of
both.
Nothing had ever taken this path: core's generic `notify.event` declares
`unsubscribeUrl` in its own seed and is bound to no trigger, so `seedByKey`
supplied it there.
Adds DELIVERY_VARIABLES beside AMBIENT_VARIABLES — declared separately because
they apply to a different set of templates. Ambient facts are about the
deployment and reach every body; delivery facts are about the send and reach the
trigger-bound ones, which is exactly the set that is engagement mail.
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -18,7 +18,7 @@ const templatesDb = require('../model/engagement/engagementTemplates.db')
|
||||
const settings = require('../model/settings/settings.model')
|
||||
const brand = require('../config/brand')
|
||||
const emailBlocks = require('../emailBlocks')
|
||||
const { SEEDS, AMBIENT_VARIABLES, seedByKey } = require('./templateSeeds')
|
||||
const { SEEDS, AMBIENT_VARIABLES, DELIVERY_VARIABLES, seedByKey } = require('./templateSeeds')
|
||||
// The trigger registry lives with the module registries, not here — a trigger is
|
||||
// something a MODULE declares (see engagement/index.js's header).
|
||||
const { eventTrigger } = require('../modules/registries')
|
||||
@@ -84,6 +84,11 @@ function variablesFor(template) {
|
||||
if (template && template.trigger_id) {
|
||||
const declared = eventTrigger(template.trigger_id)
|
||||
if (declared && Array.isArray(declared.variables)) own.push(...declared.variables)
|
||||
// A trigger-bound body is engagement mail, and engagement mail always carries
|
||||
// an unsubscribe the channel computes per recipient. A trigger declares what
|
||||
// HAPPENED and has no business declaring how the mail was sent, so the
|
||||
// delivery facts are added here rather than to every declaration.
|
||||
own.push(...DELIVERY_VARIABLES)
|
||||
} else if (template && template.seed_key) {
|
||||
const seed = seedByKey(template.seed_key)
|
||||
if (seed) own.push(...seed.variables)
|
||||
|
||||
Reference in New Issue
Block a user