Notificações
Visão Geral
O módulo de notificações do RiskFlow permite o envio de alertas e mensagens para os usuários através de múltiplos canais (sistema interno, e-mail, push e SMS). Integrado com a plataforma Novu, este módulo gerencia assinantes, preferências de notificação e o envio de mensagens para eventos importantes do fluxo de aprovação por alçada.
Endpoints
1. Verificar Status da Integração
Verifica se a integração com a plataforma Novu está funcionando corretamente.
GET /api/notificacoes/status
Exemplo de Requisição (cURL)
curl -X GET \
'http://localhost:3000/api/notificacoes/status' \
-H 'x-api-key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
Exemplo de Requisição (JavaScript - Fetch API)
const token = localStorage.getItem('token');
fetch('http://localhost:3000/api/notificacoes/status', {
method: 'GET',
headers: {
'x-api-key': token
}
})
.then(response => response.json())
.then(data => console.log('Status da integração:', data))
.catch(error => console.error('Erro ao verificar status da integração:', error));
Exemplo de Requisição (Node.js - Axios)
const axios = require('axios');
const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...';
axios.get('http://localhost:3000/api/notificacoes/status', {
headers: {
'x-api-key': token
}
})
.then(response => {
console.log('Status da integração:', response.data);
})
.catch(error => console.error('Erro ao verificar status da integração:', error));
Resposta de Sucesso (200 OK)
{
"status": "conectado",
"plataforma": "Novu",
"versao_api": "0.15.0",
"canais_disponiveis": ["email", "push", "sms", "chat"],
"templates_configurados": 8,
"ultima_verificacao": "2025-06-03T16:30:00Z"
}
Resposta de Erro (500 Internal Server Error)
{
"error": {
"message": "Erro na conexão com a plataforma de notificações",
"code": "NOTIFICATION_PLATFORM_ERROR",
"details": "API Key inválida ou serviço indisponível",
"requestId": "550e8400-e29b-41d4-a716-446655440000"
}
}
2. Criar ou Atualizar Assinante
Cria ou atualiza um assinante na plataforma de notificações.
PUT /api/notificacoes/assinantes/:subscriberId
Parâmetros de URL
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| subscriberId | string | Sim | ID do assinante (geralmente o ID do usuário) |
Corpo da Requisição
{
"email": "[email protected]",
"nome": "Nome do Usuário",
"telefone": "+5511999999999",
"dados": {
"cargo": "Analista",
"departamento": "Crédito",
"preferencias": {
"email": true,
"push": true,
"sms": false
}
}
}
Exemplo de Requisição (cURL)
curl -X PUT \
'http://localhost:3000/api/notificacoes/assinantes/550e8400-e29b-41d4-a716-446655440003' \
-H 'Content-Type: application/json' \
-H 'x-api-key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' \
-d '{
"email": "[email protected]",
"nome": "Nome do Usuário",
"telefone": "+5511999999999",
"dados": {
"cargo": "Analista",
"departamento": "Crédito",
"preferencias": {
"email": true,
"push": true,
"sms": false
}
}
}'
Exemplo de Requisição (JavaScript - Fetch API)
const token = localStorage.getItem('token');
const subscriberId = '550e8400-e29b-41d4-a716-446655440003';
const assinante = {
email: "[email protected]",
nome: "Nome do Usuário",
telefone: "+5511999999999",
dados: {
cargo: "Analista",
departamento: "Crédito",
preferencias: {
email: true,
push: true,
sms: false
}
}
};
const requestOptions = {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'x-api-key': token
},
body: JSON.stringify(assinante)
};
fetch(`http://localhost:3000/api/notificacoes/assinantes/${subscriberId}`, requestOptions)
.then(response => response.json())
.then(data => console.log('Assinante criado/atualizado:', data))
.catch(error => console.error('Erro ao criar/atualizar assinante:', error));
Resposta de Sucesso (200 OK)
{
"subscriberId": "550e8400-e29b-41d4-a716-446655440003",
"email": "[email protected]",
"nome": "Nome do Usuário",
"telefone": "+5511999999999",
"dados": {
"cargo": "Analista",
"departamento": "Crédito",
"preferencias": {
"email": true,
"push": true,
"sms": false
}
},
"status": "ativo",
"canais_ativos": ["email", "push"],
"mensagem": "Assinante criado/atualizado com sucesso"
}
3. Adicionar Token para Notificações Push
Adiciona um token de dispositivo para notificações push.
POST /api/notificacoes/assinantes/:subscriberId/tokens
Parâmetros de URL
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| subscriberId | string | Sim | ID do assinante (geralmente o ID do usuário) |
Corpo da Requisição
{
"token": "fcm-token-example-123456789",
"plataforma": "fcm"
}
Exemplo de Requisição (cURL)
curl -X POST \
'http://localhost:3000/api/notificacoes/assinantes/550e8400-e29b-41d4-a716-446655440003/tokens' \
-H 'Content-Type: application/json' \
-H 'x-api-key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' \
-d '{
"token": "fcm-token-example-123456789",
"plataforma": "fcm"
}'
Exemplo de Requisição (Node.js - Axios)
const axios = require('axios');
const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...';
const subscriberId = '550e8400-e29b-41d4-a716-446655440003';
const tokenData = {
token: "fcm-token-example-123456789",
plataforma: "fcm"
};
axios.post(`http://localhost:3000/api/notificacoes/assinantes/${subscriberId}/tokens`, tokenData, {
headers: {
'Content-Type': 'application/json',
'x-api-key': token
}
})
.then(response => {
console.log('Token adicionado:', response.data);
})
.catch(error => console.error('Erro ao adicionar token:', error));
Resposta de Sucesso (200 OK)
{
"subscriberId": "550e8400-e29b-41d4-a716-446655440003",
"token": "fcm-token-example-123456789",
"plataforma": "fcm",
"status": "ativo",
"data_criacao": "2025-06-03T16:45:00Z",
"mensagem": "Token adicionado com sucesso"
}
4. Remover Token para Notificações Push
Remove um token de dispositivo para notificações push.
POST /api/notificacoes/assinantes/:subscriberId/tokens/remover
Parâmetros de URL
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| subscriberId | string | Sim | ID do assinante (geralmente o ID do usuário) |
Corpo da Requisição
{
"token": "fcm-token-example-123456789"
}
Exemplo de Requisição (cURL)
curl -X POST \
'http://localhost:3000/api/notificacoes/assinantes/550e8400-e29b-41d4-a716-446655440003/tokens/remover' \
-H 'Content-Type: application/json' \
-H 'x-api-key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' \
-d '{
"token": "fcm-token-example-123456789"
}'
Exemplo de Requisição (JavaScript - Fetch API)
const token = localStorage.getItem('token');
const subscriberId = '550e8400-e29b-41d4-a716-446655440003';
const requestOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': token
},
body: JSON.stringify({
token: "fcm-token-example-123456789"
})
};
fetch(`http://localhost:3000/api/notificacoes/assinantes/${subscriberId}/tokens/remover`, requestOptions)
.then(response => response.json())
.then(data => console.log('Token removido:', data))
.catch(error => console.error('Erro ao remover token:', error));
Resposta de Sucesso (200 OK)
{
"subscriberId": "550e8400-e29b-41d4-a716-446655440003",
"token": "fcm-token-example-123456789",
"status": "removido",
"data_remocao": "2025-06-03T17:00:00Z",
"mensagem": "Token removido com sucesso"
}
5. Enviar Notificação Personalizada
Envia uma notificação personalizada para um ou mais assinantes.
POST /api/notificacoes/enviar
Corpo da Requisição
{
"template": "nova_analise",
"destinatarios": ["550e8400-e29b-41d4-a716-446655440003", "550e8400-e29b-41d4-a716-446655440004"],
"dados": {
"codigo_analise": "ANL-2025-0001",
"tipo_analise": "Análise de Crédito",
"cliente": "Empresa ABC Ltda",
"valor": 500000.00,
"moeda": "BRL",
"prazo_sla": "2025-06-10T14:30:00Z",
"url_analise": "http://localhost:3000/analises/550e8400-e29b-41d4-a716-446655440000"
},
"canais": ["email", "push", "sistema"]
}
Exemplo de Requisição (cURL)
curl -X POST \
'http://localhost:3000/api/notificacoes/enviar' \
-H 'Content-Type: application/json' \
-H 'x-api-key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' \
-d '{
"template": "nova_analise",
"destinatarios": ["550e8400-e29b-41d4-a716-446655440003", "550e8400-e29b-41d4-a716-446655440004"],
"dados": {
"codigo_analise": "ANL-2025-0001",
"tipo_analise": "Análise de Crédito",
"cliente": "Empresa ABC Ltda",
"valor": 500000.00,
"moeda": "BRL",
"prazo_sla": "2025-06-10T14:30:00Z",
"url_analise": "http://localhost:3000/analises/550e8400-e29b-41d4-a716-446655440000"
},
"canais": ["email", "push", "sistema"]
}'
Exemplo de Requisição (Node.js - Axios)
const axios = require('axios');
const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...';
const notificacao = {
template: "nova_analise",
destinatarios: ["550e8400-e29b-41d4-a716-446655440003", "550e8400-e29b-41d4-a716-446655440004"],
dados: {
codigo_analise: "ANL-2025-0001",
tipo_analise: "Análise de Crédito",
cliente: "Empresa ABC Ltda",
valor: 500000.00,
moeda: "BRL",
prazo_sla: "2025-06-10T14:30:00Z",
url_analise: "http://localhost:3000/analises/550e8400-e29b-41d4-a716-446655440000"
},
canais: ["email", "push", "sistema"]
};
axios.post('http://localhost:3000/api/notificacoes/enviar', notificacao, {
headers: {
'Content-Type': 'application/json',
'x-api-key': token
}
})
.then(response => {
console.log('Notificação enviada:', response.data);
})
.catch(error => console.error('Erro ao enviar notificação:', error));
Resposta de Sucesso (200 OK)
{
"status": "enviado",
"template": "nova_analise",
"destinatarios": {
"total": 2,
"sucesso": 2,
"falha": 0
},
"canais": {
"email": {
"enviados": 2,
"falhas": 0
},
"push": {
"enviados": 1,
"falhas": 1,
"motivo_falha": "Token não encontrado para um destinatário"
},
"sistema": {
"enviados": 2,
"falhas": 0
}
},
"ids_notificacao": ["550e8400-e29b-41d4-a716-446655440100", "550e8400-e29b-41d4-a716-446655440101"],
"timestamp": "2025-06-03T17:15:00Z"
}
6. Notificar Nova Análise
Envia uma notificação específica para nova análise atribuída.
POST /api/notificacoes/analises/:subscriberId/nova
Parâmetros de URL
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| subscriberId | string | Sim | ID do assinante (geralmente o ID do usuário) |
Corpo da Requisição
{
"analise_id": "550e8400-e29b-41d4-a716-446655440000",
"codigo_analise": "ANL-2025-0001",
"tipo_analise": "Análise de Crédito",
"cliente": "Empresa ABC Ltda",
"valor": 500000.00,
"moeda": "BRL",
"prazo_sla": "2025-06-10T14:30:00Z",
"url_analise": "http://localhost:3000/analises/550e8400-e29b-41d4-a716-446655440000"
}
Exemplo de Requisição (cURL)
curl -X POST \
'http://localhost:3000/api/notificacoes/analises/550e8400-e29b-41d4-a716-446655440003/nova' \
-H 'Content-Type: application/json' \
-H 'x-api-key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' \
-d '{
"analise_id": "550e8400-e29b-41d4-a716-446655440000",
"codigo_analise": "ANL-2025-0001",
"tipo_analise": "Análise de Crédito",
"cliente": "Empresa ABC Ltda",
"valor": 500000.00,
"moeda": "BRL",
"prazo_sla": "2025-06-10T14:30:00Z",
"url_analise": "http://localhost:3000/analises/550e8400-e29b-41d4-a716-446655440000"
}'
Exemplo de Requisição (JavaScript - Fetch API)
const token = localStorage.getItem('token');
const subscriberId = '550e8400-e29b-41d4-a716-446655440003';
const dadosAnalise = {
analise_id: "550e8400-e29b-41d4-a716-446655440000",
codigo_analise: "ANL-2025-0001",
tipo_analise: "Análise de Crédito",
cliente: "Empresa ABC Ltda",
valor: 500000.00,
moeda: "BRL",
prazo_sla: "2025-06-10T14:30:00Z",
url_analise: "http://localhost:3000/analises/550e8400-e29b-41d4-a716-446655440000"
};
const requestOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': token
},
body: JSON.stringify(dadosAnalise)
};
fetch(`http://localhost:3000/api/notificacoes/analises/${subscriberId}/nova`, requestOptions)
.then(response => response.json())
.then(data => console.log('Notificação de nova análise enviada:', data))
.catch(error => console.error('Erro ao enviar notificação de nova análise:', error));
Resposta de Sucesso (200 OK)
{
"status": "enviado",
"tipo": "nova_analise",
"destinatario": "550e8400-e29b-41d4-a716-446655440003",
"analise_id": "550e8400-e29b-41d4-a716-446655440000",
"codigo_analise": "ANL-2025-0001",
"canais": {
"email": "enviado",
"push": "enviado",
"sistema": "enviado"
},
"id_notificacao": "550e8400-e29b-41d4-a716-446655440100",
"timestamp": "2025-06-03T17:30:00Z"
}
7. Notificar Análise Encaminhada
Envia uma notificação específica para análise encaminhada.
POST /api/notificacoes/analises/:subscriberId/encaminhada
Parâmetros de URL
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| subscriberId | string | Sim | ID do assinante (geralmente o ID do usuário) |
Corpo da Requisição
{
"analise_id": "550e8400-e29b-41d4-a716-446655440000",
"codigo_analise": "ANL-2025-0001",
"tipo_analise": "Análise de Crédito",
"cliente": "Empresa ABC Ltda",
"valor": 500000.00,
"moeda": "BRL",
"nivel_origem": {
"id": "550e8400-e29b-41d4-a716-446655440002",
"nome": "Analista"
},
"nivel_destino": {
"id": "550e8400-e29b-41d4-a716-446655440030",
"nome": "Gestor"
},
"usuario_origem": {
"id": "550e8400-e29b-41d4-a716-446655440003",
"nome": "João Silva"
},
"justificativa": "Valor excede alçada do nível atual",
"prazo_sla": "2025-06-10T14:30:00Z",
"url_analise": "http://localhost:3000/analises/550e8400-e29b-41d4-a716-446655440000"
}
Exemplo de Requisição (Node.js - Axios)
const axios = require('axios');
const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...';
const subscriberId = '550e8400-e29b-41d4-a716-446655440004';
const dadosEncaminhamento = {
analise_id: "550e8400-e29b-41d4-a716-446655440000",
codigo_analise: "ANL-2025-0001",
tipo_analise: "Análise de Crédito",
cliente: "Empresa ABC Ltda",
valor: 500000.00,
moeda: "BRL",
nivel_origem: {
id: "550e8400-e29b-41d4-a716-446655440002",
nome: "Analista"
},
nivel_destino: {
id: "550e8400-e29b-41d4-a716-446655440030",
nome: "Gestor"
},
usuario_origem: {
id: "550e8400-e29b-41d4-a716-446655440003",
nome: "João Silva"
},
justificativa: "Valor excede alçada do nível atual",
prazo_sla: "2025-06-10T14:30:00Z",
url_analise: "http://localhost:3000/analises/550e8400-e29b-41d4-a716-446655440000"
};
axios.post(`http://localhost:3000/api/notificacoes/analises/${subscriberId}/encaminhada`, dadosEncaminhamento, {
headers: {
'Content-Type': 'application/json',
'x-api-key': token
}
})
.then(response => {
console.log('Notificação de análise encaminhada enviada:', response.data);
})
.catch(error => console.error('Erro ao enviar notificação de análise encaminhada:', error));
Resposta de Sucesso (200 OK)
{
"status": "enviado",
"tipo": "analise_encaminhada",
"destinatario": "550e8400-e29b-41d4-a716-446655440004",
"analise_id": "550e8400-e29b-41d4-a716-446655440000",
"codigo_analise": "ANL-2025-0001",
"canais": {
"email": "enviado",
"push": "enviado",
"sistema": "enviado"
},
"id_notificacao": "550e8400-e29b-41d4-a716-446655440101",
"timestamp": "2025-06-03T17:45:00Z"
}
8. Notificar Alerta de SLA
Envia uma notificação específica para alerta de SLA.
POST /api/notificacoes/analises/:subscriberId/sla
Parâmetros de URL
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| subscriberId | string | Sim | ID do assinante (geralmente o ID do usuário) |
Corpo da Requisição
{
"analise_id": "550e8400-e29b-41d4-a716-446655440000",
"codigo_analise": "ANL-2025-0001",
"tipo_analise": "Análise de Crédito",
"cliente": "Empresa ABC Ltda",
"tipo_alerta": "proximo_vencimento",
"prazo_sla": "2025-06-05T14:30:00Z",
"tempo_restante": {
"dias": 1,
"horas": 23,
"minutos": 0
},
"nivel_atual": {
"id": "550e8400-e29b-41d4-a716-446655440002",
"nome": "Analista"
},
"url_analise": "http://localhost:3000/analises/550e8400-e29b-41d4-a716-446655440000"
}
Exemplo de Requisição (cURL)
curl -X POST \
'http://localhost:3000/api/notificacoes/analises/550e8400-e29b-41d4-a716-446655440003/sla' \
-H 'Content-Type: application/json' \
-H 'x-api-key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' \
-d '{
"analise_id": "550e8400-e29b-41d4-a716-446655440000",
"codigo_analise": "ANL-2025-0001",
"tipo_analise": "Análise de Crédito",
"cliente": "Empresa ABC Ltda",
"tipo_alerta": "proximo_vencimento",
"prazo_sla": "2025-06-05T14:30:00Z",
"tempo_restante": {
"dias": 1,
"horas": 23,
"minutos": 0
},
"nivel_atual": {
"id": "550e8400-e29b-41d4-a716-446655440002",
"nome": "Analista"
},
"url_analise": "http://localhost:3000/analises/550e8400-e29b-41d4-a716-446655440000"
}'
Resposta de Sucesso (200 OK)
{
"status": "enviado",
"tipo": "alerta_sla",
"subtipo": "proximo_vencimento",
"destinatario": "550e8400-e29b-41d4-a716-446655440003",
"analise_id": "550e8400-e29b-41d4-a716-446655440000",
"codigo_analise": "ANL-2025-0001",
"canais": {
"email": "enviado",
"push": "enviado",
"sistema": "enviado"
},
"id_notificacao": "550e8400-e29b-41d4-a716-446655440102",
"timestamp": "2025-06-03T18:00:00Z"
}
Templates de Notificação
O sistema utiliza os seguintes templates de notificação pré-configurados:
| Template | Descrição | Canais Suportados |
|---|---|---|
| nova_analise | Notifica sobre uma nova análise atribuída | email, push, sistema |
| analise_encaminhada | Notifica sobre uma análise encaminhada para outro nível | email, push, sistema |
| analise_aprovada | Notifica sobre a aprovação de uma análise | email, push, sistema |
| analise_reprovada | Notifica sobre a reprovação de uma análise | email, push, sistema |
| analise_devolvida | Notifica sobre a devolução de uma análise para complementação | email, push, sistema |
| alerta_sla_proximo | Alerta sobre SLA próximo de vencer | email, push, sistema, sms |
| alerta_sla_vencido | Alerta sobre SLA vencido | email, push, sistema, sms |
| analise_cancelada | Notifica sobre o cancelamento de uma análise | email, push, sistema |
Integração com Novu
O sistema utiliza a plataforma Novu para gerenciar e enviar notificações. A integração é configurada através da variável de ambiente NOVU_API_KEY no arquivo .env.
Exemplo de Configuração do Novu
// Exemplo de configuração do cliente Novu
const { Novu } = require('@novu/node');
const novu = new Novu(process.env.NOVU_API_KEY);
// Exemplo de criação de assinante
async function criarAssinante(userId, email, nome) {
try {
const resultado = await novu.subscribers.identify(userId, {
email: email,
firstName: nome.split(' ')[0],
lastName: nome.split(' ').slice(1).join(' ')
});
return resultado.data;
} catch (error) {
console.error('Erro ao criar assinante:', error);
throw error;
}
}
// Exemplo de envio de notificação
async function enviarNotificacao(templateId, subscriberId, dados) {
try {
const resultado = await novu.trigger(templateId, {
to: {
subscriberId: subscriberId
},
payload: dados
});
return resultado.data;
} catch (error) {
console.error('Erro ao enviar notificação:', error);
throw error;
}
}
Melhores Práticas
- Personalização: Permita que os usuários personalizem suas preferências de notificação.
- Múltiplos Canais: Utilize múltiplos canais de notificação para garantir que as mensagens sejam recebidas.
- Agrupamento: Agrupe notificações relacionadas para evitar sobrecarga de mensagens.
- Conteúdo Relevante: Inclua apenas informações relevantes e acionáveis nas notificações.
- Links Diretos: Sempre inclua links diretos para as análises ou ações necessárias.
Próximos Passos
Agora que você entende como utilizar o sistema de notificações, pode explorar:
- Alertas de SLA - Para configurar alertas automáticos
- Fluxo de Aprovação por Alçada - Para entender os eventos que geram notificações
- Configuração do Novu - Para personalizar templates e canais de notificação