Marketing · Email campaign builder (wizard, A/B test, scheduling)

Four-step wizard — general info, template design, (optional) B-variant design, summary — that composes an email campaign: subject, audience segment, HTML body with personalisation variables, send window, frequency, optional A/B split, and a test send before publishing.

AreaMarketing
Routesmarketing.emailing.new · marketing.emailing.edit
Centre modulesmarketingMailing
Staff levelsroot · admin · manager · crmmanager · weboperator · content_creator
Modelsemail-bag · email-campaign · email-campaign-template · segment · test-ab
UI labelemail-campaign.new / email-campaign.edit
Coverage5 use cases · 2 happy · 15 failure

Known issues (2)

Missing translations

These keys are used on this screen but do not exist in translations.json, so users see the raw key:

  • email-campaign.insert-variable.placeholder

How it works

Step validation is declarative: stepsInfo gives each step a validateAttrs list and the design steps instead validate the HTML path (designHtmlPaths[stepId]), so isValidModel() only checks what the current step owns. Personalisation uses codeParams (centre name, user code, user email, user name) injectable into the subject and body. HTML bodies are scanned for invalid parameters and for the presence of an unsubscribe link, producing non-blocking warnings (email-campaign.warning-invalid-html-params, email-campaign.warning-unsub-link) plus a hard publish-time error (email-campaign.error-invalid-html-params, which names the offending template). Template import reads an uploaded HTML file (readImportedHtml) for A and B separately. userReachedInfo estimates reach and changes its wording when email validation is on (segment.users_reached.info_with_email_validation). Send quota is surfaced as consumedEmailbagWarningMessage from the centre’s email bag. sendTestEmail on the route validates a comma-separated address list itself and throws if it is not an array of e-mails. Frequency supports single sending plus recurring 15min/30min/hourly/daily/weekly.

Use cases

Why someone opens this (5)

  • Sending a monthly newsletter to a segment with personalised greeting.
  • A/B testing two subject lines on a percentage split before the main send.
  • Scheduling a recurring automated email (e.g. a weekly digest).
  • Sending a test to colleagues for sign-off before scheduling.
  • Re-engaging only those who opened or clicked a previous send (A/B test shipping method).

Path map

flowchart LR
    F(["Email campaign builder wizard, A/B test, schedu…"]):::feat
    F --> H1["Single-send campaign scheduled"]:::ok
    F --> H2["A/B test campaign"]:::ok
    F -.-> X1["Name or subject blank"]:::bad
    F -.-> X2["No segment"]:::bad
    F -.-> X3["Empty template"]:::bad
    F -.-> X4["Start date in the past"]:::bad
    F -.-> X5["End before start"]:::bad
    F -.-> X6["Dates missing"]:::bad
    F -.-> X7["A/B split invalid"]:::bad
    F -.-> X8["A/B shipping method missing"]:::bad
    F -.-> X9["B subject missing"]:::bad
    F -.-> X10["Invalid HTML parameters at publish"]:::bad
    F -.-> X11["Missing unsubscribe link"]:::bad
    F -.-> X12["Email bag exhausted"]:::bad
    F -.-> X13["Test send with a bad address list"]:::bad
    F -.-> X14["Duplicate campaign posting twice"]:::bad
    F -.-> X15["Raw translation key on screen"]:::bad
    classDef feat fill:#b0432c,stroke:#b0432c,color:#ffffff,font-weight:bold
    classDef ok fill:#e3f1ea,stroke:#0d6b42,color:#0d4a2e
    classDef bad fill:#f7e6e2,stroke:#9a2d1c,color:#6e1f13

Happy paths

Single-send campaign scheduled

  1. Step 1: name, subject, segment and the start/end datetime window are set; frequency is single sending.
  2. Step 2: an HTML template is imported or composed; personalisation variables are inserted and the unsubscribe link check passes.
  3. Step 4 summary shows the estimated reach and the remaining email-bag quota.
  4. A test email is sent and approved.
  5. sendCampaign publishes it and the campaign moves to scheduled.

A/B test campaign

  1. toggleABTest enables the variant; subject B, a B template and a quote (percentage split) are entered.
  2. At least one shipping method (opened or clicked) is selected.
  3. The quote validates as an integer between 0.01 and 99.99.
  4. Step 3 designs template B; the campaign is published with the split.

Failure paths

QA checklist

Tick these off while regression-testing this feature. The boxes are plain Markdown, so progress is visible in git diffs.

  • ✅ Single-send campaign scheduled
  • ✅ A/B test campaign
  • ⛔ Name or subject blank
  • ⛔ No segment
  • ⛔ Empty template
  • ⛔ Start date in the past
  • ⛔ End before start
  • ⛔ Dates missing
  • ⛔ A/B split invalid
  • ⛔ A/B shipping method missing
  • ⛔ B subject missing
  • ⛔ Invalid HTML parameters at publish
  • ⛔ Missing unsubscribe link
  • ⛔ Email bag exhausted
  • ⛔ Test send with a bad address list
  • ⛔ Duplicate campaign posting twice
  • ⛔ Raw translation key on screen

Implementation


Generated from doc/feature-inventory.json · id marketing-email-campaign-builder · commit 276788ca6