Notifications
@bext-stack/framework/notifications transforme un événement en messages sur plusieurs canaux. Vous décrivez une notification une fois — avec un toMail, toSms,
Méthode toSlack, toDatabase ou toWebhook — et notifier.send() la diffuse sur chaque canal des listes via() de la notification, renvoyant un résultat par canal. Il s'agit de la généralisation par les développeurs d'applications de la fonctionnalité Rust Courrier, calquée sur les canaux Notification + de Laravel.
Quand l'utiliser#
- Tout moment « dire quelque chose à l'utilisateur » : un reçu, une alerte, une réinitialisation de mot de passe.
- Lorsque le même événement doit atteindre plusieurs endroits (envoyez par e-mail à et un message intégré à l'application alimenter et un canal Slack ops).
- Lorsque vous souhaitez que les chaînes et leurs fournisseurs soient échangeables et testables.
Envoi#
import { createNotifier, mailChannel, smsChannel, databaseChannel } from "@bext-stack/framework/notifications";
const notifier = createNotifier([
mailChannel({ appId: "my-site" }), // real: bext's SDK email endpoint
smsChannel({ send: twilioSend }), // bext ships no SMS provider — inject one
databaseChannel({ model: Notifications }), // in-app feed via @bext-stack/framework/orm
]);
const InvoicePaid = {
via: () => ["mail", "database"],
toMail: (u) => ({ subject: "Paid", html: `<p>Thanks ${u.name}</p>` }),
toDatabase: (u) => ({ type: "invoice.paid", user_id: u.id, read: 0 }),
};
const results = await notifier.send(user, InvoicePaid);
// → { mail: { ok: true }, database: { ok: true, id: "42" } }
send() ne rejette jamais — un canal qui échoue ou échoue devient un
Résultat { ok: false, error } sans arrêter les autres. Une chaîne répertoriée dans
via() mais non enregistré est signalé ; une chaîne sans correspondance
La méthode to<Channel>() est ignorée ( { ok: true, skipped: true } ).
Canaux#
| Canal | Usine | Remarques |
|---|---|---|
mailChannel({ appId, deliver? }) |
POST sur le point de terminaison de messagerie du SDK de bouclage de bext ; injecter deliver pour les tests/transport personnalisé |
|
| SMS | smsChannel({ send }) |
pas de fournisseur intégré — vous injectez send (Twilio, Vonage,…). Ce module est l'abstraction ; le fournisseur est le vôtre |
| Mou | slackChannel({ webhookUrl?, deliver? }) |
messages sur un webhook entrant |
| Dans l'application | databaseChannel({ model }) |
conserve une ligne dans n'importe quel create(data) - compose avec le ORM pour un flux de notification |
| Webhook | webhookChannel({ url?, deliver? }) |
POST une charge utile JSON |
| Coutume | defineChannel(name, send) |
créez le vôtre à partir d'un fn asynchrone |
Chaque canal résout sa destination à partir du message ( toMail().to ) ou du destinataire ( recipient.email / recipient.phone ), de sorte qu'un Notification reste indépendant du transport.
bext n'a délibérément pas de fournisseur de SMS. smsChannel existe donc votre code dépend de l'abstraction, pas de Twilio — remplacez le send injecté par un faux dans les tests et par le vrai client en production sans toucher à un seul site d'appel.
Essai#
Parce que le transport de chaque canal est injectable, le tout est testable unitairement sans réseau : transmettez un deliver / send qui enregistre les appels et utilisez un
Modèle ORM soutenu par bun:sqlite pour le canal de base de données.
Essayez-le#
Le démo des notifications en direct envoie un message par e-mail + Slack (simulé) + un flux réel persistant dans l'application - envoyez-en un et regardez les résultats par canal et la mise à jour du flux. Source dans
sites/demo/src/app/examples/notifications/page.tsx.
Voir aussi#
- Courrier — la fonctionnalité de messagerie Rust qui se généralise.
- Données et migrations — l'ORM via lequel le canal intégré à l'application persiste.
- Boîte à outils de candidature — le reste de la couche d'application TypeScript.