Logotipo Hedhog

Receba novidades do Hedhog no seu e-mail

Novos lançamentos, receitas e breaking changes — sem spam.

Submódulo Campaign

recipient-lists

Listas nomeadas de destinatários que as campanhas alvejam. Suporta entrada manual, importação por CSV, sincronização com o CRM e cadastro público.

Caminho de origem: libraries/campaign/src/services/campaign-recipient-list.service.ts, campaign-realtime.service.ts, dto/public-signup.dto.ts

Arquivo do módulo: campaign.module.ts

Introdução

O submódulo Recipient Lists modela `campaign_recipient_list`, o contêiner de público que uma campanha aponta via `recipient_list_id`. Cada lista carrega um slug único e validado (letras minúsculas, números, hifens, no mínimo 2 caracteres — gerado automaticamente a partir do nome se não fornecido), uma classificação de `source` ("manual" | "import" | "crm" | "mixed") que reflete como seus destinatários foram populados e contadores consolidados (`total_recipients`, `total_active`, `total_unsubscribed`, `total_suppressed`, `total_invalid`) que o CampaignRecipientListService recalcula após cada mutação, em vez de computar na leitura. Todas as rotas são montadas em duplicidade tanto sob `/campaign/lists/*` quanto `/campaign/recipient-lists/*` — o controller registra cada handler duas vezes com o suporte a múltiplos decorators do NestJS — de modo que ambas as convenções de nomenclatura resolvem de forma idêntica; esta documentação usa `/campaign/recipient-lists/*` como a forma canônica.

Destinatários podem ser adicionados a uma lista de três maneiras. JSON inline (`POST .../recipients` com um array de objetos `{ email, name?, ... }` ou um atalho `{ email }` único) faz upsert por e-mail dentro da lista. A sincronização com o CRM (`person_ids` no mesmo endpoint) resolve o contato primário do tipo EMAIL de cada Person do CRM, pulando pessoas sem e-mail válido e reportando-as de volta em um array `skipped`, e então muda o `source` da lista para "mixed" (ou "crm" se todos os destinatários vieram do CRM) assim que pelo menos uma pessoa é adicionada. A importação por CSV é um fluxo em duas etapas: `POST .../recipients/import/preview` faz o parsing do arquivo enviado (parser de CSV artesanal e customizado, suportando tanto delimitadores de vírgula quanto de ponto e vírgula e campos entre aspas, limitado a 10 MB / reforçado novamente em 5000 linhas de dados) e retorna as colunas detectadas mais uma amostra de 20 linhas sem persistir nada; `POST .../recipients/import` recebe o mesmo arquivo mais um `mapping` JSON das colunas do CSV para os campos de destinatário e realiza o upsert-por-e-mail de fato, opcionalmente vinculando cada linha importada a uma empresa existente do CRM via `company_id`.

O cadastro público (`POST /campaign/lists/:slug/signup`, não autenticado) permite que uma lista aceite inscrições self-service. Ele só funciona quando `allow_public_signup` é true na lista; quando `enable_captcha` também é true, o Integration Profile de CAPTCHA configurado (reCAPTCHA, Cloudflare Turnstile ou Altcha) é invocado para validar o `captcha_token` enviado antes de o e-mail sofrer upsert. Este é o ponto de entrada típico para formulários de inscrição em newsletter incorporáveis.

O submódulo também hospeda o cursor de tempo real da campanha (`GET /campaign/realtime/cursor`, `GET /campaign/realtime/stream`): cada mutação de lista chama `CampaignRealtimeService.publish()`, incrementando um contador de sequência em memória que as UIs de admin consultam por polling ou assinam via Server-Sent Events para saber quando refazer o fetch dos dados da lista, sem que o servidor rastreie o estado por cliente.

Endpoints HTTP

15 endpoints

Obtém o cursor de atualização em tempo real atual (número de sequência e timestamp da última atualização) para refresh baseado em polling.

Abre um stream de Server-Sent Events que envia o cursor atualizado sempre que uma lista de destinatários muda (criação, atualização, exclusão, mutação de destinatário).

Estatísticas agregadas em todas as listas de destinatários: total de listas e contadores somados de destinatários/ativos/descadastrados/suprimidos/inválidos. Também disponível em /campaign/lists/stats.

Lista paginada de listas de destinatários. Também disponível em /campaign/lists.

Query
page, pageSize, search, status, source

Cria uma lista de destinatários. Também disponível em /campaign/lists.

Body

FieldTypeRequiredNotes
namestringyes
slugstringnoAuto-generated from name if omitted; lowercase letters/numbers/hyphens, min 2 chars, must be unique
descriptionstringno
source"manual" | "import" | "crm" | "mixed"noDefault: "manual"
status"active" | "inactive"noDefault: "active"
allow_public_signupbooleannoDefault: false
enable_captchabooleannoDefault: false
captcha_integration_profile_idnumbernoRequired when enable_captcha is true
metadataobjectno

Exclusão em massa de listas de destinatários. Também disponível em /campaign/lists.

Body

FieldTypeRequiredNotes
idsnumber[]yesIDs to delete

Obtém uma lista de destinatários por ID. Também disponível em /campaign/lists/:id.

Params
id (int)

Atualiza uma lista de destinatários. Apenas os campos fornecidos são alterados. Também disponível em /campaign/lists/:id.

Params
id (int)

Body

FieldTypeRequiredNotes
namestringno
descriptionstringno
source"manual" | "import" | "crm" | "mixed"no
status"active" | "inactive"no
metadataobjectno
slugstringnoMust remain unique
allow_public_signupbooleanno
enable_captchabooleanno
captcha_integration_profile_idnumberno

Exclui uma única lista de destinatários. Também disponível em /campaign/lists/:id.

Params
id (int)

Lista paginada de destinatários em uma lista específica. Também disponível em /campaign/lists/:id/recipients.

Params
id (int)
Query
page, pageSize, search, status

Pré-visualiza uma importação de CSV: faz o parsing de delimitadores/aspas e retorna as colunas detectadas mais uma amostra de 20 linhas sem persistir dados. Rejeita arquivos com mais de 5000 linhas de dados. Também disponível em /campaign/lists/:id/recipients/import/preview.

Params
id (int)

Body

FieldTypeRequiredNotes
filefile (CSV, max 10 MB)yesmultipart/form-data upload; text/csv or application/vnd.ms-excel

Importa destinatários de um arquivo CSV. Faz upsert por e-mail dentro da lista e opcionalmente cria registros de Person vinculados no CRM. Também disponível em /campaign/lists/:id/recipients/import.

Params
id (int)

Body

FieldTypeRequiredNotes
filefile (CSV, max 10 MB)yesmultipart/form-data upload
mappingstring (JSON)yesJSON object mapping CSV column names to recipient fields (e.g. {"Email":"email","Nome":"name"})
company_idnumbernoCRM company ID to associate imported recipients/persons

Adiciona destinatários a uma lista a partir de IDs de person do CRM ou de dados inline. Faz upsert por e-mail e recalcula os contadores da lista. Também disponível em /campaign/lists/:id/recipients.

Params
id (int)

Body

FieldTypeRequiredNotes
person_idsnumber[]noCRM person IDs; auto-resolves primary EMAIL contact. When provided, other fields are ignored
recipientsobject[]noArray of { email, name?, first_name?, last_name?, company?, phone?, status?, source?, person_id?, metadata? }
emailstringnoShorthand for adding a single recipient by email

Remove destinatários específicos de uma lista. Também disponível em /campaign/lists/:id/recipients.

Params
id (int)

Body

FieldTypeRequiredNotes
idsnumber[]yesRecipient IDs to remove from this list

Cadastro público em uma lista de destinatários identificada por slug. Só funciona quando a lista tem allow_public_signup habilitado. Valida o CAPTCHA (reCAPTCHA, Cloudflare Turnstile ou Altcha) quando enable_captcha está definido e então faz upsert do destinatário como ativo.

Params
slug (string) — public slug of the recipient list

Body

FieldTypeRequiredNotes
emailstringyesValid email address
namestringno
first_namestringno
last_namestringno
companystringno
phonestringno
captcha_tokenstringnoRequired when the list has enable_captcha set