Krizaka
Toutes les briques

krizaka-notifications

Notifications

E-mail, SMS et webhooks derrière un seul événement : les applications ne parlent plus jamais à un serveur SMTP.

Le problème qu'elle supprime

Un e-mail envoyé dans une transaction annulée ne se rattrape pas.

Chaque service qui envoie ses propres e-mails embarque un client SMTP, des gabarits et des relances. Une panne du fournisseur devient un bug dans chacun d'eux, et un e-mail envoyé dans une transaction ensuite annulée ne se rattrape pas.

  • Une inscription qui échoue parce que le serveur de mail est lent.
  • Un e-mail de bienvenue pour un compte dont la création a été annulée.
  • Le même message relivré qui envoie deux fois le même e-mail.

Ce qu'elle fait

  • Publiez evt.notification.requested dans votre transaction — aucun client SMTP dans votre service.
  • Des gabarits texte par langue, en en repli.
  • E-mail (SMTP), SMS (Twilio) ou webhook vers des hôtes autorisés : la même requête.

Un service qui consomme evt.notification.requested (et les événements utilisateurs), rend un gabarit dans la langue demandée et livre sur le canal voulu : SMTP, SMS Twilio ou webhook HTTP.

Le pigeon livre chaque message une fois — ou échoue là où vous le voyez. Un canal non configuré échoue et part en dead-letter ; il n'est jamais sauté en silence.

La règle du pigeon

Décisions et compromis

  1. Nous avons choisi

    Un événement, publié par l'outbox du producteur.

    Nous avons refusé

    Un endpoint HTTP synchrone « envoie un e-mail ».

    Parce que

    Pas d'e-mail pour un changement annulé ; une panne SMTP retarde le courrier au lieu de faire échouer les inscriptions ; une relivraison n'est envoyée qu'une fois (dédupliquée par messageId).

    Ce que cela vous coûte

    RabbitMQ entre votre application et le service.

  2. Nous avons choisi

    Des gabarits texte sur disque, un fichier par gabarit et par langue, repli sur en, un dossier que vous pouvez pointer ailleurs sans recompiler.

    Nous avons refusé

    Un moteur de gabarits HTML, pour l'instant.

    Parce que

    Un gabarit qu'une personne non développeuse peut modifier, et rien à rendre qui puisse casser.

    Ce que cela vous coûte

    Texte brut uniquement aujourd'hui.

  3. Nous avons choisi

    Des webhooks uniquement vers des hôtes en liste blanche (vide = pas de webhook).

    Nous avons refusé

    N'importe quelle URL envoyée par le demandeur.

    Parce que

    Un webhook ouvert est une falsification de requête côté serveur (SSRF) qui attend son heure.

    Ce que cela vous coûte

    Vous déclarez les hôtes.

En code

javaOrderService.java
@Transactional
public Order confirm(Order order) {
  Order confirmed = orders.save(order.confirmed());
  // Not an SMTP call: an event in the same transaction. The service renders and delivers it.
  events.publish(NotificationRouting.NOTIFICATION_REQUESTED, 1,
      new NotificationRequest(Channel.EMAIL, confirmed.email(), "order-confirmed", "fr-FR",
          Map.of("order", confirmed.number())));
  return confirmed;
}

// templates/order-confirmed/fr.txt — first line "Subject: …", then {{order}}; "en" is the fallback.
// SMS (Twilio) and WEBHOOK (allow-listed hosts) are the same request with another Channel.

Ne l'utilisez pas quand

  • Il vous faut le suivi d'ouverture et de clic, des campagnes ou des e-mails HTML riches : prenez un service d'e-mail marketing.
  • Votre application n'a pas de broker de messages et n'en veut pas.
  • Il vous faut des notifications push mobiles : pas encore un canal (Orochia utilise le service push d'Expo de son côté).

Où elle en est

0.1.0 sur Maven Central (le contrat -api). Le service se construit depuis les sources ou en image ; la 0.2.0 sort en novembre.

Publié

En cours

  • Le BOM 0.2.0 gère cette brique en 0.2.0, non publiée : déclarez 0.1.0 explicitement jusqu'au BOM 0.3.0.krizaka-build#11

L'adopter

xmlpom.xml
<dependency>
  <groupId>com.krizaka</groupId>
  <artifactId>krizaka-notifications-api</artifactId>
  <version>0.1.0</version>
</dependency>
<!-- the service itself: ./mvnw -pl krizaka-notifications-service -am spring-boot:run (port 8097) -->

Dites-nous où ça coince.

Une brique est juste quand elle survit à votre code, pas au nôtre. Posez votre question dans le fil de la brique, proposez un changement comme idée, ou signalez un bug sur son dépôt — chaque décision de cette page reste ouverte à un meilleur argument.

Les autres briques