Ir al contenido principal
Petanque Life

Newsletter Engine (super-premium, multi-list, multi-tenant)

F19.17 23 funcionalidades Entregado

En resumen

The newsletter engine is a fully owned, super-premium marketing-email platform — multi-list, multi-tenant, MJML templates, visual segment builder, drip automations, A/B testing with statistical winner selection, per-recipient send-time optimisation, Gemini-powered AI assist, GDPR-strict double opt-in and Litmus cross-client previews — replacing Mailchimp, ConvertKit and Customer.io without losing a single feature.

Cómo funciona

Petanque Life owns its email channel rather than renting it. An EmailDistributor abstraction (Mailjet primary, ACS failover, Null in dev) handles deliverability, while every other concern — subscribers, lists, campaigns, opens, clicks, segments, preference centre, automations, suppressions — lives in the platform's own MongoDB. Lists are scoped platform-wide or per tenant.

Subscribers move through pending → active → unsubscribed/bounced/complained/suppressed. Templates are MJML source plus a rendered HTML cache. Campaigns follow draft → scheduled → sending → sent.

Events live for 90 days under a TTL index. Double opt-in uses HMAC-SHA256 signed, purpose-bound tokens (confirm/prefs/unsub, TTL 14/30/90 days). Public endpoints cover subscribe (Turnstile + honeypot + 5/IP/h rate-limit), confirm, preferences, unsubscribe and RFC 8058 one-click list-unsubscribe, plus tracking pixels and click-redirects.

Sys-CRUD covers lists, subscribers, CSV import with attested consent proof, GDPR deletion, MJML editor, visual segment builder, campaign wizard, automations, suppressions and deliverability. A/B testing uses pooled two-proportion z-test with Wilson confidence intervals; a winner-selection job picks the winner once significance is reached. Send-time optimisation builds an engagement_profile per subscriber (best_hour_utc, best_weekday) refreshed daily; the dispatcher schedules each recipient inside their optimal 24h window.

Drip automations use a react-flow visual builder with preset onboarding, re-engagement and win-back flows. Gemini 2.5 Pro powers an AI assist (subject lines, content polish, 5-persona preview) under a 50 req/operator/24h quota with prompt and response hashes audit-logged. Heatmaps aggregate click coordinates per campaign; cohorts compute engagement scores per subscriber and flag at-risk subscribers for re-engagement.

Litmus runs cross-client previews and spam-score checks, blocking schedule when spam score > 5. The campaign dispatcher runs every minute, throttles to throttle_per_hour, renders MJML, merges variables, rewrites links, injects the open pixel, appends the compliance footer and sets List-Unsubscribe headers. The distributor webhook verifies HMAC, dedupes on provider_event_id, suppresses on hard bounce, escalates after 5 consecutive soft bounces, and suppresses + flags on complaints.

Twelve premium templates ship out of the box. Embeddable signup forms exist in both Astro and Next.js with prop-driven layouts and 4-language i18n. Compliance is non-negotiable: consent proof per subscribe, CAN-SPAM physical address auto-injected, full audit trail, 3-year post-unsub retention.

A deliverability dashboard auto-halts sends when bounce > 2% or complaint > 0.1%.

Capacidades clave

  • EmailDistributor abstraction (Mailjet primary, ACS failover, Null dev) — provider-agnostic delivery
  • HMAC-signed double opt-in with purpose-bound tokens and RFC 8058 one-click unsubscribe
  • Visual segment builder and react-flow drip automations (onboarding, re-engagement, win-back)
  • A/B testing with z-test and Wilson intervals; per-subscriber send-time optimisation
  • Gemini-powered AI assist for subject lines, content polish and 5-persona previews
  • Cross-client preview and spam-score check via Litmus, blocking sends above threshold
  • Compliance baked in: consent proof, CAN-SPAM footer, audit trail, deliverability auto-halt

En la práctica

A marketer drafts a federation announcement campaign in the sys console. She picks the 'federation_update' premium template, edits MJML in the visual editor, and uses the AI assist to generate four subject-line variants — picks two for an A/B split. She drags a segment in the visual builder ('country in [FR, BE, CH] AND role = federation_admin AND active in last 90 days'), sees 1 247 recipients live.

She enables send-time optimisation, schedules for tomorrow morning, runs a Litmus preview (spam score 1.4, all clients render clean). The dispatcher fans out across the day inside each subscriber's optimal window. The winner-selection job picks variant B at 04:00 the next morning and sends it to the remaining 80% pool — open rate 38%, click rate 7%, complaints 0.02%.

Funcionalidades de este subsistema

23
ID Status Funcionalidades
F19.17.01 Entregado EmailDistributor-abstraktion med send_transactional / send_bulk / handle_webhook; MailjetDistributor + ACSDistributor (failover) + NullDistributor (dev/test) ✅ PL-T152
F19.17.02 Entregado Beanie-modeller: NewsletterList (platform/tenant-scope), NewsletterSubscription (pending/active/unsubscribed/bounced/complained/suppressed), NewsletterTemplate (MJML-source + rendered cache), NewsletterSegment, NewsletterCampaign (draft/scheduled/sending/sent/paused/cancelled), NewsletterEvent (90 d TTL), NewsletterSuppression, NewsletterAutomationFlow, NewsletterAutomationEnrolment, NewsletterAIQuota ✅ PL-T152
F19.17.03 Entregado Double-opt-in med HMAC-SHA256-signerade tokens (purpose-bound: confirm/prefs/unsub, TTL 14/30/90 d) — services/newsletter_tokens.py ✅ PL-T152
F19.17.04 Entregado Publika endpoints: POST /public/newsletter/subscribe (Turnstile + honeypot + rate-limit 5/IP/h), GET /public/newsletter/confirm, GET/PUT /public/newsletter/preferences/{token}, POST /public/newsletter/unsubscribe/{token}, POST /public/newsletter/unsubscribe-all/{token}, POST /public/newsletter/list-unsubscribe/{token} (RFC 8058 one-click), GET /public/newsletter/open/{...}.png, GET /public/newsletter/click/{...}?url= ✅ PL-T152
F19.17.05 Entregado Sys-CRUD: lists + subscribers + CSV-import med attesterad consent-proof + GDPR-radering + templates (MJML-editor) + segments (visual builder) + campaigns (wizard) + automations + suppressions + deliverability + analytics-overview ✅ PL-T152
F19.17.06 Entregado A/B-testing: variants + random-N% / full-random-split + pooled two-proportion z-test + Wilson confidence interval + winner-selection-job (services/newsletter_stats.py) ✅ PL-T152
F19.17.07 Entregado Send-time-optimering: engagement_profile = {best_hour_utc, best_weekday, confidence} per subscriber; dagligt refresh-job + dispatcher som schemalägger per-recipient inom 24h-fönster, fallback till scheduled_at vid confidence < 0.3 ✅ PL-T152
F19.17.08 Entregado Drip-automations: AutomationFlow med visual flow-builder (react-flow, trigger/wait/send/branch/exit); preset-flows: 7-day onboarding, 30-day re-engagement, 90-day win-back; triggers: subscription_confirmed, webinar_registered, tenant_onboarded, user_inactive_days, manual_enroll ✅ PL-T152
F19.17.09 Entregado Dynamic content blocks i MJML: {% content-block key variants=[...] %} med send-time-evaluation per subscriber-context (språk/tenant/merge_data) ✅ PL-T152
F19.17.10 Entregado AI-assist via Gemini 2.5 Pro: /sys/newsletter/ai/subject-lines, /ai/content-polish, /ai/preview-audience-reaction (5 personas); quota 50 req/operator/24h via newsletter_ai_quota; alla calls audit-loggade med prompt+response-hash ✅ PL-T152
F19.17.11 Entregado Heatmaps + cohort-analytics: click-koordinat-aggregation per campaign, open/click-rate per cohort (tenant/role/language/source), engagement-score per subscriber (rolling 30d), at-risk-flagg (< 0.1 → feeder till re-engagement-automation) ✅ PL-T152
F19.17.12 Entregado Cross-client-preview via Litmus API: screenshots per klient (Gmail, Apple Mail, Outlook, Yahoo) + spam-score-check; blockerar schedule vid spam-score > 5 ✅ PL-T152
F19.17.13 Entregado Visuell segment-builder: drag-and-drop AND/OR-grupper, live recipient-count, sparbara segments; allow-list av fält + ops (eq, neq, in, nin, gt/gte/lt/lte, regex escaped, exists); services/newsletter_segment.py ✅ PL-T152
F19.17.14 Entregado Campaign-dispatcher-job (newsletter-campaign-dispatcher, 1 min-cadence): throttled send enligt throttle_per_hour (default 5000/h); per recipient: MJML-render + merge-vars + link-rewrite + pixel-inject + compliance-footer + List-Unsubscribe-header + RFC 8058-one-click; pause/resume/cancel ✅ PL-T152
F19.17.15 Entregado Distributor-webhook: POST /_internal/distributor-webhook/{provider} med HMAC-signaturverifiering, idempotent på provider_event_id; hard_bounce → suppression; soft_bounce-escalation efter 5 consecutive; complaint → suppression + status=complained ✅ PL-T152
F19.17.16 Entregado Premium-template-gallery (12+ pre-designed): announcement, digest, event_invite, product_drop, case_study, win_back, re_engagement, onboarding_step, tournament_recap, scoreboard_release, federation_update, seasonal — clone-to-customize ✅ PL-T152
F19.17.17 Entregado Embeddable signup-form — Astro (www/src/components/conversion/NewsletterSignup.astro) + Next.js (web/src/components/blocks/NewsletterSignupBlock.tsx); prop listSlug, layouts (inline/modal/card), 4-språk i18n, Turnstile + honeypot ✅ PL-T152
F19.17.18 Entregado Preference-center-sida: www/src/pages/{en,sv,fr,es}/newsletter/preferences.astro med query-string-token, lista av lists i samma scope, name/language/per-list-membership, unsubscribe-all ✅ PL-T152
F19.17.19 Entregado Webinar-integration (T151): GDPR-strikt default-unticked opt-in på POST /public/webinars/{slug}/register; vid kryss skapas NewsletterSubscription(status=pending, source=webinar_registration) parallellt med webinar-confirmation ✅ PL-T152
F19.17.20 Entregado Tenant-admin read-only-vy: admin/app/(dashboard)/newsletter/{index,[id]}.tsx + /admin/newsletter/{lists,lists/{id}/subscribers,campaigns}-API scoped via request.state.tenant_id (403 utan tenant-kontext) ✅ PL-T152
F19.17.21 Entregado Compliance: consent-proof per subscribe (IP-hash + UA-hash + form_id + timestamp + method), CAN-SPAM physical-address auto-inject i footer, audit-trail för subscribe/confirm/preferences/unsubscribe/import/suppression/GDPR, 3-year post-unsub retention ✅ PL-T152
F19.17.22 Entregado Deliverability-dashboard: per from-domain reputation + SPF/DKIM/DMARC-status + bounce/complaint/unsub 30d-rater + spam-score-historik; halt-sends-action vid threshold-breach (bounce > 2 % eller complaint > 0.1 %) ✅ PL-T152
F19.17.23 Entregado Tester: 35 testfall i api/tests/test_t152_newsletter.py — unit (z-test, Wilson, pick_winner, tokens, segment DSL), integration (full subscribe→confirm→prefs→unsub-cykel, suppression, honeypot, rate-limit 429, tenant-admin 403), alla passerar ✅ PL-T152

Partes interesadas que necesitan este subsistema

Aparece en 2 análisis de partes interesadas