01 · Jornadas RB
Uma conexão, jornadas por pedido
A integração recebe eventos na conexão Registro Base já existente da conta. Não crie outra conexão: a URL usa rb.connections.journeys_public_id. O segredo de entrada é independente do token RB usado para consultas e Cobrança RB.
- Obtenha a URL e gere o segredo em Conexões → Registro Base → Editar → Jornadas RB.
- Configure remetente, gatilho e intervalos em Automações → Jornadas RB e ative o recebimento na conexão.
- Monte o evento, assine os bytes exatos e envie. O HTTP confirma o ingresso; o processamento e o envio ocorrem depois.
POST https://api.itstime.pro/api/integrations/rb/v1/connections/{publicConnectionId}/events02 · Jornadas RB
Conexão e credenciais
Na aba Jornadas RB, gere a credencial, copie o segredo para o servidor RB e ative o recebimento. O segredo é exibido somente na resposta de geração/rotação. A primeira geração mantém a integração desativada até a ativação explícita. A aba Conexão preserva o token de consultas existente.
A rotação mantém o segredo imediatamente anterior válido por 24 horas; uma segunda rotação substitui esse anterior. Guarde o segredo fora de navegador, código público e logs.
| Estado | Significado |
|---|---|
| unconfigured | Sem segredo configurado. |
| paused | Configurada e desativada. |
| waiting | Ativada, ainda sem eventos. |
| receiving | Com eventos recebidos. |
| error | Evento bloqueado ou diagnóstico operacional não resolvido. |
03 · Jornadas RB
Autenticação HMAC
Envie JSON UTF-8, sem compressão, com no máximo 1 MiB. A assinatura é o hexadecimal de HMAC-SHA256 com o segredo da conexão.
| Cabeçalho | Valor |
|---|---|
| Content-Type | application/json |
| X-RB-Timestamp | Unix timestamp em segundos; janela de ±300 segundos. |
| X-RB-Signature | Hash hexadecimal; aceita prefixo sha256=. |
| Idempotency-Key | UUID igual ao event_id do corpo. |
signature = HMAC-SHA256(secret, timestamp + "." + rawBody)
X-RB-Signature: sha256=<hash_hexadecimal>04 · Jornadas RB
Payload e campos
{
"event_id": "10000000-0000-4000-8000-000000000001",
"event_type": "venda_convertida",
"occurred_at": "2026-10-20T12:00:00-03:00",
"ACES_ID": "70",
"EMP_ID": "1",
"CLIE_ID": "99",
"ATEN_ID": "100",
"ATEN_NO": "A-100",
"customer": {
"name": "Cliente",
"phone": "+5541999990000",
"email": "cliente@example.com",
"birth_date": "1990-01-02",
"whatsapp_consent": true
},
"order": {
"total_amount": "125.50",
"issued_at": "2026-10-20T12:00:00-03:00",
"items": [{"id":"1", "description":"Lente", "total_amount":"125.50"}],
"recipes": [{"id":"rx-1", "issued_at":"2026-10-20", "expires_at":"2027-10-20"}]
}
}| Campo | Obrigatoriedade e formato |
|---|---|
| event_id / event_type / occurred_at | Sempre obrigatórios. ID UUID; tipo listado neste guia; ocorrência ISO 8601 com fuso. |
| ACES_ID / EMP_ID | Sempre obrigatórios. ACES_ID corresponde a rb_aces_id; EMP_ID pertence a rb_empresa_ids da mesma conexão. |
| CLIE_ID | Obrigatório, exceto em pedido_cancelado. |
| ATEN_ID / ATEN_NO | Obrigatórios, exceto em consentimento_revogado. Identificam o pedido. |
| customer | Para eventos de mensagens: name, phone e whatsapp_consent:true explícito. email e birth_date enriquecem o cadastro. |
| customer.phone | 10 a 15 dígitos; números brasileiros sem DDI recebem 55 no processamento. |
| customer.birth_date | Somente YYYY-MM-DD, entre 1900 e hoje. |
| order | Nos eventos de mensagens: total_amount, issued_at, items e recipes. |
| order.total_amount | Decimal não negativo, ponto e até duas casas. Prefira string; normalizado para duas casas. |
| order.issued_at | Data YYYY-MM-DD ou ISO 8601 com fuso. |
| order.recipes[] | Receitas oftalmológicas com id, issued_at e expires_at (data ou null quando desconhecida). |
IDs aceitam strings ou inteiros seguros e são normalizados como strings. Envie strings para preservar zeros à esquerda. Detalhes adicionais em itens e receitas são preservados; envie somente os dados necessários à jornada, sem necessidade de medidas clínicas.
05 · Jornadas RB
Quando enviar cada evento
| Evento | Quando enviar | Conteúdo adicional |
|---|---|---|
| venda_convertida | Uma vez por venda convertida. | Cliente com nome, telefone e consentimento true; pedido com total, emissão, itens e receitas. |
| mercadoria_liberada | Em cada liberação; event_id próprio por liberação. | Mesmo conteúdo completo de cliente e pedido. |
| venda_entregue | Somente quando 100% do pedido foi entregue. | Todos os itens e todas as receitas, inclusive de entregas anteriores. |
| pedido_cancelado | Ao cancelar o pedido. | IDs do pedido, escopo e ocorrência. Dispensa telefone, consentimento e order; CLIE_ID opcional. |
| consentimento_revogado | Ao revogar o consentimento do cliente. | CLIE_ID, escopo e ocorrência. Dispensa pedido, atendimento e telefone. |
{
"event_id": "10000000-0000-4000-8000-000000000002",
"event_type": "pedido_cancelado",
"occurred_at": "2026-10-20T13:00:00-03:00",
"ACES_ID": "70", "EMP_ID": "1",
"ATEN_ID": "100", "ATEN_NO": "A-100"
}{
"event_id": "10000000-0000-4000-8000-000000000003",
"event_type": "consentimento_revogado",
"occurred_at": "2026-10-20T14:00:00-03:00",
"ACES_ID": "70", "EMP_ID": "1", "CLIE_ID": "99"
}06 · Jornadas RB
Assinar e enviar com Node.js
Salve como enviar.mjs e execute com node enviar.mjs. Use a URL real copiada da conexão e o segredo de entrada. Cada evento novo precisa de seu próprio UUID.
// Node.js 18+ · salve o payload acima como evento.json.
// Configure RB_WEBHOOK_URL e RB_WEBHOOK_SECRET no ambiente do servidor.
import { createHmac } from 'node:crypto';
import { readFile } from 'node:fs/promises';
const url = process.env.RB_WEBHOOK_URL;
const secret = process.env.RB_WEBHOOK_SECRET;
if (!url || !secret) throw new Error('Configure a URL e o segredo da conexão');
const rawBody = await readFile('evento.json');
const event = JSON.parse(rawBody.toString('utf8'));
const timestamp = String(Math.floor(Date.now() / 1000));
const signature = createHmac('sha256', secret)
.update(timestamp + '.')
.update(rawBody)
.digest('hex');
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-RB-Timestamp': timestamp,
'X-RB-Signature': 'sha256=' + signature,
'Idempotency-Key': event.event_id,
},
body: rawBody,
});
console.log(response.status, await response.text());
// Nas retentativas: mesmos bytes e event_id; novo timestamp e HMAC.
// Para corrigir o conteúdo: use um novo event_id e atualize Idempotency-Key.07 · Jornadas RB
Respostas e retentativas
{"accepted":true,"duplicate":false,"eventId":"10000000-0000-4000-8000-000000000001"}O 202 só é retornado após persistir a inbox. A repetição do mesmo evento com os mesmos bytes retorna 200 com duplicate:true. Mesmo ID com bytes diferentes retorna 409 RB_JOURNEYS_IDEMPOTENCY_CONFLICT. A regra persiste após reinício e serializa eventos por conexão para evitar corridas. Para corrigir conteúdo, gere novo event_id.
| HTTP | Significado / ação |
|---|---|
| 400 | JSON ou identificador inválido. Corrija a requisição. |
| 401 | Assinatura inválida ou expirada. Confira segredo, relógio e bytes. |
| 403 | Escopo divergente: confira acesso e empresa. |
| 404 | Conexão não encontrada. Confira a URL pública. |
| 409 | Conflito de payload; na API administrativa, também credencial ausente ao ativar. |
| 413 / 415 / 422 | Corpo acima de 1 MiB / tipo de conteúdo incorreto / contrato inválido. |
| 429 | Limite persistente de 120 requisições aceitas/repetidas por minuto e conexão. Retry-After: 60. |
| 503 | Jornadas pausadas ou conexão RB inativa. Retome antes de reenviar. |
Em falha de persistência, indisponibilidade ou pausa, não há 202. Repita com o mesmo corpo e ID, gerando novo timestamp/HMAC. Respeite o Retry-After e aplique espera crescente nas falhas transitórias. Receber o evento não confirma envio ou entrega no WhatsApp.
08 · Jornadas RB
Automações e dados de cada pedido
Mensagens, remetente e intervalos são definidos em Automações, origem Jornadas RB. Cada execução guarda o retrato do seu evento sem substituir metadados da cobrança.
| Gatilho | Marco dos intervalos | Identidade da execução |
|---|---|---|
| Venda convertida | occurred_at da conversão | Conexão, versão do acesso RB, empresa e pedido; uma entrada por automação. |
| Mercadoria liberada | occurred_at da liberação | Mesmo escopo + event_id. Liberações diferentes podem entrar novamente. |
| Venda entregue | occurred_at da entrega integral | Conexão, versão do acesso RB, empresa e pedido; uma entrada por automação. |
| Receita oftalmológica vencida | expires_at de cada receita, após venda_entregue | Mesmo escopo do pedido + receita e validade. |
| Aniversário | Data anual de nascimento em America/Sao_Paulo | Contato, automação e ano. Correção antes do envio substitui o agendamento. |
Datas sem horário usam meia-noite em São Paulo; o intervalo da automação determina o horário desejado.
rb.order_number
rb.order_total
rb.order_issued_at
rb.event_type
rb.company_id
rb.recipe_date
rb.recipe_expiry
rb.itemsA IA trata o conteúdo recebido como dados e não executa instruções contidas nele. O contato é identificado pelo vínculo RB existente ou por telefone único na mesma conta; contatos ambíguos não são escolhidos arbitrariamente.
09 · Jornadas RB
Cancelamento, consentimento e ordem de chegada
Cancelamento é definitivo na v1. Interrompe ações pendentes do pedido, empresa e acesso RB informados, inclusive ações preparadas pelo worker. Não altera Cobrança RB nem aniversários sem pedido. Evento antigo não reativa pedido cancelado. Uma chamada ao provedor já iniciada não pode ser desfeita.
Eventos de mensagens exigem customer.whatsapp_consent:true explícito. Cancelamento e revogação continuam aceitos sem telefone. A revogação é registrada antes de confirmar o ingresso, interrompe novas jornadas pendentes do contato e é revalidada imediatamente antes do disparo.
Prevalece a observação de consentimento mais recente; em empate, a revogação. Eventos atrasados não restauram permissão nem nascimento anterior. Novo consentimento explícito posterior à revogação pode autorizar jornadas futuras.
Não há erro genérico por evento fora de ordem: cada evento é persistido e avaliado por essas regras. Estornos, trocas, devoluções e reabertura estão fora da v1.
10 · Jornadas RB
Aniversários e importação
O aniversário usa a base estruturada: o RB não precisa enviar evento a cada aniversário. Nascimento recebido em conversão ou importação atualiza o perfil. A agenda anual usa America/Sao_Paulo; 29/02 vira 28/02 em anos não bissextos.
Correção de nascimento antes do envio substitui o agendamento. Após o envio, não cria outro aniversário no mesmo ano. Aniversários antigos não são recuperados retroativamente.
nome,telefone,data_nascimento,consentimento_whatsapp
Cliente,5541999990000,1990-01-02,Snome e telefone continuam obrigatórios. data_nascimento aceita AAAA-MM-DD ou DD/MM/AAAA; consentimento_whatsapp aceita S/N. A importação atualiza contatos existentes com autorização de edição da conta. Campos omitidos preservam os valores atuais; coluna de consentimento vazia não presume autorização.
11 · Jornadas RB
API administrativa da conexão
Requer sessão autenticada de administrador da conta. Todas as respostas usam Cache-Control: no-store. O :id identifica a conexão administrativa; o webhook utiliza seu identificador público.
| Método e rota | Corpo / resultado |
|---|---|
| GET /api/rb/connections/:id/journeys | Consulta settings no envelope {success:true,settings:{...}}. |
| POST /api/rb/connections/:id/journeys | {enabled:true|false}; retorna o mesmo envelope. Ativação exige credencial. |
| POST /api/rb/connections/:id/journeys/rotate-secret | Retorna {success:true,settings:{...},secret:"..."}. Única exibição do segredo. |
| POST /api/rb/connections/:id/journeys/retry | Repõe eventos bloqueados na fila com tentativas zeradas; retorna o envelope de settings. |
connectionId, publicConnectionId, webhookUrl, credentialConfigured,
enabled, status, lastReceivedAt, lastEventType, lastError,
pendingCount, blockedCountlastReceivedAt é a data de recebimento, não a ocorrência. pendingCount conta pendentes/em processamento; blockedCount, os que exigem intervenção. lastError inclui diagnósticos não resolvidos, como receita sem vencimento.
12 · Jornadas RB
Operação e publicação
- Aplique, nessa ordem,
20261020135424_rb_journeys_ingress.sqle20261020135625_rb_journeys_automations.sql. Dependem das migrations anteriores de RB, consultas de clientes e Automações. Execute o preflight de tabelas e colunas do repositório. - Configure a chave de criptografia e a URL pública do backend. Guarde a chave junto dos backups; o RB recebe somente o segredo da sua conexão.
- Publique backend, frontend e a função
import-leads-csv, incluindo_shared/lead-import-profile.ts,deno.jsone lockfile. O worker de Automações existente efetua os disparos. - Ative o worker de ingresso e homologue os eventos. Tentativas usam espera crescente; após oito falhas, o evento fica bloqueado e pode ser retomado pelo administrador. Processamento interrompido é recuperado após cinco minutos com novo identificador de tentativa, invalidando o anterior.
RB_JOURNEYS_SECRETS_ENCRYPTION_KEY=<32 bytes em hex ou base64>
RB_JOURNEYS_SECRETS_ENCRYPTION_KEY_VERSION=v1
CRM_BACKEND_PUBLIC_URL=<URL pública do backend>
RB_JOURNEYS_WORKER_ENABLED=true
RB_JOURNEYS_WORKER_POLL_MS=30000As credenciais são cifradas com AES-256-GCM. A versão identifica a chave configurada; trocar a chave exige migrar as credenciais cifradas, além de alterar a variável. Credenciais/inbox e RPCs são restritos ao serviço; nenhum disparo ocorre no HTTP de ingresso.
Pausar Jornadas RB retorna 503 para novos eventos e posterga processamento e disparos pendentes, preservando a fila. Retomar continua o trabalho. Trocar o acesso/base RB invalida execuções da identidade anterior; eventos aceitos não são transferidos à nova identidade.
13 · Jornadas RB
Checklist de homologação
- Validar a publicação, migrations, chave, worker e conexão ativa no ambiente de destino.
- Homologar os cinco tipos de evento; só enviar venda_entregue após a entrega integral.
- Validar 202 persistido, repetição 200 e conflito 409 para o mesmo ID com bytes diferentes.
- Rejeitar assinatura expirada/inválida e acesso ou empresa fora do escopo da conexão.
- Simular indisponibilidade, pausa/retomada e bloqueio por instância ambígua; recuperar sem duplicar ações.
- Validar execuções independentes de pedidos e liberações; conferir as oito variáveis RB.
- Testar cancelamento e revogação antes do disparo, eventos atrasados e novo consentimento posterior.
- Homologar receita sem validade e correção com novo evento, sem prazo presumido.
- Validar aniversário por evento/importação, correção de nascimento e política de 29/02.
- Testar rotação do segredo e alinhar o uso da credencial atual com o responsável RB.