/create-message-v4

API de Mensagem — v4 (createMessage)

Documentação do módulo createMessage, que cria uma mensagem (push, SMS, WhatsApp, e-mail, RCS, in-app, on-site ou multicanal), persistindo um documento control_message no MongoDB e os destinatários no MariaDB. Suporta agendamento, envio imediato (instant_message), campanhas, templates de API e fluxo de aprovação.

Gerada a partir do código em 2026-07-07 (branch marco).

EndpointO que faz
POST /v4/createMessage/Cria e agenda (ou dispara na hora) uma mensagem multicanal

Autenticação

  • app_token obrigatório no corpo — resolvido no MariaDB (app); inválido → 401.
  • JWT condicional: se o app tiver token ativo em app_auth_token, o header Authorization passa a ser obrigatório (ausente ou "undefined"403). Se o app não tem JWT ativo, o header é ignorado.

Envelopes aceitos

FormatoComportamento
{ "savePushRequest": { ... } }usa o objeto interno
{ "sendPushRequest": { ... } }formato V1: renomeia identifieridentifiers (força array), messagebody, e força instant_message = true
objeto diretosem envelope

Corpo da requisição

Apenas app_token é obrigatório no schema ("app_token is required"); todo o resto é opcional/nullish — as obrigatoriedades condicionais são validadas no service (abaixo). Campos extras são descartados (.strip()). Validação Zod retorna apenas a primeira mensagem de erro.

Conteúdo da mensagem

CampoTipoObs.
titlestringdefault ""
bodystringdefault ""; pode vir de campanha/template; no V1 é message
imagestringgravado como img_push
url, url_typestringurl vira url_push
actionsanyações do push
emailobjetohtml, subjectEmail, contentHeaderEmail, sender_email, sender_name, reply_to_*
wtp_dataobjetoWhatsApp Template (template_id, params, buttonParam...)
rcs_dataobjetoRCS (type: CAROUSEL/RICHCARD/..., contents[], title, description, image_url)
inappobjetoin-app (title, body)
on_site_messageobjetoon-site (title, body, scratch_card.sortition, wellcomeCampaign)

Destinatários (mutuamente exclusivos entre si)

CampoTipoObs.
identifiersstring | string[]no V1 é identifier
audiences(number | string)[]exatamente uma audiência, inteiro positivo, pertencente ao app
registrationstringtoken de device
subscriber_idstring | string[]
phone_numberstring | numbernormalizado (remove não-dígitos; prefixa 55 em celular BR de 10–11 dígitos)
subscriber_emailstring

Canal, agendamento e fluxo

CampoTipoObs.
channel_idnumber | stringdefault 1 (push)
channel_flagnumber | stringflag multicanal; 0 → null
channelsarray | objetoarray (novo padrão) ou objeto por nome (legado); cada canal exige custom_body
instant_messageboolean | stringtruthy = true/"true"/1/"1"; exige destinatário direto
schedulestringdata de agendamento, convertida para o timezone do app; ausente = agora
send_until, expiration_timestringvalidade; on-site sem send_until ganha default +72h
expiration_period + expiration_period_typenumber/string + stringhours/days/minutes
need_approvalboolean | numbertruthy → mensagem criada com status pendente (11)
campaignnumber | stringID em new_campaigns; preenche conteúdo/canais da campanha
template_id / api_template_idnumber | stringdispara fluxo de template de API
tagsobjetovalores para substituição de {{tag}} no template
automation_idnumber | stringgravado no doc; suprime sender_id
sender_idnumber | stringignorado se houver automation_id
originnumber | stringdefault 3 (vira message_type_id); 4 = bulk
authentication_codestring2FA: com phone_number, grava em message_authentication
utm_source/utm_medium/utm_campaign/utm_term, utm_datastring / objeto
additional_dataanygravado como meta_data
geo_fence, first_access, af, email_test, is_testdiversosis_test é aceito mas não usado no insert

Validações condicionais (service) — mensagens exatas

  • Faltando token/destinatário/corpo → "Required parameters were not informed: <lista>." (corpo não é exigido se houver template_id/api_template_id/campaign).
  • campaign junto com template_id"campaign e template_id são mutuamente exclusivos. Envie apenas um."
  • Mais de um tipo de destinatário → "You must choose between an audience, an identifier, a registration or subscriberID."
  • instant_message sem destinatário direto → "instant_message requires a direct recipient (identifiers, registration, subscriber_id, phone_number or subscriber_email)."
  • Audiência inválida → "Invalid audience: exactly one audience is required." / "Invalid audience_id: <valor>" / "Invalid audience: <id> does not belong to app <appId>."
  • Campanha inexistente → "Invalid campaign ID!" · Canal sem custom_body"Invalid payload. Check your JSON. [custom_body] is required"

Comportamento

  1. Template (template_id sem campaign): delega ao fluxo de template de API (new_api_template), que valida as {{tags}} e reexecuta a criação uma vez por identifier, sempre como instant_message. Erros próprios de tags (tag não cadastrada, obrigatória ausente, template inexistente).
  2. Campanha (campaign): lê new_campaigns/new_campaign_channel e preenche título/corpo/imagem/canais (inclui multicanal por prioridade via multichannel_config).
  3. Persistência: insere o documento em inn_db.control_message com schema_version: 2, status inicial 11 (pendente) se need_approval, senão 0. Canais são adicionados via $addToSet no array channel, sempre no shape único { channel: { channel_provider_id, priority, custom_title, custom_body, ... } }.
  4. Destinatários (MariaDB control_message_recipient): gravados por tipo — identifier=1, subscriber=5, phone=6, email=7, registration=8. Depois o status da CM vai para 1 (pronta).
  5. Dispatch:
    • instant_message: chama in-process o processQueue do módulo newQueuePubsubV2 (fire-and-forget), que cria tópico/assinatura Pub/Sub por CM e despacha. Se pendente de aprovação, não despacha.
    • Não-instant (agendada): fica em status 1 e é coletada depois pelo agendador — não passa pelo dispatch deste módulo.
    • Falha ao salvar destinatários/dispatch → status 9 (erro).
  6. Aprovação: com need_approval, dispara e-mail para os aprovadores (app_approval_email) via self-call HTTP interno (fire-and-forget).

Importante: esta API não verifica existência/atividade do subscriber — a checagem é responsabilidade do fluxo de entrega.

Respostas

Shape sempre { "saveResponse": { "status": <n>, "details": <...> } }.

Sucesso — 200. O details varia por fluxo:

Fluxodetails
instant{ "CM_id": "<id>", "message": "Message created and directed to the delivery queue." } ou "Message created and pending approval."
identifiers{ "control": "<id>", "recipients": <total> }
audience{ "control": "<id>", "Audiences": [<id>] }
subscriber_id{ "control": "<id>", "recipients": [...] }
bulk (origin: 4){ "control": "<id>", "recipients": <identifiers> }
fallback "all"{ "control": "<id>", "recipients": "all" }
templateresultado único ou array (um por identifier)

Erros:

StatusQuandodetails
400validação Zod, payload vazio, app_token ausente ou ValidationErrormensagem do erro (ex.: "Invalid payload. Check your JSON.", "app_token is required.")
401app_token inválido"Invalid App Token."
403app com JWT ativo sem header Authorization"Forbidden, check your authorization!"
500DomainError ou erro inesperadomensagem do erro ou "Internal Server Error"

Exemplos

Push agendado para lista de identifiers:

{
  "app_token": "a1b2c3d4e5f6",
  "title": "Promoção relâmpago",
  "body": "Aproveite 30% OFF só hoje!",
  "image": "https://cdn.exemplo.com/promo.png",
  "url": "https://loja.exemplo.com/ofertas",
  "channel_id": 1,
  "identifiers": ["user-123", "user-456"],
  "schedule": "2026-07-08 09:00:00",
  "expiration_period": 24,
  "expiration_period_type": "hours",
  "utm_source": "push"
}

Envio instant de 2FA por SMS:

{
  "app_token": "a1b2c3d4e5f6",
  "body": "Seu código de acesso é 4821",
  "instant_message": true,
  "phone_number": "+55 11 99999-8888",
  "authentication_code": "4821",
  "channel_id": 2
}

Formato V1 (legado):

{
  "sendPushRequest": {
    "app_token": "a1b2c3d4e5f6",
    "identifier": "user-123",
    "title": "Olá",
    "message": "Bem-vindo de volta!"
  }
}

Referências de código

  • Router: v4/createMessage/routes/createMessageRoute.js
  • Validator: v4/createMessage/validators/createMessageSchema.js (schema, adaptador V1 e middleware)
  • Controller: v4/createMessage/controller/createMessageController.js
  • Services: v4/createMessage/services/createMessageService.js, v4/createMessage/services/apiTemplateService.js
  • Repositórios: controlMessageRepository.js (MongoDB control_message), messageLogRepository.js (MariaDB control_message_recipient, message_authentication), appRepository.js (MariaDB)
  • Dispatch delegado a v4/newQueuePubsubV2/services/queueOrchestrationService.js


Did this page help you?