Getting started

This walks you through adding notify4j to a Spring Boot app and sending your first notification. For the engine without Spring, see Architecture.

1. Requirements

  • Java 17+

  • Spring Boot 4.x (for the starter)

2. 1. Add the dependency

The starter transitively pulls in notify4j-core:

<dependency>
    <groupId>org.alexmond</groupId>
    <artifactId>notify4j-spring-boot-starter</artifactId>
    <version>0.2.0</version>
</dependency>

To align versions across modules, import the BOM in <dependencyManagement>:

<dependency>
    <groupId>org.alexmond</groupId>
    <artifactId>notify4j-bom</artifactId>
    <version>0.2.0</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

3. 2. Provide a NotificationAdapter

notify4j is domain-agnostic: it never references your event type directly. You supply one NotificationAdapter<E> bean that maps your event to the three things every channel needs — a stable id (used to detect status transitions), a status, and a human message.

@Bean
NotificationAdapter<BuildEvent> buildAdapter() {
    return new NotificationAdapter<>() {
        public Object id(BuildEvent e)      { return e.getBuildId(); }
        public String status(BuildEvent e)  { return e.getStatus(); }   // e.g. "FAILED"
        public String message(BuildEvent e) { return e.describe(); }
    };
}

Once this bean exists, the starter auto-configures a Notifications<BuildEvent> facade.

4. 3. Declare channels

List channels as Apprise-style URLs in application.yml:

notify4j:
  urls:
    - slack://hooks.slack.com/services/T000/B000/XXXX
    - pagerduty://<routing-key>?tags=failed

5. 4. Send

Inject the facade and call send:

@Service
class BuildListener {

    private final Notifications<BuildEvent> notifications;

    BuildListener(Notifications<BuildEvent> notifications) {
        this.notifications = notifications;
    }

    void onBuild(BuildEvent event) {
        notifications.send(event);                       // all untagged channels
        // or route to a subset by tag:
        notifications.send(event, List.of("failed"));    // only channels tagged "failed"
    }
}

By default notify4j only fires on meaningful status transitions and skips intermediate states (PENDING/RUNNING/ASSIGNED) — so a build that goes RUNNING → FAILED notifies once, on FAILED. See transition filtering.

6. Try the sample

The notify4j-sample module is a runnable Spring Boot app wired exactly as above; its application.yml ships a commented example of every channel. Build it with:

./mvnw -Pdefault -pl notify4j-sample spring-boot:run

With no channels configured it still fans the demo event out to the always-on logging sink.