E-mail transacional
core.transactional-email — configuração protegida, templates versionados, preview, envio idempotente, fila com retentativas e painel administrativo.
1. Declare a capability
{
"capabilities": ["core.transactional-email"],
"capabilitySettings": {
"core.transactional-email": {
"enabled": true,
"scopePolicy": "tenant_override",
"retentionDays": 30,
"attachmentsPolicy": { "allowed": false },
"templates": [
{ "code": "confirmacao", "definition": "./backend/emails/confirmacao.json", "initialStatus": "active" }
]
}
}
}
| Configuração | Valores |
|---|---|
scopePolicy |
app_only, tenant_required ou tenant_override |
retentionDays |
1 a 90 |
attachmentsPolicy |
Anexos não são permitidos nesta linha |
templates[].definition |
Caminho relativo ao manifesto, dentro de backend/ para ir na imagem |
2. Crie o template
{
"code": "confirmacao",
"name": "Confirmação",
"subject": "Olá, {{nome}}",
"htmlContent": "<p>Olá, {{nome}}.</p>",
"textContent": "Olá, {{nome}}.",
"variablesSchema": {
"type": "object",
"additionalProperties": false,
"required": ["nome"],
"properties": { "nome": { "type": "string" } }
},
"locale": "pt-BR",
"initialStatus": "active",
"attachmentsPolicy": { "allowed": false }
}
Templates usam somente interpolação Handlebars escapada. Blocos, helpers, subexpressões, triple-stache e conteúdo remoto executável não são aceitos. O escape HTML vale só para htmlContent; assunto e texto saem literais (CR/LF são removidos do assunto).
3. Envie pelo backend
const { capabilities } = require("@oondemand/oon-core-back");
async function enviarConfirmacao({ email, nome, idempotencyKey }, req) {
return capabilities.transactionalEmail.send(
{
templateCode: "confirmacao",
to: email,
variables: { nome },
idempotencyKey,
correlationId: req.correlationId,
maxAttempts: 5,
},
{ ...req.accessContext, userId: req.accessContext?.userId },
);
}
module.exports = { enviarConfirmacao };
Retorno: { dispatchId, status, correlationId } com status igual a accepted ou duplicate.
O namespace capabilities.transactionalEmail também oferece preview e versionamento de templates, consulta de dispatches e retry de dead letter.
4. Painel administrativo
import { CoreTransactionalEmail } from "@oondemand/oon-core-front";
export function EmailPage() {
return <CoreTransactionalEmail />;
}
Quando a capability está declarada, o Core já registra a página /configuracoes/email-transacional e o item de menu em Configurações. Conceda apenas as permissões necessárias:
| Permissão | Uso |
|---|---|
transactional-email.config.read / .config.manage |
Ver / gerenciar provedor e configuração |
transactional-email.templates.read / .templates.manage |
Ver / gerenciar templates |
transactional-email.dispatches.read / .dispatches.retry |
Ver envios / reenviar dead letter |
Credenciais do provedor são inseridas pela tela protegida e armazenadas pelo Core — nunca no manifesto, frontend, repositório ou log.
Segurança e operação
- App e tenant são resolvidos do contexto validado;
tenant_requiredexige tenant;tenant_overrideusa a configuração do tenant e recua para a do App;- destinatários e variáveis são validados antes de enfileirar;
- payload protegido tem retenção limitada e não aparece nas listagens;
- erros usam
TransactionalEmailErrorcom códigosEMAIL_*sanitizados; sem declaração:EMAIL_CAPABILITY_NOT_DECLARED; - no runtime local, falha fechado até a capability estar configurada;
- testes substituem a fronteira externa — nunca envie e-mail real em testes.