SDK Java
☕ Java 11+ nativo: SDK oficial com HttpClient, CompletableFuture e zero dependências externas
O SDK Java permite integrar a Notifica em qualquer aplicação Java com suporte a sync e async. Este guia cobre:
- Instalação (Gradle & Maven)
- Envio de notificações (email, SMS, WhatsApp, in-app, push)
- Gerenciamento de subscribers, templates e workflows
- Webhooks e analytics
- Tratamento de erros
Instalação
Gradle
implementation 'com.notifica:notifica-java:1.0.0'
Gradle (Kotlin DSL)
implementation("com.notifica:notifica-java:1.0.0")
Maven
<dependency>
<groupId>com.notifica</groupId>
<artifactId>notifica-java</artifactId>
<version>1.0.0</version>
</dependency>
Requisitos: Java 11+ · Zero dependências externas (usa java.net.http.HttpClient)
Setup básico
Síncrono
import com.notifica.Notifica;
import com.notifica.models.*;
var notifica = new Notifica("nk_live_sua_chave");
var notification = notifica.notifications().send(new SendNotificationParams()
.channel("email")
.recipient("[email protected]")
.templateId("welcome")
.payload(Map.of("name", "Fernanda"))
);
System.out.println("Enviada: " + notification.id() + " — " + notification.status());
Assíncrono (CompletableFuture)
notifica.notifications().sendAsync(new SendNotificationParams()
.channel("email")
.recipient("[email protected]")
.templateId("welcome")
.payload(Map.of("name", "Fernanda"))
).thenAccept(n -> {
System.out.println("Enviada: " + n.id());
}).exceptionally(err -> {
System.err.println("Erro: " + err.getMessage());
return null;
});
Autenticação
// Chave de produção
var notifica = new Notifica("nk_live_sua_chave");
// Chave de sandbox (desenvolvimento)
var notifica = new Notifica("nk_test_sua_chave");
Use variáveis de ambiente para não commitar chaves no código:
var notifica = new Notifica(System.getenv("NOTIFICA_API_KEY"));
Configuração avançada
var notifica = Notifica.builder("nk_live_...")
// URL customizada (self-hosted ou staging)
.baseUrl("https://api.staging.notifica.com.br")
// Timeout
.timeout(Duration.ofSeconds(60))
// Retry com backoff exponencial
.maxRetries(5)
// HTTP client customizado
.httpClient(HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10))
.build())
.build();
| Opção | Padrão | Descrição |
|---|---|---|
baseUrl | https://api.notifica.com.br | URL base da API |
timeout | 30s | Timeout de requisições |
maxRetries | 3 | Tentativas com backoff exponencial |
httpClient | HttpClient.newHttpClient() | HTTP client customizado |
Enviando notificações
Todas as notificações são assíncronas e retornam status accepted (202).
Email
var n = notifica.notifications().send(new SendNotificationParams()
.channel("email")
.recipient("[email protected]")
.templateId("order-confirmation")
.payload(Map.of(
"name", "Roberto",
"orderId", "ORD-12345"
))
);
WhatsApp
var n = notifica.notifications().send(new SendNotificationParams()
.channel("whatsapp")
.recipient("+5511998765432")
.templateId("welcome")
.payload(Map.of(
"customerName", "João",
"company", "Acme"
))
);
SMS
var n = notifica.notifications().send(new SendNotificationParams()
.channel("sms")
.recipient("+5511998765432")
.payload(Map.of("content", "Seu código é: 583921"))
);
In-App
var n = notifica.notifications().send(new SendNotificationParams()
.channel("in_app")
.recipient("subscriber-id-aqui")
.payload(Map.of(
"title", "Novo comentário",
"body", "Maria comentou na sua tarefa #123"
))
);
Com chave de idempotência
var n = notifica.notifications().send(new SendNotificationParams()
.channel("email")
.recipient("[email protected]")
.templateId("payment-receipt")
.payload(Map.of("amount", "R$ 99,90"))
.idempotencyKey("payment-12345")
);
Tracking de entrega
Ver status de uma notificação
var n = notifica.notifications().get("notification-id");
System.out.println(n.status()); // "delivered"
System.out.println(n.deliveredAt()); // 2024-01-15T14:30:05Z
Listar tentativas de entrega
var attempts = notifica.notifications().listAttempts("notification-id");
for (var a : attempts) {
System.out.printf("Tentativa %d: %s (%s)%n", a.attemptNumber(), a.status(), a.provider());
}
Listar notificações com filtros
var page = notifica.notifications().list(new ListNotificationsParams()
.status("failed")
.channel("email")
.limit(50)
);
for (var n : page.data()) {
System.out.println(n.id() + " " + n.status());
}
// Paginação via cursor
if (page.meta().hasMore()) {
var nextPage = notifica.notifications().list(new ListNotificationsParams()
.cursor(page.meta().cursor())
);
}
Subscribers (Assinantes)
Criar ou atualizar (upsert)
var sub = notifica.subscribers().create(new CreateSubscriberParams()
.externalId("user-123")
.email("[email protected]")
.phone("+5511999999999")
.name("Maria Silva")
.customProperties(Map.of("plan", "pro", "company", "Acme"))
);
Listar com busca
var page = notifica.subscribers().list(new ListSubscribersParams()
.search("maria")
.limit(20)
);
System.out.printf("Encontrados: %d subscribers%n", page.total());
Atualizar
var sub = notifica.subscribers().update("subscriber-id",
new UpdateSubscriberParams().name("Maria Santos")
);
Deletar (LGPD)
notifica.subscribers().delete("subscriber-id");
Preferências de notificação
// Consultar
var prefs = notifica.subscribers().getPreferences("subscriber-id");
// Atualizar
notifica.subscribers().setPreferences("subscriber-id", List.of(
new PreferenceInput("marketing", "email", false),
new PreferenceInput("transacional", "email", true)
));
Importação em massa
var result = notifica.subscribers().bulkImport(List.of(
new CreateSubscriberParams().externalId("user-1").email("[email protected]").name("Ana"),
new CreateSubscriberParams().externalId("user-2").email("[email protected]").name("Bruno")
));
System.out.printf("Importados: %d subscribers%n", result.imported());
Templates
Criar template
var tmpl = notifica.templates().create(new CreateTemplateParams()
.channel("email")
.slug("welcome")
.name("Email de Boas-vindas")
.content("Olá {{name}}, bem-vindo ao {{company}}!")
.status("published")
);
Preview com dados de exemplo
var result = notifica.templates().preview("template-id",
Map.of("name", "Maria", "company", "Acme")
);
System.out.println(result.output()); // "Olá Maria, bem-vindo ao Acme!"
Validar template
var result = notifica.templates().validate("template-id");
if (!result.valid()) {
System.out.println("Erros: " + result.errors());
}
Workflows
Criar e disparar workflow
// Criar
var wf = notifica.workflows().create(new CreateWorkflowParams()
.slug("onboarding")
.name("Onboarding do Usuário")
.steps(List.of(
Map.of("type", "send", "channel", "email", "template", "welcome"),
Map.of("type", "delay", "duration", "24h"),
Map.of("type", "send", "channel", "email", "template", "getting-started")
))
);
// Disparar
var run = notifica.workflows().trigger("onboarding", new TriggerWorkflowParams()
.recipient("user-123")
.data(Map.of("name", "João", "plan", "pro"))
);
System.out.println("Run: " + run.id() + " — " + run.status());
// Cancelar
notifica.workflows().cancelRun("run-id");
Webhooks
Criar webhook
var wh = notifica.webhooks().create(new CreateWebhookParams()
.url("https://api.empresa.com/webhooks/notifica")
.events(List.of("notification.sent", "notification.delivered", "notification.failed"))
);
System.out.println("Secret (guarde!): " + wh.secret());
Listar deliveries
var page = notifica.webhooks().listDeliveries("webhook-id", 50);
for (var d : page.data()) {
System.out.printf("Evento: %s, HTTP: %d%n", d.eventType(), d.responseStatus());
}
Domínios de envio
// Registrar
var domain = notifica.domains().create("mail.empresa.com.br");
// Verificar
domain = notifica.domains().verify(domain.id());
// Health check
var health = notifica.domains().checkHealth(domain.id());
System.out.printf("SPF: %s, DKIM: %s, DMARC: %s%n",
health.spf().status(), health.dkim().status(), health.dmarc().status());
Analytics
// Resumo
var overview = notifica.analytics().overview("7d");
System.out.printf("Enviados: %d, Entregues: %d, Falhas: %d%n",
overview.sent(), overview.delivered(), overview.failed());
// Por canal
var stats = notifica.analytics().byChannel("30d");
for (var s : stats) {
System.out.printf("%s: %d enviados%n", s.channel(), s.sent());
}
// Top templates
var top = notifica.analytics().topTemplates("30d", 5);
Audit Logs (Admin Only)
Audit logs requerem autenticação admin (Bearer token do backoffice). Não estão disponíveis com API keys regulares (nk_live_... ou nk_test_...).
Rastreie ações sensíveis na sua organização:
- API Keys: created, rotated, revoked
- Team Members: invited, removed, role_changed
- Subscriptions: created, plan_changed, cancelled, payment_failed
- Domains: added, verified, removed
- Webhooks: created, updated, deleted
import com.notifica.sdk.models.AuditLog;
import com.notifica.sdk.models.ListAuditLogsParams;
import com.notifica.sdk.models.common.PaginatedResponse;
// Listar logs recentes
PaginatedResponse<AuditLog> result = notifica.audit().list(
new ListAuditLogsParams().setLimit(50)
);
for (AuditLog log : result.getData()) {
System.out.printf("%s by %s at %s%n",
log.getAction(), log.getActor().getName(), log.getCreatedAt());
}
// Filtrar por tipo de ação
var apiKeyLogs = notifica.audit().list(
new ListAuditLogsParams()
.setAction("api_key.created")
.setLimit(20)
);
// Filtrar por tipo de recurso
var webhookLogs = notifica.audit().list(
new ListAuditLogsParams()
.setResourceType("webhook")
);
// Filtrar por período
var logs = notifica.audit().list(
new ListAuditLogsParams()
.setStartDate("2024-01-01T00:00:00Z")
.setEndDate("2024-01-31T23:59:59Z")
);
// Obter um audit log específico
AuditLog log = notifica.audit().get("audit_abc123");
// Async
notifica.audit().listAsync(new ListAuditLogsParams().setLimit(50))
.thenAccept(page -> {
for (AuditLog l : page.getData()) {
System.out.println(l.getAction());
}
});
Filtros disponíveis
| Parâmetro | Tipo | Descrição |
|---|---|---|
action | String | Filtrar por ação (ex: api_key.created) |
resourceType | String | Filtrar por tipo de recurso (api_key, webhook, etc.) |
resourceId | String | Filtrar por ID do recurso |
actorType | String | Filtrar por tipo de ator (user, api_key, system) |
actorId | String | Filtrar por ID do ator |
startDate | String | Data inicial (ISO 8601) |
endDate | String | Data final (ISO 8601) |
Tratamento de erros
import com.notifica.exceptions.*;
try {
notifica.notifications().send(params);
} catch (ValidationException e) {
// 422: Dados inválidos
System.out.println("Campos inválidos: " + e.details());
} catch (RateLimitException e) {
// 429: Limite excedido
System.out.println("Rate limited");
} catch (NotFoundException e) {
// 404: Recurso não encontrado
} catch (NotificaException e) {
// Qualquer erro da API
System.out.printf("HTTP %d | %s: %s%n", e.statusCode(), e.code(), e.message());
}
O SDK faz retry automático com backoff exponencial para erros 429 e 5xx. Configure maxRetries(0) para desabilitar.
Integração com Spring Boot
@Configuration
public class NotificaConfig {
@Bean
public Notifica notificaClient(@Value("${notifica.api-key}") String apiKey) {
return new Notifica(apiKey);
}
}
@RestController
public class NotificationController {
@Autowired
private Notifica notifica;
@PostMapping("/send-welcome")
public ResponseEntity<?> sendWelcome(@RequestBody WelcomeRequest req) {
var n = notifica.notifications().send(new SendNotificationParams()
.channel("email")
.recipient(req.email())
.templateId("welcome")
.payload(Map.of("name", req.name()))
);
return ResponseEntity.ok(Map.of(
"notificationId", n.id(),
"status", n.status()
));
}
}
# application.yml
notifica:
api-key: ${NOTIFICA_API_KEY}
FAQ
Q: Qual a versão mínima do Java?
A: Java 11+. O SDK usa java.net.http.HttpClient nativo.
Q: Preciso de alguma dependência externa? A: Não. Zero dependências. O SDK usa apenas a stdlib do Java.
Q: Como funciona o async?
A: Todos os métodos possuem uma variante *Async() que retorna CompletableFuture<T>.
Q: Funciona com Kotlin? A: Sim. API fluida funciona naturalmente em Kotlin.
Q: O SDK é thread-safe?
A: Sim. A instância de Notifica pode ser compartilhada entre threads.
Links
- Maven Central: search.maven.org/artifact/com.notifica/notifica-java
- GitHub: github.com/notifica-tech/notifica-java
- API Reference: API Reference
- Templates: Email Templates
- Webhooks: Webhooks