06 — E-mailové notifikace a newsletter architektura
Přehled
E-maily v rámci Economia ekosystému se dělí do čtyř kategorií s jasnou odpovědností:
| Kategorie | Příklady | Kdo triggeruje | Kdo odesílá |
|---|---|---|---|
| Transakční — předplatné | Potvrzení objednávky, prodloužení, expirující předplatné, faktura | REMP CRM (interní eventy) | REMP Mailer (CRM volá Mailer API) |
| Transakční — identita | Reset hesla, potvrzení e-mailu, welcome email | EGO-SSO (Ecoidentita) | EGO-SSO (vlastní SMTP) |
| Marketing / Newsletter | Denní digest, týdenní newsletter, autorský digest | Redakce via CMS | REMP Mailer |
| Systémové / Admin | Toxin error, admin pozvánky, admin password reset | Folio CMS | ActionMailer (Rails SMTP) |
Poznámka: Folio CMS neposílá transakční e-maily čtenářům. Subscription/payment lifecycle řídí REMP CRM, identitu řídí EGO-SSO. CMS odesílá pouze interní admin/systémové notifikace.
Architektura — kdo co odesílá
┌─────────────────────────────────────────────────────────┐
│ REMP CRM (FatChilli) │
│ │
│ Transakční e-maily ──► REMP Mailer API │
│ (order confirmation, POST /api/v1/mailers/send-email │
│ subscription lifecycle, │
│ payment receipt, │
│ invoice) │
│ │
│ CRM řídí lifecycle events → interně volá Mailer │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ EGO-SSO (Ecoidentita) │
│ │
│ Transakční — identita ──► vlastní SMTP │
│ (reset hesla, potvrzení e-mailu, welcome) │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ Folio CMS │
│ │
│ Systémové e-maily ──► ActionMailer (Rails) │
│ (admin alerts, direct SMTP │
│ Toxin errors, │
│ admin invitations) │
│ │
│ Newsletter handoff ──► REMP Mailer API │
│ (redaktor připraví POST /api/v1/mailers/templates │
│ obsah v CMS, + POST /api/v2/mailers/jobs │
│ Mailer doručí) │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ REMP Mailer │
│ │
│ Receives: │
│ - send-email requests (od REMP CRM — transakční) │
│ - job requests (od CMS — newsletter handoff) │
│ - template push (od CMS — newsletter HTML/text) │
│ │
│ Owns: │
│ - Mail templates (Twig) │
│ - Mail types & categories │
│ - User ↔ mail-type subscriptions │
│ - Delivery queue (Hermes/Redis) │
│ - Delivery logs & stats │
│ │
│ Segment provider: │
│ - REMP CRM segments (`crm-segment`) │
│ - Další REMP providery dle deploymentu │
└─────────────────────────────────────────────────────────┘
Transakční e-maily
REMP CRM → REMP Mailer (předplatné, platby)
Všechny e-maily spojené se subscription lifecycle a platbami triggeruje REMP CRM interně — CMS do nich nezasahuje.
| Trigger (REMP CRM event) | Template (v Maileru) | |
|---|---|---|
| Potvrzení objednávky | Platba proběhla | subscription_confirmed |
| Předplatné expiruje | N dní před expirací | subscription_expiring |
| Předplatné vypršelo | Po expiraci | subscription_expired |
| Předplatné zrušeno | Uživatel/admin zrušil | subscription_cancelled |
| Potvrzení platby / faktura | Po platbě | payment_receipt |
REMP CRM moduly (crm-subscriptions-module, crm-payments-module) obsahují handlery, které při lifecycle eventech volají REMP Mailer API (POST /api/v1/mailers/send-email) interně. Template design a obsah těchto e-mailů je odpovědností FatChilli.
EGO-SSO → vlastní SMTP (identita)
E-maily spojené s identitou čtenáře odesílá EGO-SSO (Ecoidentita) ze svého SMTP:
| Trigger | Systém | |
|---|---|---|
| Welcome / registrace | Nový účet na ucet.centrum.cz | EGO-SSO |
| Reset hesla | Žádost o reset | EGO-SSO |
| Potvrzení e-mailu | Změna e-mailu | EGO-SSO |
CMS ani REMP CRM tyto e-maily neposílají — identita je v režii EGO-SSO.
Folio CMS → ActionMailer (admin / systém)
CMS odesílá jen interní administrátorské e-maily přes Rails ActionMailer:
| Trigger | Mailer (existující kód) | |
|---|---|---|
| Toxin upload failed | Chyba XML importu | Economia::ToxinErrorMailer#upload_failed |
| Admin password reset | Admin žádá o reset | Folio::DeviseMailer#reset_password_instructions |
| Admin invitation | Pozvání do konzole | Folio::DeviseMailer#invitation_instructions |
Toto jsou e-maily pro redaktory a administrátory, nikoli pro čtenáře.
Newslettery
Boundary: CMS připravuje, REMP odesílá
Pro newslettery platí tento model:
- CMS vlastní obsahovou přípravu: editor, prolinky na články, výběr médií, subject, preheader, lokální preview a archiv toho, co redakce schválila.
- REMP Mailer vlastní mail types, layout wrappery, příjemce, odběry, segment resolution, frontu odeslání, tracking a unsubscribe logiku.
- REMP CRM je zdroj segmentů a příjemců pro bulk rozesílky, typicky přes provider
crm-segment.
Konkrétní mail_type_code, mail_layout_code a segment kódy musí existovat v deploymentu REMP. CMS je pouze používá a mapuje; jejich provisioning není součástí CMS implementace.
Pracovní flow newsletteru z CMS do Maileru
1. Redaktor v CMS vytvoří newsletter
│
├── vybere články, média, pořadí bloků, subject, preheader
│
├── CMS udělá lokální preview
│ (email-safe HTML + plain text)
│
├── POST /api/v1/mailers/templates
│ form-data:
│ name, code, description, mail_type_code, subject,
│ template_html, template_text, mail_layout_code, preheader
│
├── volitelně GET /api/v1/mailers/render-template?code=...
│ pro kontrolu uložené template v Maileru
│
├── POST /api/v2/mailers/jobs
│ {
│ template_code: "hn_daily_digest_20260801",
│ include_segments: [
│ { provider: "crm-segment", code: "all_hn_digital" }
│ ],
│ context: "daily_digest_2026_08_01",
│ start_at: "2026-08-01T06:00:00Z"
│ }
│
└── rozesílka, tracking a status běží v REMP Maileru
Důležité k aktuálnímu remp:
render-templatejeGETnad uloženou template podlecode, nePOSTdraft preview endpoint.- Pro nový handoff preferujeme
POST /api/v2/mailers/jobs; v1 API je starší a pracuje stemplate_id+segment_code. - V aktuálním
rempnení opora proGET /api/v1/mailers/jobs/{id}jako stabilní integrační kontrakt. Monitoring je proto potřeba brát jako součást Mailer adminu nebo vendor-specifického rozšíření.
CMS Admin UI pro newslettery
Nový admin modul v Folio CMS řeší obsahovou přípravu a handoff:
# Economia::Console::Remp::NewslettersController
class Economia::Console::Remp::NewslettersController < Folio::Console::BaseController
def new
# Form: mail type mapping, articles, media, subject, preheader, segment reference
end
def preview
# Lokální render email-safe HTML v CMS, bez závislosti na Maileru
end
def create
# NewsletterComposerService:
# 1. vyrenderuje HTML + text
# 2. pushne template do Maileru
# 3. založí Mailer job
# 4. uloží template_code / job_id / context do CMS audit záznamu
end
def index
# Přehled newsletter handoffů z CMS, ne náhrada Mailer delivery dashboardu
end
end
Reader odběry zůstávají v REMP
Reader subscription management není součástí CMS integračního scope. V aktuálním remp existují endpointy:
POST /api/v1/users/subscribePOST /api/v1/users/un-subscribePOST /api/v1/users/user-preferencesPOST /api/v1/mailers/send-emailPOST /api/v1/mailers/mail-type-upsert
Tyto flows patří do reader části provozované v REMP / FatChilli. Pokud bude web potřebovat CTA typu “spravovat odběry”, CMS má na tyto REMP-owned obrazovky nebo API flows pouze navazovat podle finální dohody s vendorem, ne je znovu implementovat jako vlastní business logiku.
Automatický Author / Section Digest
CMS může skládat obsah digestu, ale doručení stále obstarává Mailer.
# app/jobs/economia/remp/author_digest_job.rb
class Economia::Remp::AuthorDigestJob < ApplicationJob
queue_as :default
def perform
Economia::Author.with_digest_schedule.find_each do |author|
articles = author.articles
.published
.where("published_at > ?", 1.week.ago)
.order(published_at: :desc)
.limit(10)
next if articles.empty?
Economia::Remp::NewsletterComposerService.new.publish!(
mail_type_code: author.mail_type_code,
template_code: "author_digest_#{author.slug}_#{Date.current.strftime('%Y%m%d')}",
template_name: "Digest autora #{author.full_name}",
subject: "Nové články autora #{author.full_name}",
preheader: "Výběr článků za poslední týden",
include_segments: [
{ provider: "crm-segment", code: author.segment_code }
],
content: {
author_name: author.full_name,
articles: articles
}
)
end
end
end
Předpoklad tohoto flow:
author.mail_type_codeaauthor.segment_codeukazují na již nakonfigurované entity v REMP.- CMS negeneruje nové mail types ani subscription preference model.
- Cron/job v CMS jen skládá obsah a spouští handoff do Maileru.
Newsletter z CMS editoru (TipTap)
Požadavek HN dává smysl: newsletter se má psát ve stejném editačním prostředí jako články, stránky a další obsah CMS. Nejpraktičtější varianta podle aktuální reality remp je push handoff:
- CMS vyrenderuje finální email-safe HTML a plain-text verzi.
- CMS předá hotovou template přes
POST /api/v1/mailers/templates. - CMS založí rozesílku přes
POST /api/v2/mailers/jobs. - Mailer doplní vlastní wrapper, unsubscribe logiku, tracking a delivery pipeline.
Alternativa přes custom IGenerator na straně Maileru existuje, ale je to vendor customizace. Pro tuto dokumentaci proto není považovaná za výchozí integrační variantu.
Technické poznámky
- TipTap → Email HTML: CMS musí generovat výstup kompatibilní s e-mail klienty, tedy inline CSS a konzervativní layout.
- Plain-text verze:
template_textje povinná a musí vznikat v CMS spolu s HTML. - Layout koordinace: Mailer layout (
mail_layout_code) zůstává na straně REMP, takže CMS musí generovat obsah, který se s wrapperem nebije. - Preview: draft preview má být lokální v CMS;
GET /api/v1/mailers/render-template?code=...je vhodný až po uložení template do Maileru. - Audit trail: CMS by si mělo ukládat
template_code,job_id,context, timestamp handoffu a autora změny.
Rozdělení odpovědností: shrnutí
| Co | Kdo vlastní | Kdo odesílá / provozuje |
|---|---|---|
| Newsletter obsah, články, média, subject | Redakce / CMS | CMS připraví handoff |
| Email-safe HTML a plain-text render | CMS | CMS |
| Mail types, layouts, unsubscribe wrapper | REMP Mailer | REMP Mailer |
| Segmenty a seznam příjemců | REMP CRM / Mailer | REMP |
| Delivery queue a SMTP | REMP Mailer | REMP Mailer |
| Delivery stats, opens, clicks | REMP Mailer | REMP Mailer |
| Reader subscribe / unsubscribe | REMP Mailer | REMP Mailer |
| Admin / systémové e-maily | Folio CMS | ActionMailer |