Skip to content

feat(message): unify bulk template variables onto the shared {{name}} renderer (#69) - #411

Merged
rmyndharis merged 3 commits into
mainfrom
feat/unify-template-variable-syntax
Jun 22, 2026
Merged

feat(message): unify bulk template variables onto the shared {{name}} renderer (#69)#411
rmyndharis merged 3 commits into
mainfrom
feat/unify-template-variable-syntax

Conversation

@rmyndharis

Copy link
Copy Markdown
Owner

Closes #69.

Problem

The gateway had two placeholder conventions for variable substitution:

  • Message templates (send-template, stored templates) use double-brace {{name}} via the shared renderTemplate helper.
  • Bulk send (send-bulk, messages[].variables) used a separate single-brace {name} renderer inside bulk-message.service.ts.

So the same idea — "substitute a variable" — needed different syntax depending on the endpoint, and {{name}} in bulk content was silently mangled to {value} by the single-brace regex.

Fix

Route bulk content through the shared renderTemplate, extended to accept both conventions via one ordered-alternation regex:

/\{\{\s*([\w.-]+)\s*\}\}|\{(\w+)\}/g

The double-brace branch is tried first at each position, so {{name}} is consumed as a unit and the legacy single-brace branch never sees its interior (no {{name}}{value} mangling). The legacy branch keeps the historical {name} shape exactly (word chars, no whitespace), so existing single-brace bulk content renders bit-for-bit as before.

  • {{name}} is now the canonical form, consistent across the gateway and documented.
  • {name} is deprecated but still substituted for backward compatibility.

Tests

  • New template-render.spec.ts: both syntaxes, mixed strings, the {{name}}-not-mangled disambiguation, missing-key-left-literal, whitespace, dotted/dashed keys, empty-string value, non-placeholder braces.
  • New bulk tests: canonical {{name}} substitutes; legacy {name} still works.

Notes

  • Updated the API spec bulk examples to {{name}} + a deprecation note on messages[].variables.
  • One minor behavior refinement: an explicitly-provided empty-string variable now substitutes to '' (the old single-brace renderer treated '' as "missing" and left the placeholder literal). The shared hasOwnProperty semantics are the more correct behavior.

Full suite: 1096 passed / 96 suites; build + lint clean.

… renderer (#69)

Bulk send (send-bulk) substituted messages[].variables with a single-brace
{name} convention, inconsistent with the {{name}} used by message templates and
everywhere else in the gateway. Route bulk content through the shared
renderTemplate helper, extended to accept both conventions via ordered
alternation: the double-brace branch is tried first, so {{name}} is consumed as
a unit and the legacy single-brace branch can't mangle it to {value}. Existing
{name} content renders bit-for-bit as before; {{name}} is now the canonical,
documented form and {name} is deprecated.
@rmyndharis
rmyndharis merged commit 982575e into main Jun 22, 2026
5 checks passed
@rmyndharis
rmyndharis deleted the feat/unify-template-variable-syntax branch June 22, 2026 03:56
CaldeDaniele pushed a commit to CaldeDaniele/OpenWA that referenced this pull request Jun 22, 2026
* commit '61582a487ca0759b049df0f667e27eb7196b0d32': (244 commits)
  fix(hooks): emit the message:ack hook (declared but never fired) (rmyndharis#427)
  feat: plugin platform — sandboxed plugins + dashboard install/uninstall (v0.6.0) (rmyndharis#426)
  test(security): verify undici honors the SSRF connect.lookup pin (real connection) (rmyndharis#425)
  chore(deps-dev): bump @types/node from 25.9.3 to 26.0.0 (rmyndharis#423)
  chore(deps): bump undici from 6.27.0 to 8.5.0 (rmyndharis#422)
  chore(deps-dev): bump @types/node from 25.9.3 to 26.0.0 in /dashboard (rmyndharis#420)
  chore(deps): bump the minor-and-patch group in /dashboard with 3 updates (rmyndharis#419)
  chore(deps): bump the minor-and-patch group with 10 updates (rmyndharis#421)
  fix(dashboard): keep the appearance popover inside the sidebar (rmyndharis#424)
  test(e2e): isolate the auth/audit (main) DB too, so e2e api-keys don't pollute the dev DB (rmyndharis#418)
  docs(changelog): log the plugin action/state color fix under [Unreleased]
  fix(dashboard): distinguish plugin action buttons from passive state (rmyndharis#417)
  test(e2e): isolate the e2e data DB so suites don't pollute the dev database (rmyndharis#416)
  chore(release): v0.5.1 (rmyndharis#413)
  feat(plugins): enforce declared capability permissions at the boundary (rmyndharis#412)
  feat(message): unify bulk template variables onto the shared {{name}} renderer (rmyndharis#69) (rmyndharis#411)
  fix(session): ignore engine callbacks from a superseded or torn-down engine (rmyndharis#410)
  ci(release): block a mis-tagged or under-documented release at the gate (rmyndharis#408)
  fix(docs): source version badges + Swagger from package.json and guard drift in CI (rmyndharis#407)
  chore(release): v0.5.0 (rmyndharis#406)
  ...

# Conflicts:
#	dashboard/Dockerfile
#	dashboard/Dockerfile.traefik
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

message template support

1 participant