Milesoft Notifications SDK (notifications-sdk)
1. Overview
The Notifications SDK (notifications-sdk) provides a strongly-typed programmatic client for orchestrating cross-channel messaging and tenant communications inside the Milesoft platform. It supports managing user delivery preferences, issuing direct push notifications, publishing message payloads to broad topic cohorts, dispatching transactional emails via SMTP, and processing system events across different client-facing channels (Push, App persist, Email, Mobile).
2. Initialization
2.1 Dependency Installation
The notifications-sdk package is hosted in our secure Google Cloud Artifact Registry repository.
To consume notifications-sdk in your Spring Boot application, apply the Google Cloud Artifact Registry plugin and declare our secure repository in your build.gradle:
plugins {
id "com.google.cloud.artifactregistry.gradle-plugin" version "2.2.5"
}
repositories {
mavenCentral()
maven { url "artifactregistry://us-west2-maven.pkg.dev/milesoft-repo/repo-maven" }
}
dependencies {
// Declaring the standard notifications-sdk library dependency
implementation "io.milesoft:notifications-sdk:2.1.0"
}
2.2 Central Spring Boot Configuration
Configure the underlying clients and NotificationService helper class inside your Spring configuration layer.
import io.milesoft.clients.PlatformClient;
import io.milesoft.clients.strategy.PlatformTokenProvider;
import io.milesoft.notifications.client.v2.EventClient;
import io.milesoft.notifications.client.v2.NotificationClient;
import io.milesoft.notifications.client.v2.PreferencesClient;
import io.milesoft.notifications.services.NotificationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class NotificationsSdkConfig {
private final NotificationClient notificationClient;
private final EventClient eventClient;
private final PreferencesClient preferencesClient;
private final NotificationService notificationService;
@Autowired
public NotificationsSdkConfig(PlatformClient platformClient,
@Value("${milesoft.notifications.baseUrl}") String baseUrl) {
PlatformTokenProvider tokenProvider = new PlatformTokenProvider(platformClient);
this.notificationClient = new NotificationClient(baseUrl, tokenProvider);
this.eventClient = new EventClient(baseUrl, tokenProvider);
this.preferencesClient = new PreferencesClient(baseUrl, tokenProvider);
this.notificationService = new NotificationService(notificationClient, eventClient);
}
@Bean
public NotificationClient notificationClient() { return notificationClient; }
@Bean
public EventClient eventClient() { return eventClient; }
@Bean
public PreferencesClient preferencesClient() { return preferencesClient; }
@Bean
public NotificationService notificationService() { return notificationService; }
}
3. Core SDK Clients & Method Specifications
Programmatic execution is managed across logical clients designed to completely abstract the underlying REST boundaries.
3.1 NotificationClient
Manages direct notifications and inboxes.
Notifications list(String cursor, Integer limit, Actor actor): Paginated fetch of the active user's notification inbox.List<Notification> loadBulk(Ids payload, Actor actor): Loads specific notifications by their unique IDs.Notification create(SaveNotification payload, Actor actor): Creates and delivers a direct notification to targeted recipients.void markAsRead(Ids payload, Actor actor): Marks a batch of notifications as read.void delete(String id, Actor actor): Deletes a specific notification.void deleteBulk(Ids payload, Actor actor): Deletes multiple notifications in a single batch.void pushToTopic(PushToTopic payload, Actor actor): Broadcasts a direct push notification to an FCM topic.
3.2 EventClient
Triggers audience-based platform system events.
boolean emit(EmitEvent payload, Actor actor): Emits an event to explicit recipients, letting preference matrices dictate channel routing.boolean push(PushEvent payload, Actor actor): Broadcasts an event to a registered topic channel.
3.3 PreferencesClient
Tracks user device tokens and subscriptions.
Preferences load(Actor actor): Loads active caller's delivery channel configurations.Preferences update(Preferences payload, Actor actor): Saves active user's FCM registration tokens and topic channel subscription mappings.
3.4 NotificationService
A high-level convenience helper aggregating notifications and events propagation acting under active user contexts.
List<Receipt> emit(Notification notification, Recipients recipients): Emits a notification to a specific cohort.boolean emit(Event event, Recipients recipients): Emits an event to a targeted cohort.
4. Built-In SDK Capabilities
- 🔒 Map Guardrails (
@MapGuard): Generic payload and metadata contexts are validated at the gateway to protect parsing engines from heap-bloat and DoS vulnerabilities:- Maximum Key Count: 100 unique keys per map.
- Maximum Nesting Depth: 5 nested levels.
- Key Pattern: Must be alphanumeric matching
^[a-zA-Z0-9_\-]{1,256}$.
- Intelligent Routing: Channels are evaluated dynamically. If a billing alert targets a cohort of 50 users, the engine parses each operator's customized
Preferencesmap to resolve whether to dispatch via Push, App persist, or transactional Email.
5. Code Examples
5.1 Dispatching Direct Cohort Alerts
import io.milesoft.notifications.services.NotificationService;
import io.milesoft.notifications.domain.Notification;
import io.milesoft.notifications.domain.Recipients;
import io.milesoft.notifications.domain.Receipt;
import io.milesoft.primitives.actor.Actor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class BillingNotificationService {
private final NotificationService notificationService;
@Autowired
public BillingNotificationService(NotificationService notificationService) {
this.notificationService = notificationService;
}
public void dispatchOverdueInvoiceAlert(Actor actor, String title, String description, List<String> clientUserIds) {
// Construct targeted recipients
Recipients recipients = Recipients.builder()
.users(false)
.admins(false)
.includeIds(clientUserIds)
.excludeIds(List.of())
.build();
// Construct notification payload
Notification notification = Notification.builder()
.type("billing_alert")
.mail(true)
.title(title)
.description(description)
.gotoUrl("/billing/invoices")
.build();
// Emit over the platform
List<Receipt> receipts = notificationService.emit(notification, recipients);
for (Receipt receipt : receipts) {
System.out.println("Alert successfully delivered to user " + receipt.getUserId() + " via " + receipt.getMethod());
}
}
}
5.2 Emitting Platform System Events
import io.milesoft.notifications.services.NotificationService;
import io.milesoft.notifications.domain.Event;
import io.milesoft.notifications.domain.Recipients;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
@Component
public class RewardEventEngine {
private final NotificationService notificationService;
public RewardEventEngine(NotificationService notificationService) {
this.notificationService = notificationService;
}
public void triggerRewardUnlockedEvent(String userId, String rewardName, int pointsAmount) {
Recipients recipients = Recipients.builder()
.users(false)
.admins(false)
.includeIds(List.of(userId))
.excludeIds(List.of())
.build();
Event event = Event.builder()
.type("reward_unlocked")
.payload(Map.of("reward", rewardName, "amount", pointsAmount))
.build();
boolean success = notificationService.emit(event, recipients);
if (success) {
System.out.println("System event successfully emitted over the platform.");
}
}
}
6. SDK Data Transfer Objects (DTOs)
SaveNotification
Structure used to submit/create a direct notification.
| Field | Type | Description / Constraints |
|---|---|---|
type |
String |
Semantic type/category of the notification (e.g., billing_alert). Required / Not Blank. |
mail |
Boolean |
Indicates whether SMTP email delivery should also be executed. Required / Not Null. |
title |
String |
The title heading of the notification. Required / Not Blank. |
description |
String |
Longer description body of the notification. |
gotoUrl |
String |
Deep-link redirection path triggered when a user clicks the notification. |
emailExtra |
String |
Supplemental content parsed solely into the email template body. |
payload |
Map<String, Object> |
Raw key-value context details linked to the notification. Subject to @MapGuard. |
metadata |
Map<String, Object> |
Extra key-value metadata parameters. Subject to @MapGuard. |
data |
MergeData |
Structured template variables for Liquid engine compilation. |
recipients |
Recipients |
Targeted cohort filters mapping the intended recipients. Required / Not Null. |
Notification
Schema representing a persistent notification record retrieved from the database.
| Field | Type | Description / Constraints |
|---|---|---|
id |
String |
The unique database identifier of the notification. Required / Not Blank. |
type |
String |
The semantic category of the notification. Required / Not Blank. |
mail |
Boolean |
Indicates whether email delivery was processed. Required / Not Null. |
state |
NotificationState |
The reading status of the notification (New, Read). Required / Not Null. |
title |
String |
The header title. Required / Not Blank. |
description |
String |
The long description text. Required / Not Blank. |
gotoUrl |
String |
Deep-link redirection target path. |
metadata |
Map<String, Object> |
Key-value meta data fields. Subject to @MapGuard. |
created |
ZonedDateTime |
Timestamp indicating creation. Required / Not Null. |
updated |
ZonedDateTime |
Timestamp marking last state modification. Required / Not Null. |
Recipients
Scoping criteria defining targeted user recipient groups.
| Field | Type | Description / Constraints |
|---|---|---|
users |
Boolean |
If true, targets all standard active tenant users. Required / Not Null. |
admins |
Boolean |
If true, targets all tenant administrators. Required / Not Null. |
supers |
Boolean |
If true, targets all system super-users. Required / Not Null. |
includeIds |
List<String> |
Specific User IDs whitelist. Required / Not Null. |
excludeIds |
List<String> |
Specific User IDs blacklist. Required / Not Null. |
Preferences
User-specific configuration mapping messaging tokens and channel selections.
| Field | Type | Description / Constraints |
|---|---|---|
messagingToken |
String |
FCM device messaging token registered by mobile/web clients. |
deliveries |
Map<String, DeliveryMethod> |
Map indexing notification types to delivery methods (None, Mobile, App, Email). Required / Not Null. |
topics |
Map<String, Boolean> |
Map indexing topics to subscription statuses (True if subscribed). Required / Not Null. |
Receipt
Delivery confirmation object generated for each successful dispatch channel attempt.
| Field | Type | Description / Constraints |
|---|---|---|
userId |
String |
Target user's system identifier. Required / Not Blank. |
to |
String |
Channel endpoint used (e.g., email address, device token). Required / Not Blank. |
method |
DeliveryMethod |
Channel mechanism executed (None, Mobile, App, Email). Required / Not Null. |
Receipts
Wrapping container holding a list of delivery confirmations.
| Field | Type | Description / Constraints |
|---|---|---|
receipts |
List<Receipt> |
List of delivery confirmations. Required / Not Null. |
EmitEvent
Specifies parameters to trigger an audience-based system event.
| Field | Type | Description / Constraints |
|---|---|---|
type |
String |
Semantic event identifier matching liquid templates. Required / Not Blank. |
payload |
Map<String, Object> |
Raw key-value contextual data. Subject to @MapGuard. |
data |
MergeData |
Template compilation merge values. |
recipients |
Recipients |
Recipient audience definitions. Required / Not Null. |
PushEvent
Specifies parameters to trigger a topic-wide system event broadcast.
| Field | Type | Description / Constraints |
|---|---|---|
topic |
String |
Active topic name to broadcast the event to. Required / Not Blank. |
payload |
Map<String, Object> |
Raw key-value contextual data. Subject to @MapGuard. |
data |
MergeData |
Template compile merge variables. |
PushToTopic
Broadcasts a direct push notification to all users subscribed to a specific topic channel.
| Field | Type | Description / Constraints |
|---|---|---|
topic |
String |
Unique topic name. Required / Not Blank. |
title |
String |
The push notification title text. Required / Not Blank. |
gotoUrl |
String |
The redirection deep-link. |
payload |
Map<String, Object> |
Key-value context payload. Subject to @MapGuard. |
data |
MergeData |
Template merge fields. |
Topic
Subscription mapping associating standard topic channels to the user.
| Field | Type | Description / Constraints |
|---|---|---|
type |
String |
Semantic topic identifier. Required / Not Blank. |
subscribed |
Boolean |
Boolean registration status. Required / Not Null. |
Delivery
Type mapping linking specific notification keys to preferred delivery methods.
| Field | Type | Description / Constraints |
|---|---|---|
type |
String |
Unique notification type identifier. Required / Not Blank. |
method |
DeliveryMethod |
Preferred delivery method selection. Required / Not Null. |
Ids
Utility request envelope payload packaging multiple document identifiers.
| Field | Type | Description / Constraints |
|---|---|---|
ids |
List<String> |
Collection of system identifiers. Required / Not Null. |
MergeData
Template context package used by the template-compilation engines.
| Field | Type | Description / Constraints |
|---|---|---|
userId |
String |
Contextual user identifier. |
contactId |
String |
Contextual contact identifier. |
userQualifiers |
List<Qualifier> |
Qualifier-based routing filters for user attributes. |
contactQualifiers |
List<Qualifier> |
Qualifier-based routing filters for contact attributes. |
models |
List<Model> |
Nested list of rich objects loaded into template context. |
Qualifier
Filtering parameter mapping within MergeData.
| Field | Type | Description / Constraints |
|---|---|---|
key |
String |
Filter identifier field. Required / Not Blank. |
id |
String |
Filter argument value. Required / Not Blank. |
Model
A data model object dictionary evaluated inside dynamic template frameworks.
| Field | Type | Description / Constraints |
|---|---|---|
key |
String |
Variable name inside template parsing (e.g., invoice). Required / Not Blank. |
data |
Map<String, Object> |
Nested fields/properties of the target model object. Required / Not Null. |
Enums
DeliveryMethod
The configured delivery mechanics supporting different dispatch options:
None: Triggers event-only emissions (no visual delivery).Mobile: Sends push notifications directly to registered FCM mobile/web devices.App: Sends push notifications to FCM and persists the notification inside the user's persistent inbox (Firestore database).Email: Delivers via FCM push, persists in the user's inbox, and constructs/dispatches a transactional email via the SMTP connector.
NotificationState
Reflects reading status in user inboxes:
NewRead