Canaux de notification personnalisés dans un package et vérification de l'envoi
Découvrez comment fournir un canal de notification Laravel 13 depuis un package : résolution par nom de classe, routage des destinataires, mise en file d’attente et tests de l’envoi réel.
Écouter la pageenviron 7 min
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.
Emplacement
Exemple de cette page
Rôle
via() de la notification
OperationsLogChannel::class
Résolution du canal et envoi
Route de l’objet notifiable
operationsLog → operations
Destinataire utilisé dans le canal
viaQueues() de la notification
OperationsLogChannel::class → operations-log
File de destination du job en cas de mise en file d’attente
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.
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.
<?phpnamespace Acme\OperationsLog;use Illuminate\Notifications\Notification;use InvalidArgumentException;use Psr\Log\LoggerInterface;final class OperationsLogChannel{ public function __construct(private readonly LoggerInterface $logger) { } public function send(object $notifiable, Notification $notification): void { $destination = $notifiable->routeNotificationFor('operationsLog', $notification); if (! is_string($destination) || $destination === '') { throw new InvalidArgumentException('Operations log destination is required.'); } $this->logger->info('Operations notification', [ 'destination' => $destination, 'event' => $notification->toOperationsLog($notifiable), ]); }}
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.
<?phpnamespace App\Notifications;use Acme\OperationsLog\OperationsLogChannel;use Illuminate\Bus\Queueable;use Illuminate\Contracts\Queue\ShouldQueue;use Illuminate\Notifications\Notification;class HealthCheckPassed extends Notification implements ShouldQueue{ use Queueable; public function via(object $notifiable): array { return [OperationsLogChannel::class]; } public function toOperationsLog(object $notifiable): string { return 'health-check-passed'; } public function viaQueues(): array { return [OperationsLogChannel::class => 'operations-log']; }}
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', ...).
use App\Notifications\HealthCheckPassed;use Illuminate\Support\Facades\Notification;Notification::route('operationsLog', 'operations') ->notify(new HealthCheckPassed());
Pour envoyer depuis un modèle de l’application, ajoutez la méthode suivante au modèle qui utilise Notifiable.
use Illuminate\Notifications\Notification;public function routeNotificationForOperationsLog(Notification $notification): string{ return 'operations';}
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.
php artisan queue:work --queue=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.
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.
<?phpnamespace Acme\OperationsLog;use Illuminate\Support\Facades\Notification;use Illuminate\Support\ServiceProvider;class OperationsLogServiceProvider extends ServiceProvider{ public function boot(): void { Notification::extend( 'acme-operations-log', fn ($app) => $app->make(OperationsLogChannel::class), ); }}
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é.
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.
<?phpnamespace Acme\OperationsLog\Tests;use Acme\OperationsLog\OperationsLogChannel;use Illuminate\Bus\Queueable;use Illuminate\Contracts\Queue\ShouldQueue;use Illuminate\Notifications\Notification as BaseNotification;use Illuminate\Support\Facades\Notification;use Orchestra\Testbench\TestCase;use Psr\Log\LoggerInterface;class OperationsLogChannelTest extends TestCase{ public function test_channel_writes_the_routed_event(): void { $notification = new class extends BaseNotification implements ShouldQueue { use Queueable; public function via(object $notifiable): array { return [OperationsLogChannel::class]; } public function toOperationsLog(object $notifiable): string { return 'health-check-passed'; } }; $logger = $this->createMock(LoggerInterface::class); $logger->expects($this->once())->method('info')->with( 'Operations notification', ['destination' => 'operations', 'event' => 'health-check-passed'], ); $this->app->instance(LoggerInterface::class, $logger); Notification::route('operationsLog', 'operations')->notifyNow($notification); }}
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.
{"docsConfig":{"theme":"aspen","$schema":"https://mintlify.com/docs.json","name":"Knowledge of Laravel","colors":{"primary":"#16A34A","light":"#07C983","dark":"#15803D"},"logo":{"light":"https://mintcdn.com/invokable/AuZ0xql2mAbUyZ99/logo/light.svg?fit=max\u0026auto=format\u0026n=AuZ0xql2mAbUyZ99\u0026q=85\u0026s=df0b7397202a6aa1c1f321620c5aa146","dark":"https://mintcdn.com/invokable/AuZ0xql2mAbUyZ99/logo/dark.svg?fit=max\u0026auto=format\u0026n=AuZ0xql2mAbUyZ99\u0026q=85\u0026s=a8a0340d86ff8aa90e9adfc98a0362d7","href":"/"},"favicon":"https://mintcdn.com/invokable/AuZ0xql2mAbUyZ99/favicon.svg?fit=max\u0026auto=format\u0026n=AuZ0xql2mAbUyZ99\u0026q=85\u0026s=8f5a03a681c95d31803fc237b5811065","api":{"playground":{"display":"simple"}},"navbar":{},"footer":{"socials":{"github":"https://github.com/invokable"}},"seo":{"metatags":{"canonical":"https://kawax.biz"},"indexing":"all"},"styling":{"eyebrows":"breadcrumbs","latex":true},"contextual":{"options":["copy","view","chatgpt","claude","perplexity","mcp","cursor","vscode"],"display":"header"},"interaction":{"drilldown":false},"metadata":{"timestamp":true},"navigation":{"languages":[{"language":"jp","default":true,"href":"jp/packages/laravel-boost-copilot-cli"},{"language":"en","href":"en/packages/laravel-boost-copilot-cli"},{"language":"de","href":"de/packages/laravel-boost-copilot-cli"},{"language":"es","href":"es/packages/laravel-boost-copilot-cli"},{"language":"fr","href":"fr/packages/laravel-boost-copilot-cli"},{"language":"it","href":"it/packages/laravel-boost-copilot-cli"},{"language":"ko","href":"ko/packages/laravel-boost-copilot-cli"},{"language":"nl","href":"nl/packages/laravel-boost-copilot-cli"},{"language":"zh-Hans","href":"zh-CN/packages/laravel-boost-copilot-cli"},{"language":"zh-Hant","href":"zh-TW/packages/laravel-boost-copilot-cli"}]}},"deployment":{"deploymentMetadataValue":{"subdomain":"invokable","hasAudioNarration":true,"actualSubdomain":"invokable","customDomains":["kawax.biz"],"gitSource":{"type":"github","owner":"kawax","repo":"mintlify-docs","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"feedback":{"thumbs":true,"agentFeedback":true},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6af4f8bb899645a1d83de491","clientVersion":"0.0.4111","searchFilterCounts":[{"language":"en","tag":"My Packages","count":145},{"language":"jp","tag":"マイパッケージ","count":145},{"language":"de","tag":"Meine Pakete","count":100},{"language":"es","tag":"Mis paquetes","count":100},{"language":"fr","tag":"Mes packages","count":100},{"language":"it","tag":"I miei pacchetti","count":100},{"language":"ko","tag":"My 패키지","count":100},{"language":"nl","tag":"Mijn packages","count":100},{"language":"zh-Hans","tag":"我的包","count":100},{"language":"zh-Hant","tag":"我的套件","count":100},{"language":"de","tag":"Fortgeschrittene Themen","count":82},{"language":"en","tag":"Advanced Topics","count":82},{"language":"es","tag":"Temas avanzados","count":82},{"language":"fr","tag":"Sujets avancés","count":82},{"language":"it","tag":"Argomenti avanzati","count":82},{"language":"jp","tag":"応用トピック","count":82},{"language":"ko","tag":"심화 주제","count":82},{"language":"nl","tag":"Geavanceerde onderwerpen","count":82},{"language":"zh-Hans","tag":"进阶主题","count":82},{"language":"zh-Hant","tag":"進階主題","count":82},{"language":"en","tag":"VOICEVOX","count":67},{"language":"jp","tag":"VOICEVOX","count":67},{"language":"de","tag":"Leitfaden","count":61},{"language":"en","tag":"Guide","count":61},{"language":"es","tag":"Guía","count":61},{"language":"fr","tag":"Guide","count":61},{"language":"it","tag":"Guida","count":61},{"language":"jp","tag":"ガイド","count":61},{"language":"ko","tag":"가이드","count":61},{"language":"nl","tag":"Gids","count":61},{"language":"zh-Hans","tag":"指南","count":61},{"language":"zh-Hant","tag":"指南","count":61},{"language":"de","tag":"Blog","count":47},{"language":"en","tag":"Blog","count":47},{"language":"es","tag":"Blog","count":47},{"language":"fr","tag":"Blog","count":47},{"language":"it","tag":"Blog","count":47},{"language":"jp","tag":"ブログ","count":47},{"language":"ko","tag":"블로그","count":47},{"language":"nl","tag":"Blog","count":47},{"language":"zh-Hans","tag":"博客","count":47},{"language":"zh-Hant","tag":"部落格","count":47},{"language":"en","tag":"VOICEVOX Engine API Reference","count":45},{"language":"jp","tag":"VOICEVOXエンジンAPIリファレンス","count":45},{"language":"de","tag":"Paketentwicklung","count":43},{"language":"de","tag":"GitHub Copilot","count":43},{"language":"en","tag":"Package Development","count":43},{"language":"en","tag":"GitHub Copilot","count":43},{"language":"es","tag":"Desarrollo de paquetes","count":43},{"language":"es","tag":"GitHub Copilot","count":43},{"language":"fr","tag":"Développement de packages","count":43},{"language":"fr","tag":"GitHub Copilot","count":43},{"language":"it","tag":"Sviluppo di pacchetti","count":43},{"language":"it","tag":"GitHub Copilot","count":43},{"language":"jp","tag":"パッケージ開発","count":43},{"language":"jp","tag":"GitHub Copilot","count":43},{"language":"ko","tag":"패키지 개발","count":43},{"language":"ko","tag":"GitHub Copilot","count":43},{"language":"nl","tag":"Package-ontwikkeling","count":43},{"language":"nl","tag":"GitHub Copilot","count":43},{"language":"zh-Hans","tag":"包开发","count":43},{"language":"zh-Hans","tag":"GitHub Copilot","count":43},{"language":"zh-Hant","tag":"套件開發","count":43},{"language":"zh-Hant","tag":"GitHub Copilot","count":43},{"language":"de","tag":"GitHub Copilot SDK for Laravel","count":41},{"language":"en","tag":"GitHub Copilot SDK for Laravel","count":41},{"language":"es","tag":"GitHub Copilot SDK for Laravel","count":41},{"language":"fr","tag":"GitHub Copilot SDK for Laravel","count":41},{"language":"it","tag":"GitHub Copilot SDK for Laravel","count":41},{"language":"jp","tag":"GitHub Copilot SDK for Laravel","count":41},{"language":"ko","tag":"GitHub Copilot SDK for Laravel","count":41},{"language":"nl","tag":"GitHub Copilot SDK for Laravel","count":41},{"language":"zh-Hans","tag":"GitHub Copilot SDK for Laravel","count":41},{"language":"zh-Hant","tag":"GitHub Copilot SDK for Laravel","count":41},{"language":"de","tag":"Tutorial","count":35},{"language":"en","tag":"Tutorial","count":35},{"language":"es","tag":"Tutorial","count":35},{"language":"fr","tag":"Tutoriel","count":35},{"language":"it","tag":"Tutorial","count":35},{"language":"jp","tag":"チュートリアル","count":35},{"language":"ko","tag":"튜토리얼","count":35},{"language":"nl","tag":"Tutorial","count":35},{"language":"zh-Hans","tag":"教程","count":35},{"language":"zh-Hant","tag":"教學","count":35},{"language":"de","tag":"SDK","count":27},{"language":"es","tag":"SDK","count":27},{"language":"fr","tag":"SDK","count":27},{"language":"it","tag":"SDK","count":27},{"language":"ko","tag":"SDK","count":27},{"language":"nl","tag":"SDK","count":27},{"language":"zh-Hans","tag":"SDK","count":27},{"language":"zh-Hant","tag":"SDK","count":27},{"language":"de","tag":"VOICEVOX","count":22},{"language":"es","tag":"VOICEVOX","count":22},{"language":"fr","tag":"VOICEVOX","count":22},{"language":"it","tag":"VOICEVOX","count":22},{"language":"ko","tag":"VOICEVOX","count":22},{"language":"nl","tag":"VOICEVOX","count":22},{"language":"zh-Hans","tag":"VOICEVOX","count":22},{"language":"zh-Hant","tag":"VOICEVOX","count":22}],"searchSettings":{"isFiltersEnabled":false,"showContentSnippets":true,"fullPageSearch":true}},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-rbac-roles","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"privacy":{"consentBanner":{"enabled":true}},"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"fr/advanced/package-notification-channels","slug":"/fr/advanced/package-notification-channels","pageMetadata":{"title":"Canaux de notification personnalisés dans un package et vérification de l'envoi","description":"Découvrez comment fournir un canal de notification Laravel 13 depuis un package : résolution par nom de classe, routage des destinataires, mise en file d'attente et tests de l'envoi réel.","href":"/fr/advanced/package-notification-channels"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Découvrez comment fournir un canal de notification Laravel 13 depuis un package : résolution par nom de classe, routage des destinataires, mise en file d’attente et tests de l’envoi réel.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,li:`li`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Mermaid,Table,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Mermaid)_missingMdxReference(`Mermaid`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[`Pour ajouter un mode d’envoi de notifications depuis un package, concevez séparément `,_jsx(_components.strong,{children:`le choix du canal`}),` et `,_jsx(_components.strong,{children:`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.`]}),`\n`,_jsxs(_components.p,{children:[`Cette page s’appuie sur l’implémentation du Laravel Framework `,_jsx(_components.code,{children:`v13.38.0`}),`. Pour les opérations de base sur les notifications, consultez `,_jsx(_components.a,{href:`/fr/notifications`,children:`Notifications`}),` ; pour l’environnement de test du package, consultez `,_jsx(_components.a,{href:`/fr/advanced/package-testing`,children:`Tester un package`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`le-nom-de-classe-désigne-le-mode-d’envoi-la-route-désigne-le-destinataire`,children:`Le nom de classe désigne le mode d’envoi, la route désigne le destinataire`}),`\n`,_jsxs(_components.p,{children:[`Le nom de classe de canal renvoyé par `,_jsx(_components.code,{children:`via()`}),` indique sur quel objet appeler `,_jsx(_components.code,{children:`send()`}),`. La valeur obtenue via `,_jsx(_components.code,{children:`routeNotificationFor()`}),`, en revanche, est le destinataire utilisé par ce canal. Les deux n’ont pas besoin de porter le même nom.`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Emplacement`}),_jsx(_components.th,{children:`Exemple de cette page`}),_jsx(_components.th,{children:`Rôle`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.code,{children:`via()`}),` de la notification`]}),_jsx(_components.td,{children:_jsx(_components.code,{children:`OperationsLogChannel::class`})}),_jsx(_components.td,{children:`Résolution du canal et envoi`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Route de l’objet notifiable`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`operationsLog`}),` → `,_jsx(_components.code,{children:`operations`})]}),_jsx(_components.td,{children:`Destinataire utilisé dans le canal`})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.code,{children:`viaQueues()`}),` de la notification`]}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`OperationsLogChannel::class`}),` → `,_jsx(_components.code,{children:`operations-log`})]}),_jsx(_components.td,{children:`File de destination du job en cas de mise en file d’attente`})]})]})]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`NotificationSender`}),` transmet le nom de canal choisi par `,_jsx(_components.code,{children:`via()`}),` à `,_jsx(_components.code,{children:`ChannelManager::driver()`}),`. Si `,_jsx(_components.code,{children:`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. `,_jsxs(_components.strong,{children:[`Si vous l’utilisez uniquement par nom de classe, ni `,_jsx(_components.code,{children:`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.`]}),`\n`,_jsx(Mermaid,{chart:`flowchart LR\n A[\"Choisir un nom de classe dans via()\"] --> B[\"ChannelManager::driver()\"]\n B --> C{\"Déjà résolu ?\"}\n C -->|Oui| D[\"Canal conservé\"]\n C -->|Non| E[\"Création par le conteneur\"]\n E --> D\n D --> F[\"send() récupère le destinataire et envoie\"]`}),`\n`,_jsx(Heading,{level:`2`,id:`fournir-le-canal-lui-même-dans-le-package`,children:`Fournir le canal lui-même dans le package`}),`\n`,_jsxs(_components.p,{children:[`Le package d’exemple `,_jsx(_components.code,{children:`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, `,_jsx(_components.code,{children:`Psr\\\\Log\\\\LoggerInterface`}),` est lié au service de logs : vous pouvez donc le recevoir dans le constructeur.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`28`,language:`php`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`php`,children:_jsxs(_components.code,{language:`php`,numberOfLines:`28`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c?`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`php`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`namespace`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` Acme\\\\OperationsLog`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`use`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` Illuminate\\\\Notifications\\\\`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`Notification`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`use`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` InvalidArgumentException`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`use`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` Psr\\\\Log\\\\`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`LoggerInterface`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`final`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` class`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` OperationsLogChannel`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` public`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` function`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` __construct`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`private`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` readonly`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` LoggerInterface`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $logger`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` public`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` function`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` send`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`object`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $notifiable`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`Notification`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $notification`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` void`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $destination`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $notifiable`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`routeNotificationFor`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'operationsLog'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`$notification`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`!`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` is_string`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`$destination`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`||`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $destination`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` ===`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` ''`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` throw`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` new`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` InvalidArgumentException`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'Operations log destination is required.'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` $this`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`logger`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`info`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'Operations notification'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, [`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'destination'`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $destination`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'event'`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $notification`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`toOperationsLog`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`$notifiable`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`),`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ]);`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`L’objet reçu est soit un modèle utilisant le trait `,_jsx(_components.code,{children:`Notifiable`}),`, soit un destinataire à la demande créé par `,_jsx(_components.code,{children:`Notification::route()`}),`. Dans le premier cas, c’est `,_jsx(_components.code,{children:`routeNotificationForOperationsLog()`}),` qui fournit la valeur ; dans le second, c’est la valeur enregistrée avec `,_jsx(_components.code,{children:`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`,_jsx(Warning,{children:_jsx(_components.p,{children:`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.`})}),`\n`,_jsx(Heading,{level:`2`,id:`définir-la-notification-et-le-destinataire-côté-application`,children:`Définir la notification et le destinataire côté application`}),`\n`,_jsxs(_components.p,{children:[`La notification de l’application renvoie la classe du canal et définit uniquement le message transmis au canal. Avec `,_jsx(_components.code,{children:`ShouldQueue`}),` et `,_jsx(_components.code,{children:`Queueable`}),`, un appel classique à `,_jsx(_components.code,{children:`notify()`}),` passe par la file d’attente.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`28`,language:`php`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`php`,children:_jsxs(_components.code,{language:`php`,numberOfLines:`28`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c?`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`php`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`namespace`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` App\\\\Notifications`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`use`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` Acme\\\\OperationsLog\\\\`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`OperationsLogChannel`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`use`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` Illuminate\\\\Bus\\\\`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`Queueable`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`use`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` Illuminate\\\\Contracts\\\\Queue\\\\`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`ShouldQueue`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`use`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` Illuminate\\\\Notifications\\\\`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`Notification`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`class`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` HealthCheckPassed`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` extends`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` Notification`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` implements`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` ShouldQueue`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` use`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` Queueable`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` public`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` function`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` via`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`object`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $notifiable`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` array`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`OperationsLogChannel`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`class`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`];`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` public`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` function`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` toOperationsLog`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`object`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $notifiable`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` string`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'health-check-passed'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` public`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` function`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` viaQueues`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`()`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` array`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`OperationsLogChannel`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`class`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =>`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'operations-log'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`];`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Lorsque vous indiquez le destinataire à la volée, la clé de `,_jsx(_components.code,{children:`Notification::route()`}),` n’est `,_jsx(_components.strong,{children:`pas le nom de classe du canal`}),`, mais la clé utilisée dans le canal avec `,_jsx(_components.code,{children:`routeNotificationFor('operationsLog', ...)`}),`.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`5`,language:`php`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`php`,children:_jsxs(_components.code,{language:`php`,numberOfLines:`5`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`use`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` App\\\\Notifications\\\\`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`HealthCheckPassed`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`use`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` Illuminate\\\\Support\\\\Facades\\\\`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`Notification`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`Notification`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`route`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'operationsLog'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'operations'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` ->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`notify`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`new`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` HealthCheckPassed`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`());`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Pour envoyer depuis un modèle de l’application, ajoutez la méthode suivante au modèle qui utilise `,_jsx(_components.code,{children:`Notifiable`}),`.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`6`,language:`php`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`php`,children:_jsxs(_components.code,{language:`php`,numberOfLines:`6`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`use`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` Illuminate\\\\Notifications\\\\`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`Notification`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`public`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` function`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` routeNotificationForOperationsLog`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`Notification`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $notification`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` string`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'operations'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Avec `,_jsx(_components.code,{children:`$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 `,_jsx(_components.code,{children:`operations-log`}),`.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`php`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` artisan`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` queue:work`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --queue=operations-log`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`OperationsLogChannel`}),` lui-même est conservé par le Manager pour chaque canal : `,_jsx(_components.strong,{children:`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 `,_jsx(_components.code,{children:`send()`}),`. Ainsi, même un worker de file d’attente qui tourne longtemps ne conserve pas les informations de la notification précédente.`]}),`\n`,_jsx(Heading,{level:`2`,id:`si-vous-avez-besoin-d’un-alias-court`,children:`Si vous avez besoin d’un alias court`}),`\n`,_jsxs(_components.p,{children:[`Uniquement si vous voulez permettre aux utilisateurs d’indiquer dans `,_jsx(_components.code,{children:`via()`}),` un nom court plutôt qu’un nom de classe, utilisez `,_jsx(_components.code,{children:`Notification::extend()`}),` dans le service provider habituel du package.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`17`,language:`php`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`php`,children:_jsxs(_components.code,{language:`php`,numberOfLines:`17`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c?`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`php`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`namespace`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` Acme\\\\OperationsLog`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`use`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` Illuminate\\\\Support\\\\Facades\\\\`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`Notification`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`use`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` Illuminate\\\\Support\\\\`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`ServiceProvider`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`class`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` OperationsLogServiceProvider`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` extends`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` ServiceProvider`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` public`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` function`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` boot`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`()`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` void`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` Notification`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`extend`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'acme-operations-log'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` fn`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`$app`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) => `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`$app`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`make`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`OperationsLogChannel`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`class`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`),`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` );`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Faites charger le provider avant le début de l’envoi, par exemple grâce à la `,_jsx(_components.a,{href:`/fr/advanced/package-discovery`,children:`découverte automatique des packages`}),`. Dans les notifications qui utilisent l’alias, remplacez `,_jsx(_components.code,{children:`via()`}),` par `,_jsx(_components.code,{children:`['acme-operations-log']`}),` et utilisez ce même nom comme clé de `,_jsx(_components.code,{children:`viaQueues()`}),`. `,_jsxs(_components.strong,{children:[_jsx(_components.code,{children:`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.`]}),`\n`,_jsx(_components.p,{children:`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é.`}),`\n`,_jsx(Heading,{level:`2`,id:`tester-l’envoi-indépendamment-de-fake`,children:`Tester l’envoi indépendamment de fake`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`Notification::fake()`}),` sert à vérifier `,_jsx(_components.strong,{children:`l’intention`}),` d’envoyer une notification. Il ne permet pas de confirmer que `,_jsx(_components.code,{children:`send()`}),` du canal ou la récupération de la route fonctionnent. Pour tester l’envoi, utilisez le vrai Manager de notifications et remplacez `,_jsx(_components.code,{children:`LoggerInterface`}),` par une version de test.`]}),`\n`,_jsxs(_components.p,{children:[`L’exemple suivant s’exécute depuis le `,_jsxs(_components.a,{href:`/fr/advanced/package-testing`,children:[_jsx(_components.code,{children:`TestCase`}),` de Testbench`]}),`. Avec `,_jsx(_components.code,{children:`notifyNow()`}),`, le traitement du canal s’exécute sans lancer de worker, même pour une notification `,_jsx(_components.code,{children:`ShouldQueue`}),`.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`41`,language:`php`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`php`,children:_jsxs(_components.code,{language:`php`,numberOfLines:`41`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c?`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`php`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`namespace`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` Acme\\\\OperationsLog\\\\Tests`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`use`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` Acme\\\\OperationsLog\\\\`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`OperationsLogChannel`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`use`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` Illuminate\\\\Bus\\\\`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`Queueable`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`use`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` Illuminate\\\\Contracts\\\\Queue\\\\`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`ShouldQueue`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`use`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` Illuminate\\\\Notifications\\\\`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`Notification`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` as`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` BaseNotification`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`use`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` Illuminate\\\\Support\\\\Facades\\\\`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`Notification`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`use`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` Orchestra\\\\Testbench\\\\`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`TestCase`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`use`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` Psr\\\\Log\\\\`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`LoggerInterface`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`class`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` OperationsLogChannelTest`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` extends`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` TestCase`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` public`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` function`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` test_channel_writes_the_routed_event`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`()`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` void`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $notification`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` new`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` class`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` extends`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` BaseNotification`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` implements`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` ShouldQueue`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` use`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` Queueable`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` public`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` function`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` via`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`object`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $notifiable`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` array`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`OperationsLogChannel`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`class`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`];`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` public`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` function`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` toOperationsLog`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`object`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $notifiable`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` string`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'health-check-passed'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` };`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $logger`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` $this`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`createMock`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`LoggerInterface`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`class`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` $logger`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`expects`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`$this`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`once`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`())`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`method`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'info'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`with`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'Operations notification'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'destination'`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =>`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'operations'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'event'`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =>`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'health-check-passed'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`],`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` );`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` $this`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`app`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`instance`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`LoggerInterface`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`class`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`$logger`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` Notification`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`route`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'operationsLog'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'operations'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`notifyNow`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`$notification`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`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 `,_jsx(_components.code,{children:`operations-log`}),` et qu’il est traité.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`NotificationSender`}),` découpe les notifications `,_jsx(_components.code,{children:`ShouldQueue`}),` en un job par canal et choisit la file d’après la clé de `,_jsx(_components.code,{children:`viaQueues()`}),`. Si `,_jsx(_components.code,{children:`send()`}),` du canal lève une exception, il déclenche `,_jsx(_components.code,{children:`NotificationFailed`}),` puis relance l’exception ; s’il se termine normalement, il déclenche `,_jsx(_components.code,{children:`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.`]}),`\n`,_jsx(Heading,{level:`2`,id:`sources-primaires-consultées`,children:`Sources primaires consultées`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`https://github.com/laravel/docs/blob/13.x/notifications.md#custom-channels`,children:`Documentation officielle de Laravel 13 : canaux de notification personnalisés et files d’attente`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`https://github.com/laravel/docs/blob/13.x/packages.md#package-discovery`,children:`Documentation officielle de Laravel 13 : découverte automatique des packages`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`https://github.com/laravel/framework/blob/v13.38.0/src/Illuminate/Notifications/ChannelManager.php`,children:`ChannelManager : résolution à partir du nom de classe`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`https://github.com/laravel/framework/blob/v13.38.0/src/Illuminate/Notifications/NotificationSender.php`,children:`NotificationSender : envoi, file d’attente et événements par canal`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`https://github.com/laravel/framework/blob/v13.38.0/src/Illuminate/Notifications/RoutesNotifications.php`,children:`RoutesNotifications et AnonymousNotifiable : routes des destinataires`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`https://github.com/laravel/framework/blob/v13.38.0/src/Illuminate/Support/Manager.php`,children:`Manager : conservation et extension des drivers`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`https://github.com/laravel/framework/blob/v13.38.0/src/Illuminate/Foundation/Application.php`,children:`Application : liaison de LoggerInterface`})}),`\n`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Canaux de notification personnalisés dans un package et vérification de l'envoi","description":"Découvrez comment fournir un canal de notification Laravel 13 depuis un package : résolution par nom de classe, routage des destinataires, mise en file d'attente et tests de l'envoi réel.","href":"/fr/advanced/package-notification-channels"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Le nom de classe désigne le mode d’envoi, la route désigne le destinataire","slug":"le-nom-de-classe-désigne-le-mode-d’envoi-la-route-désigne-le-destinataire","depth":2,"children":[]},{"title":"Fournir le canal lui-même dans le package","slug":"fournir-le-canal-lui-même-dans-le-package","depth":2,"children":[]},{"title":"Définir la notification et le destinataire côté application","slug":"définir-la-notification-et-le-destinataire-côté-application","depth":2,"children":[]},{"title":"Si vous avez besoin d’un alias court","slug":"si-vous-avez-besoin-d’un-alias-court","depth":2,"children":[]},{"title":"Tester l’envoi indépendamment de fake","slug":"tester-l’envoi-indépendamment-de-fake","depth":2,"children":[]},{"title":"Sources primaires consultées","slug":"sources-primaires-consultées","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"narration":{"path":"fr/advanced/package-notification-channels","locale":"fr","estimatedDurationSec":416},"subdomain":"invokable","siteName":"Knowledge of Laravel","title":"Canaux de notification personnalisés dans un package et vérification de l'envoi - Knowledge of Laravel","relatedPagesConfig":{"enabled":true,"limit":5,"mode":"automatic"},"navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{"jp":{"href":"/jp/advanced/package-notification-channels","matchLevel":1},"en":{"href":"/en/advanced/package-notification-channels","matchLevel":1},"de":{"href":"/de/advanced/package-notification-channels","matchLevel":1},"es":{"href":"/es/advanced/package-notification-channels","matchLevel":1},"fr":{"href":"/fr/advanced/package-notification-channels","matchLevel":0},"it":{"href":"/it/advanced/package-notification-channels","matchLevel":1},"ko":{"href":"/ko/advanced/package-notification-channels","matchLevel":1},"nl":{"href":"/nl/advanced/package-notification-channels","matchLevel":1},"zh-Hans":{"href":"/zh-CN/advanced/package-notification-channels","matchLevel":1},"zh-Hant":{"href":"/zh-TW/advanced/package-notification-channels","matchLevel":1}}},"lastModified":"2026-10-22T22:21:35.007Z","gitLastModified":"2026-10-22T22:21:00.000Z","originalFileLocation":"fr/advanced/package-notification-channels.mdx","locale":"fr"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Découvrez comment fournir un canal de notification Laravel 13 depuis un package : résolution par nom de classe, routage des destinataires, mise en file d\u0026#x27;attente et tests de l\u0026#x27;envoi réel.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Knowledge of Laravel\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/invokable/pboFjibLpJPX3oCo/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/invokable/pboFjibLpJPX3oCo/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/invokable/pboFjibLpJPX3oCo/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/invokable/pboFjibLpJPX3oCo/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/invokable/pboFjibLpJPX3oCo/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/invokable/pboFjibLpJPX3oCo/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/invokable/pboFjibLpJPX3oCo/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/invokable/pboFjibLpJPX3oCo/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/invokable/pboFjibLpJPX3oCo/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Canaux de notification personnalisés dans un package et vérification de l\u0026#x27;envoi - Knowledge of Laravel\">\u003cmeta data-mint-head property=\"og:description\" content=\"Découvrez comment fournir un canal de notification Laravel 13 depuis un package : résolution par nom de classe, routage des destinataires, mise en file d\u0026#x27;attente et tests de l\u0026#x27;envoi réel.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Knowledge of Laravel\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://kawax.biz/fr/advanced/package-notification-channels\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://invokable.mintlify.site/_mintlify/api/og/v2?division=D%C3%A9veloppement+de+packages\u0026amp;title=Canaux+de+notification+personnalis%C3%A9s+dans+un+package+et+v%C3%A9rification+de+l%27envoi\u0026amp;description=D%C3%A9couvrez+comment+fournir+un+canal+de+notification+Laravel+13+depuis+un+package+%3A+r%C3%A9solution+par+nom+de+classe%2C+routage+des+destinataires%2C+mise+en+file+d%27attent\u0026amp;theme=cef70bdc0dd1884481ab7c5d\u0026amp;signature=7f75569343b1927e31358d4ff1202b4ffcf2460cda0f4eae5cb5c55e166c3229\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Canaux de notification personnalisés dans un package et vérification de l\u0026#x27;envoi - Knowledge of Laravel\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Découvrez comment fournir un canal de notification Laravel 13 depuis un package : résolution par nom de classe, routage des destinataires, mise en file d\u0026#x27;attente et tests de l\u0026#x27;envoi réel.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://invokable.mintlify.site/_mintlify/api/og/v2?division=D%C3%A9veloppement+de+packages\u0026amp;title=Canaux+de+notification+personnalis%C3%A9s+dans+un+package+et+v%C3%A9rification+de+l%27envoi\u0026amp;description=D%C3%A9couvrez+comment+fournir+un+canal+de+notification+Laravel+13+depuis+un+package+%3A+r%C3%A9solution+par+nom+de+classe%2C+routage+des+destinataires%2C+mise+en+file+d%27attent\u0026amp;theme=cef70bdc0dd1884481ab7c5d\u0026amp;signature=7f75569343b1927e31358d4ff1202b4ffcf2460cda0f4eae5cb5c55e166c3229\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/invokable/pboFjibLpJPX3oCo/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Knowledge of Laravel\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#16A34A\">\u003clink data-mint-head rel=\"canonical\" href=\"https://kawax.biz/fr/advanced/package-notification-channels\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/fr/advanced/package-notification-channels.md\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"fr\" href=\"https://kawax.biz/fr/advanced/package-notification-channels\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"ja\" href=\"https://kawax.biz/jp/advanced/package-notification-channels\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"en\" href=\"https://kawax.biz/en/advanced/package-notification-channels\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"de\" href=\"https://kawax.biz/de/advanced/package-notification-channels\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"es\" href=\"https://kawax.biz/es/advanced/package-notification-channels\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"it\" href=\"https://kawax.biz/it/advanced/package-notification-channels\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"ko\" href=\"https://kawax.biz/ko/advanced/package-notification-channels\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"nl\" href=\"https://kawax.biz/nl/advanced/package-notification-channels\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"zh-Hans\" href=\"https://kawax.biz/zh-CN/advanced/package-notification-channels\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"zh-Hant\" href=\"https://kawax.biz/zh-TW/advanced/package-notification-channels\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"x-default\" href=\"https://kawax.biz/jp/advanced/package-notification-channels\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://kawax.biz/#organization\",\"name\":\"Knowledge of Laravel\",\"url\":\"https://kawax.biz\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/invokable/AuZ0xql2mAbUyZ99/logo/light.svg?fit=max\u0026auto=format\u0026n=AuZ0xql2mAbUyZ99\u0026q=85\u0026s=df0b7397202a6aa1c1f321620c5aa146\"}},{\"@type\":\"WebSite\",\"@id\":\"https://kawax.biz#website\",\"name\":\"Knowledge of Laravel\",\"url\":\"https://kawax.biz\",\"publisher\":{\"@id\":\"https://kawax.biz/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://kawax.biz/fr/advanced/package-notification-channels#webpage\",\"url\":\"https://kawax.biz/fr/advanced/package-notification-channels\",\"name\":\"Canaux de notification personnalisés dans un package et vérification de l'envoi\",\"description\":\"Découvrez comment fournir un canal de notification Laravel 13 depuis un package : résolution par nom de classe, routage des destinataires, mise en file d'attente et tests de l'envoi réel.\",\"dateModified\":\"2026-10-22T22:21:00.000Z\",\"isPartOf\":{\"@id\":\"https://kawax.biz#website\"},\"breadcrumb\":{\"@id\":\"https://kawax.biz/fr/advanced/package-notification-channels#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://kawax.biz/fr/advanced/package-notification-channels#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Développement de packages\",\"item\":\"https://kawax.biz/fr/advanced/package-development\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Canaux de notification personnalisés dans un package et vérification de l'envoi\",\"item\":\"https://kawax.biz/fr/advanced/package-notification-channels\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://kawax.biz/fr/advanced/package-notification-channels#article\",\"headline\":\"Canaux de notification personnalisés dans un package et vérification de l'envoi\",\"name\":\"Canaux de notification personnalisés dans un package et vérification de l'envoi\",\"description\":\"Découvrez comment fournir un canal de notification Laravel 13 depuis un package : résolution par nom de classe, routage des destinataires, mise en file d'attente et tests de l'envoi réel.\",\"url\":\"https://kawax.biz/fr/advanced/package-notification-channels\",\"mainEntityOfPage\":{\"@id\":\"https://kawax.biz/fr/advanced/package-notification-channels#webpage\"},\"dateModified\":\"2026-10-22T22:21:00.000Z\",\"publisher\":{\"@id\":\"https://kawax.biz/#organization\"},\"isPartOf\":{\"@id\":\"https://kawax.biz#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Knowledge of Laravel\",\"publisher\":{\"@type\":\"Organization\",\"name\":\"Knowledge of Laravel\"},\"provider\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","agentPointerHref":"/fr/advanced/package-notification-channels.md","siteName":"Knowledge of Laravel","nav":{"global":null,"languages":[{"language":"jp","default":true,"pages":[{"title":"jp","href":"/jp/advanced/package-notification-channels"}]},{"language":"en","pages":[{"title":"en","href":"/en/advanced/package-notification-channels"}]},{"language":"de","pages":[{"title":"de","href":"/de/advanced/package-notification-channels"}]},{"language":"es","pages":[{"title":"es","href":"/es/advanced/package-notification-channels"}]},{"language":"fr","tabs":[{"tab":"Mes packages","pages":[{"title":"Mes packages","href":"/fr/packages/laravel-boost-copilot-cli"}]},{"tab":"Tutoriel","pages":[{"title":"Tutoriel","href":"/fr/introduction"}]},{"tab":"Guide","pages":[{"title":"Guide","href":"/fr/lifecycle"}]},{"tab":"Sujets avancés","groups":[{"group":"Développement IA","pages":[{"title":"Créer un serveur MCP avec Laravel","href":"/fr/advanced/mcp-server"},{"title":"Créer un agent personnalisé pour Boost","href":"/fr/advanced/boost-custom-agent"},{"title":"Créer un fournisseur personnalisé pour l'AI SDK","href":"/fr/advanced/ai-sdk-custom-provider"},{"title":"Les middlewares d'agent de Laravel AI SDK","href":"/fr/advanced/ai-sdk-agent-middleware"}]},{"group":"Patrons de conception","pages":[{"title":"Pattern Pipeline","href":"/fr/advanced/pipeline"},{"title":"Classe Fluent","href":"/fr/advanced/fluent"},{"title":"Trait Macroable","href":"/fr/advanced/macroable"},{"title":"Trait Conditionable","href":"/fr/advanced/conditionable"},{"title":"Trait InteractsWithTime","href":"/fr/advanced/interacts-with-time"},{"title":"Trait ForwardsCalls","href":"/fr/advanced/forwards-calls"},{"title":"Helper tap() et trait Tappable","href":"/fr/advanced/tap"},{"title":"Implémentation interne du helper once() — Once, Onceable et PreventsCircularRecursion","href":"/fr/advanced/once-helper"},{"title":"Trait Dumpable","href":"/fr/advanced/dumpable"},{"title":"Support Contracts (Arrayable / Jsonable / Htmlable / Responsable)","href":"/fr/advanced/support-contracts"},{"title":"Classe Lottery","href":"/fr/advanced/lottery"},{"title":"Messages d'ordre supérieur des collections","href":"/fr/advanced/higher-order-messages"},{"title":"Collection Deep Dive","href":"/fr/advanced/collection-deep-dive"},{"title":"Illuminate\\Support\\Manager — anatomie du système de drivers","href":"/fr/advanced/manager"},{"title":"API PHP Reflection","href":"/fr/advanced/php-reflection"},{"title":"PHP FFI","href":"/fr/advanced/ffi"},{"title":"PHP AST","href":"/fr/advanced/php-ast"}]},{"group":"Développement de packages","pages":[{"title":"Développement de packages Laravel","href":"/fr/advanced/package-development"},{"title":"Fonctionnement interne de la découverte automatique des packages","href":"/fr/advanced/package-discovery"},{"title":"Trait InteractsWithData","href":"/fr/advanced/interacts-with-data"},{"title":"Service providers différés","href":"/fr/advanced/deferred-provider"},{"title":"Gestion de la compatibilité de versions de package","href":"/fr/advanced/package-versioning"},{"title":"Pinning et sécurité de GitHub Actions","href":"/fr/advanced/github-actions-pinning"},{"title":"CHANGELOG et gestion des releases de packages","href":"/fr/advanced/package-changelog"},{"title":"Tester des packages Laravel avec Orchestra Testbench","href":"/fr/advanced/package-testing"},{"title":"Développer un package avec Testbench Workbench","href":"/fr/advanced/package-workbench"},{"title":"GeneratorCommand — implémenter des commandes make: personnalisées","href":"/fr/advanced/generator-command"},{"title":"Créer un starter kit Laravel","sidebarTitle":"Créer un starter kit","href":"/fr/advanced/starter-kit-creation"},{"title":"Analyse statique de packages (PHPStan / Larastan)","href":"/fr/advanced/package-static-analysis"},{"title":"Fusion et cache de la configuration des packages","href":"/fr/advanced/package-config-merging"},{"title":"Publier et mettre à jour les migrations d'un package","href":"/fr/advanced/package-migrations"},{"title":"Surcharger et mettre à jour les vues d'un package","href":"/fr/advanced/package-views"},{"title":"Enregistrement et cache des routes d'un package","href":"/fr/advanced/package-routes"},{"title":"Cache d'un package et intégration à optimize","href":"/fr/advanced/package-optimization"},{"title":"Assets publics d'un package et mises à jour","href":"/fr/advanced/package-assets"},{"title":"Surcharge et mise à jour des traductions d'un package","href":"/fr/advanced/package-translations"},{"title":"Hooks de résolution des services d'un package","href":"/fr/advanced/package-service-resolution"},{"title":"Ajouter des informations de diagnostic du package à about","href":"/fr/advanced/package-about"},{"title":"Enregistrement des commandes Artisan d'un package et résolution des dépendances","href":"/fr/advanced/package-commands"},{"title":"Enregistrement et mise en cache des écouteurs d'événements d'un package","href":"/fr/advanced/package-events"},{"title":"Conception du cycle de vie des services d'un package","href":"/fr/advanced/package-service-lifetimes"},{"title":"Enregistrement et portée des middlewares d'un package","href":"/fr/advanced/package-middleware"},{"title":"Extensions Blade d'un package et cache de compilation","href":"/fr/advanced/package-blade-extensions"},{"title":"Enregistrer des drivers Storage dans un package et les résoudre à nouveau","description":"En analysant le FilesystemManager de Laravel 13, découvrez l'enregistrement via Storage::extend(), la conservation des instances de disque, la nouvelle résolution après un changement de configuration et une vérification qui ne dépend pas de fake.","href":"/fr/advanced/package-filesystem-drivers"},{"title":"Canaux de notification personnalisés dans un package et vérification de l'envoi","href":"/fr/advanced/package-notification-channels"},{"title":"Tags de conteneur et agrégation de plugins d'un package","description":"Agrégez les implémentations de plusieurs packages avec les tags du conteneur de Laravel 13, et examinez la résolution paresseuse de tagged(), la différence avec giveTagged(), les enregistrements en double et le cycle de vie.","href":"/fr/advanced/package-container-tags"},{"title":"Client HTTP et tests dans un package","href":"/fr/advanced/package-http-client"},{"title":"Étendre et résoudre à nouveau les canaux de log d'un package","href":"/fr/advanced/package-logging"},{"title":"Stores de cache personnalisés et contrats pour les packages","href":"/fr/advanced/package-cache-drivers"},{"title":"Enregistrer et tester des transports de mail dans un package","href":"/fr/advanced/package-mail-transports"},{"title":"Attributs contextuels et résolution des dépendances dans un package","href":"/fr/advanced/package-contextual-attributes"},{"title":"Enregistrement et maintenance des tâches planifiées d'un package","href":"/fr/advanced/package-scheduling"},{"title":"Drivers de session personnalisés pour les packages","href":"/fr/advanced/package-session-drivers"},{"title":"Extension des connexions de base de données pour les packages","href":"/fr/advanced/package-database-connections"},{"title":"Enregistrement de relations dynamiques pour les packages","href":"/fr/advanced/package-dynamic-relations"},{"title":"Enregistrement de règles de validation sous forme de chaîne pour les packages","sidebarTitle":"Règles de validation en chaîne","href":"/fr/advanced/package-validation-extensions"},{"title":"Macros de réponse et contrats HTTP dans les packages","href":"/fr/advanced/package-response-macros"},{"title":"Décoration de services et extend dans un package","href":"/fr/advanced/package-service-decoration"},{"title":"Enregistrer et remplacer les policies d'un package","href":"/fr/advanced/package-authorization"},{"title":"Morph maps d'un package et compatibilité des données stockées","href":"/fr/advanced/package-morph-maps"}]},{"group":"Structure d'application","pages":[{"title":"Structure d'application Laravel 11+","href":"/fr/advanced/app-structure"},{"title":"Guide de migration de l'ancienne vers la nouvelle structure","sidebarTitle":"Guide de migration","href":"/fr/advanced/app-structure-migration"},{"title":"FAQ sur la nouvelle structure d'application Laravel 11+","sidebarTitle":"FAQ nouvelle structure","href":"/fr/advanced/app-structure-faq"}]},{"group":"Nouveautés Laravel 13","pages":[{"title":"Attributs PHP","href":"/fr/advanced/php-attributes"},{"title":"Attributs PHP des contrôleurs","sidebarTitle":"Attributs de contrôleur","href":"/fr/advanced/controller-attributes"}]},{"group":"Eloquent approfondi","pages":[{"title":"Observateurs Eloquent et événements de modèle","href":"/fr/advanced/eloquent-observers"},{"title":"Scopes Eloquent","href":"/fr/advanced/eloquent-scopes"},{"title":"Casts personnalisés Eloquent","href":"/fr/advanced/eloquent-casts"},{"title":"Eloquent Bootable Traits","href":"/fr/advanced/eloquent-bootable-traits"},{"title":"Modèles Pivot personnalisés et chaperone","href":"/fr/advanced/eloquent-custom-pivot"},{"title":"afterQuery d'Eloquent et le contrat des résultats","sidebarTitle":"afterQuery et traitement des résultats","href":"/fr/advanced/eloquent-after-query"}]},{"group":"Extension de la validation","pages":[{"title":"Règles de validation personnalisées","href":"/fr/advanced/custom-validation-rules"}]},{"group":"Extension de l'authentification","pages":[{"title":"Implémenter un guard d'authentification personnalisé","href":"/fr/advanced/custom-auth-guard"},{"title":"Laravel Fortify et les starter kits","href":"/fr/advanced/fortify"}]},{"group":"Sécurité","pages":[{"title":"Personnalisation de la limitation de débit","href":"/fr/advanced/rate-limiting"}]},{"group":"Files d'attente","pages":[{"title":"Contrôle de l'exécution des jobs de queue","href":"/fr/advanced/queue-job-control"}]},{"group":"Tests","pages":[{"title":"Tests avancés avec Pest","href":"/fr/advanced/testing-pest"}]},{"group":"Temps réel","pages":[{"title":"Au cœur du driver de broadcasting Mercure","href":"/fr/advanced/mercure-broadcasting"}]}]},{"tab":"Blog","pages":[{"title":"Blog","href":"/fr/blog/changelog/202610"}]}]},{"language":"it","pages":[{"title":"it","href":"/it/advanced/package-notification-channels"}]},{"language":"ko","pages":[{"title":"ko","href":"/ko/advanced/package-notification-channels"}]},{"language":"nl","pages":[{"title":"nl","href":"/nl/advanced/package-notification-channels"}]},{"language":"zh-Hans","pages":[{"title":"zh-Hans","href":"/zh-CN/advanced/package-notification-channels"}]},{"language":"zh-Hant","pages":[{"title":"zh-Hant","href":"/zh-TW/advanced/package-notification-channels"}]}]},"basePath":"","title":"Canaux de notification personnalisés dans un package et vérification de l'envoi - Knowledge of Laravel","buildId":"dpl_DqYu5MPb49gWBBbUGgpHQUmCHY3P","deploymentId":"dpl_DqYu5MPb49gWBBbUGgpHQUmCHY3P","dynamics":["2bfc744e19"],"chunks":["NarrationPlayer-CfOFO133.js","types-CiTgMxws.js","shallow-dY3TMRCk.js"]}