Skip to main content
Pour ajouter un mode d’envoi de notifications depuis un package, concevez séparément le choix du canal et la détermination du destinataire. Cette page prend l’exemple d’un petit canal qui consigne des événements d’exploitation dans les logs, et explique le chemin de résolution des classes fournies par le package ainsi que les vérifications nécessaires lors des mises à jour. Si vous le remplacez par un envoi vers un service externe, la répartition des responsabilités entre canal et notification reste la même. Cette page s’appuie sur l’implémentation du Laravel Framework v13.38.0. Pour les opérations de base sur les notifications, consultez Notifications ; pour l’environnement de test du package, consultez Tester un package.

Le nom de classe désigne le mode d’envoi, la route désigne le destinataire

Le nom de classe de canal renvoyé par via() indique sur quel objet appeler send(). La valeur obtenue via routeNotificationFor(), en revanche, est le destinataire utilisé par ce canal. Les deux n’ont pas besoin de porter le même nom. NotificationSender transmet le nom de canal choisi par via() à ChannelManager::driver(). Si ChannelManager ne trouve ce nom ni parmi les noms intégrés ni parmi les noms enregistrés, et que le nom correspond à une classe existante, il résout cette classe via le conteneur. Si vous l’utilisez uniquement par nom de classe, ni Notification::extend() ni service provider de package ne sont nécessaires. Assurez-vous simplement que l’autoload de Composer trouve la classe et que le conteneur peut résoudre les dépendances du constructeur.

Fournir le canal lui-même dans le package

Le package d’exemple Acme\OperationsLog consigne des noms d’événements ne contenant aucune information sensible, accompagnés du nom de l’équipe d’exploitation destinataire. Dans une application Laravel, Psr\Log\LoggerInterface est lié au service de logs : vous pouvez donc le recevoir dans le constructeur.
L’objet reçu est soit un modèle utilisant le trait Notifiable, soit un destinataire à la demande créé par Notification::route(). Dans le premier cas, c’est routeNotificationForOperationsLog() qui fournit la valeur ; dans le second, c’est la valeur enregistrée avec route('operationsLog', ...). Pour éviter de considérer la notification comme envoyée en l’absence de destinataire, cet exemple lève une exception. Si vous le remplacez par un véritable envoi externe, vérifiez également le destinataire et le résultat de l’envoi, et ne masquez pas un échec en le traitant comme un succès.
N’incluez ni jetons d’accès ni données personnelles dans les noms d’événements ou les destinataires consignés dans les logs. Cet exemple est un envoi vers les logs destiné à illustrer la résolution du canal et les tests ; il ne s’agit pas d’une implémentation d’envoi vers un service externe.

Définir la notification et le destinataire côté application

La notification de l’application renvoie la classe du canal et définit uniquement le message transmis au canal. Avec ShouldQueue et Queueable, un appel classique à notify() passe par la file d’attente.
Lorsque vous indiquez le destinataire à la volée, la clé de Notification::route() n’est pas le nom de classe du canal, mais la clé utilisée dans le canal avec routeNotificationFor('operationsLog', ...).
Pour envoyer depuis un modèle de l’application, ajoutez la méthode suivante au modèle qui utilise Notifiable.
Avec $user->notify(new HealthCheckPassed()) sur ce modèle, le même canal est sélectionné. Configurez une connexion de file d’attente et lancez un worker qui traite la file operations-log.
OperationsLogChannel lui-même est conservé par le Manager pour chaque canal : ne stockez donc ni le destinataire ni le contenu de la notification dans les propriétés du canal, et récupérez-les à chaque fois depuis les arguments de send(). Ainsi, même un worker de file d’attente qui tourne longtemps ne conserve pas les informations de la notification précédente.

Si vous avez besoin d’un alias court

Uniquement si vous voulez permettre aux utilisateurs d’indiquer dans via() un nom court plutôt qu’un nom de classe, utilisez Notification::extend() dans le service provider habituel du package.
Faites charger le provider avant le début de l’envoi, par exemple grâce à la découverte automatique des packages. Dans les notifications qui utilisent l’alias, remplacez via() par ['acme-operations-log'] et utilisez ce même nom comme clé de viaQueues(). operationsLog, utilisé pour récupérer le destinataire, est une clé distincte et n’a pas besoin d’être modifié. Choisissez un nom qui n’entre pas en conflit avec les noms de canaux intégrés. Le Manager conserve les canaux résolus par nom. Même si vous réenregistrez le traitement de création de l’alias dans le même processus, l’instance déjà créée n’est pas remplacée. Vérifiez aussi tout changement de méthode d’enregistrement dans une application ou un worker fraîchement démarré.

Tester l’envoi indépendamment de fake

Notification::fake() sert à vérifier l’intention d’envoyer une notification. Il ne permet pas de confirmer que send() du canal ou la récupération de la route fonctionnent. Pour tester l’envoi, utilisez le vrai Manager de notifications et remplacez LoggerInterface par une version de test. L’exemple suivant s’exécute depuis le TestCase de Testbench. Avec notifyNow(), le traitement du canal s’exécute sans lancer de worker, même pour une notification ShouldQueue.
Vérifiez en outre qu’une exception est levée en l’absence de destinataire et, si vous fournissez un alias, qu’il se résout depuis un démarrage à neuf. Si vous passez par la file d’attente, testez aussi, dans une application de vérification qui fait tourner un worker séparé, que le job arrive dans la file operations-log et qu’il est traité. NotificationSender découpe les notifications ShouldQueue en un job par canal et choisit la file d’après la clé de viaQueues(). Si send() du canal lève une exception, il déclenche NotificationFailed puis relance l’exception ; s’il se termine normalement, il déclenche NotificationSent. Les paramètres de nouvelle tentative de la file suivent la configuration de l’application. Notez que si vous masquez l’exception à l’intérieur du canal, un envoi échoué sera traité comme un succès.

Sources primaires consultées

Dernière modification le 22 octobre 2026