Laravel 13의 알림 채널을 패키지에서 제공하는 방법과 클래스 이름 기반 해석, 수신처 라우팅, 큐 처리, 실제 전송 테스트를 설명합니다.
페이지 듣기약 9분
패키지에서 알림 전송 방법을 추가하고 싶다면 채널 선택과 수신처 결정을 분리해서 설계합니다. 이 페이지에서는 운영 이벤트를 로그에 기록하는 작은 채널을 예로 들어, 패키지에서 제공하는 클래스가 해석되는 경로와 업데이트 시 필요한 검증을 설명합니다. 외부 서비스로 전송하도록 바꾸는 경우에도 채널과 알림의 책임 분담은 동일합니다.이 페이지는 Laravel Framework v13.38.0의 구현을 확인한 내용입니다. 알림의 기본 사용법은 알림을, 패키지 테스트 환경은 패키지 테스트를 참조하세요.
via()에서 반환하는 채널 클래스 이름은 어떤 객체의 send()를 호출할지 지정합니다. 반면 routeNotificationFor()에서 얻는 값은 해당 채널이 사용하는 수신처입니다. 두 값의 이름을 같게 맞출 필요는 없습니다.
지정 위치
이 페이지의 예
역할
알림의 via()
OperationsLogChannel::class
채널 해석과 전송
알림 가능 객체의 라우트
operationsLog → operations
채널 내부에서 사용하는 수신처
알림의 viaQueues()
OperationsLogChannel::class → operations-log
큐에 넣을 때 잡이 향하는 곳
NotificationSender는 via()가 선택한 채널 이름을 ChannelManager::driver()에 전달합니다. ChannelManager는 내장 이름이나 등록된 이름에서 찾지 못했고 그 이름이 실제로 존재하는 클래스라면, 컨테이너로 해당 클래스를 해석합니다. 클래스 이름으로만 사용한다면 Notification::extend()나 패키지 서비스 프로바이더는 필요 없습니다. Composer 오토로드로 클래스를 찾을 수 있고, 생성자의 의존성을 컨테이너가 해석할 수 있도록 하면 됩니다.
예제의 Acme\OperationsLog 패키지는 민감한 정보를 포함하지 않는 이벤트 이름을 수신처인 운영 팀 이름과 함께 기록합니다. Laravel 애플리케이션에서는 Psr\Log\LoggerInterface가 로그 서비스에 바인딩되어 있으므로 생성자로 주입받을 수 있습니다.
<?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), ]); }}
전달받는 객체는 Notifiable 트레이트를 사용하는 모델이거나 Notification::route()가 만드는 온디맨드 수신처라고 가정합니다. 전자에서는 routeNotificationForOperationsLog()의 값이, 후자에서는 route('operationsLog', ...)로 등록한 값이 반환됩니다. 수신처가 없는데도 전송 완료로 처리되지 않도록 이 예제에서는 예외를 던집니다. 실제 외부 전송으로 바꾸는 경우에도 수신처와 전송 결과를 확인하고, 실패를 성공으로 묻어 버리지 않도록 설계하세요.
로그에 기록하는 이벤트 이름이나 수신처에 액세스 토큰이나 개인정보를 포함하지 마세요. 이 예제는 채널 해석과 테스트를 보여 주기 위한 로그 전송이며, 외부 서비스로의 전송 구현이 아닙니다.
사용자가 via()에서 클래스 이름 대신 짧은 이름을 지정하게 하고 싶을 때만, 패키지의 일반 서비스 프로바이더에서 Notification::extend()를 사용합니다.
<?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), ); }}
프로바이더는 패키지 자동 감지 등을 통해 전송 처리가 시작되기 전에 로드되도록 합니다. 별칭을 사용하는 알림에서는 via()를 ['acme-operations-log']로, viaQueues()의 키도 같은 이름으로 변경합니다. 수신처 조회용 operationsLog는 별개의 키이므로 변경할 필요가 없습니다. 내장 채널 이름과 충돌하지 않는 이름을 사용하세요.Manager는 해석한 채널을 이름별로 보관합니다. 같은 프로세스에서 별칭 생성 처리를 다시 등록해도 이미 생성된 인스턴스는 교체되지 않습니다. 등록 방법을 변경했다면 새로 시작한 애플리케이션이나 워커에서도 검증하세요.
Notification::fake()는 알림을 보내려는 의도를 검증하기 위한 것입니다. 채널의 send()나 라우트 조회가 동작하는지는 확인할 수 없습니다. 전송 테스트에서는 실제 알림 Manager를 사용하고, LoggerInterface를 테스트용으로 교체합니다.다음은 Testbench의 TestCase에서 실행하는 예입니다. notifyNow()를 사용하면 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); }}
추가로 수신처가 없을 때 예외가 발생하는지, 별칭을 제공하는 경우 새로 시작한 상태에서 해석되는지도 확인합니다. 큐를 거쳐 사용하는 경우에는 별도로 큐 워커를 실행하는 검증용 애플리케이션에서 operations-log 큐에 잡이 도착하고 처리되는지도 테스트합니다.NotificationSender는 ShouldQueue 알림을 채널별 잡으로 나누고, viaQueues()의 키로 큐를 선택합니다. 채널의 send()가 예외를 던지면 NotificationFailed를 발생시킨 뒤 예외를 다시 던지고, 정상적으로 반환되면 NotificationSent를 발생시킵니다. 큐의 재시도 설정은 애플리케이션 설정을 따릅니다. 채널 내부에서 예외를 묻어 버리면 전송에 실패해도 성공으로 처리된다는 점에 주의하세요.
{"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":"ko/advanced/package-notification-channels","slug":"/ko/advanced/package-notification-channels","pageMetadata":{"title":"패키지의 커스텀 알림 채널과 전송 검증","description":"Laravel 13의 알림 채널을 패키지에서 제공하는 방법과 클래스 이름 기반 해석, 수신처 라우팅, 큐 처리, 실제 전송 테스트를 설명합니다.","href":"/ko/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: \"Laravel 13의 알림 채널을 패키지에서 제공하는 방법과 클래스 이름 기반 해석, 수신처 라우팅, 큐 처리, 실제 전송 테스트를 설명합니다.\"\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:[`패키지에서 알림 전송 방법을 추가하고 싶다면 `,_jsx(_components.strong,{children:`채널 선택`}),`과 `,_jsx(_components.strong,{children:`수신처 결정`}),`을 분리해서 설계합니다. 이 페이지에서는 운영 이벤트를 로그에 기록하는 작은 채널을 예로 들어, 패키지에서 제공하는 클래스가 해석되는 경로와 업데이트 시 필요한 검증을 설명합니다. 외부 서비스로 전송하도록 바꾸는 경우에도 채널과 알림의 책임 분담은 동일합니다.`]}),`\n`,_jsxs(_components.p,{children:[`이 페이지는 Laravel Framework `,_jsx(_components.code,{children:`v13.38.0`}),`의 구현을 확인한 내용입니다. 알림의 기본 사용법은 `,_jsx(_components.a,{href:`/ko/notifications`,children:`알림`}),`을, 패키지 테스트 환경은 `,_jsx(_components.a,{href:`/ko/advanced/package-testing`,children:`패키지 테스트`}),`를 참조하세요.`]}),`\n`,_jsx(Heading,{level:`2`,id:`클래스-이름은-전송-방법-라우트는-수신처`,children:`클래스 이름은 전송 방법, 라우트는 수신처`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`via()`}),`에서 반환하는 채널 클래스 이름은 어떤 객체의 `,_jsx(_components.code,{children:`send()`}),`를 호출할지 지정합니다. 반면 `,_jsx(_components.code,{children:`routeNotificationFor()`}),`에서 얻는 값은 해당 채널이 사용하는 수신처입니다. 두 값의 이름을 같게 맞출 필요는 없습니다.`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`지정 위치`}),_jsx(_components.th,{children:`이 페이지의 예`}),_jsx(_components.th,{children:`역할`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[`알림의 `,_jsx(_components.code,{children:`via()`})]}),_jsx(_components.td,{children:_jsx(_components.code,{children:`OperationsLogChannel::class`})}),_jsx(_components.td,{children:`채널 해석과 전송`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`알림 가능 객체의 라우트`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`operationsLog`}),` → `,_jsx(_components.code,{children:`operations`})]}),_jsx(_components.td,{children:`채널 내부에서 사용하는 수신처`})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[`알림의 `,_jsx(_components.code,{children:`viaQueues()`})]}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`OperationsLogChannel::class`}),` → `,_jsx(_components.code,{children:`operations-log`})]}),_jsx(_components.td,{children:`큐에 넣을 때 잡이 향하는 곳`})]})]})]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`NotificationSender`}),`는 `,_jsx(_components.code,{children:`via()`}),`가 선택한 채널 이름을 `,_jsx(_components.code,{children:`ChannelManager::driver()`}),`에 전달합니다. `,_jsx(_components.code,{children:`ChannelManager`}),`는 내장 이름이나 등록된 이름에서 찾지 못했고 그 이름이 실제로 존재하는 클래스라면, 컨테이너로 해당 클래스를 해석합니다. `,_jsxs(_components.strong,{children:[`클래스 이름으로만 사용한다면 `,_jsx(_components.code,{children:`Notification::extend()`}),`나 패키지 서비스 프로바이더는 필요 없습니다`]}),`. Composer 오토로드로 클래스를 찾을 수 있고, 생성자의 의존성을 컨테이너가 해석할 수 있도록 하면 됩니다.`]}),`\n`,_jsx(Mermaid,{chart:`flowchart LR\n A[\"via()로 클래스 이름 선택\"] --> B[\"ChannelManager::driver()\"]\n B --> C{\"이미 해석됨?\"}\n C -->|예| D[\"보관된 채널\"]\n C -->|아니요| E[\"컨테이너로 생성\"]\n E --> D\n D --> F[\"send()에서 수신처를 얻어 전송\"]`}),`\n`,_jsx(Heading,{level:`2`,id:`채널-본체를-패키지에서-제공하기`,children:`채널 본체를 패키지에서 제공하기`}),`\n`,_jsxs(_components.p,{children:[`예제의 `,_jsx(_components.code,{children:`Acme\\\\OperationsLog`}),` 패키지는 민감한 정보를 포함하지 않는 이벤트 이름을 수신처인 운영 팀 이름과 함께 기록합니다. Laravel 애플리케이션에서는 `,_jsx(_components.code,{children:`Psr\\\\Log\\\\LoggerInterface`}),`가 로그 서비스에 바인딩되어 있으므로 생성자로 주입받을 수 있습니다.`]}),`\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:[`전달받는 객체는 `,_jsx(_components.code,{children:`Notifiable`}),` 트레이트를 사용하는 모델이거나 `,_jsx(_components.code,{children:`Notification::route()`}),`가 만드는 온디맨드 수신처라고 가정합니다. 전자에서는 `,_jsx(_components.code,{children:`routeNotificationForOperationsLog()`}),`의 값이, 후자에서는 `,_jsx(_components.code,{children:`route('operationsLog', ...)`}),`로 등록한 값이 반환됩니다. 수신처가 없는데도 전송 완료로 처리되지 않도록 이 예제에서는 예외를 던집니다. 실제 외부 전송으로 바꾸는 경우에도 수신처와 전송 결과를 확인하고, 실패를 성공으로 묻어 버리지 않도록 설계하세요.`]}),`\n`,_jsx(Warning,{children:_jsx(_components.p,{children:`로그에 기록하는 이벤트 이름이나 수신처에 액세스 토큰이나 개인정보를 포함하지 마세요. 이 예제는 채널 해석과 테스트를 보여 주기 위한 로그 전송이며, 외부 서비스로의 전송 구현이 아닙니다.`})}),`\n`,_jsx(Heading,{level:`2`,id:`사용하는-쪽에서-알림과-수신처-정의하기`,children:`사용하는 쪽에서 알림과 수신처 정의하기`}),`\n`,_jsxs(_components.p,{children:[`애플리케이션의 알림은 채널 클래스를 반환하고, 채널에 전달할 메시지만 정의합니다. `,_jsx(_components.code,{children:`ShouldQueue`}),`와 `,_jsx(_components.code,{children:`Queueable`}),`을 사용하면 일반적인 `,_jsx(_components.code,{children:`notify()`}),` 호출이 큐를 거치게 됩니다.`]}),`\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:[`수신처를 그 자리에서 지정하는 경우, `,_jsx(_components.code,{children:`Notification::route()`}),`의 키는 `,_jsx(_components.strong,{children:`채널 클래스 이름이 아니라`}),` 채널 내부에서 호출하는 `,_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:[`애플리케이션의 모델에서 보내는 경우에는 `,_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:[`이 모델에 대해 `,_jsx(_components.code,{children:`$user->notify(new HealthCheckPassed())`}),`를 호출해도 같은 채널이 선택됩니다. 큐 연결을 설정하고 `,_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`}),` 자체는 채널별로 Manager에 보관되므로, `,_jsx(_components.strong,{children:`수신처나 알림 본문을 채널의 프로퍼티에 저장하지 말고`}),` 매번 `,_jsx(_components.code,{children:`send()`}),`의 인수에서 꺼내세요. 오래 실행되는 큐 워커에서도 이전 알림의 정보가 남지 않도록 하기 위해서입니다.`]}),`\n`,_jsx(Heading,{level:`2`,id:`짧은-별칭이-필요한-경우`,children:`짧은 별칭이 필요한 경우`}),`\n`,_jsxs(_components.p,{children:[`사용자가 `,_jsx(_components.code,{children:`via()`}),`에서 클래스 이름 대신 짧은 이름을 지정하게 하고 싶을 때만, 패키지의 일반 서비스 프로바이더에서 `,_jsx(_components.code,{children:`Notification::extend()`}),`를 사용합니다.`]}),`\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:[`프로바이더는 `,_jsx(_components.a,{href:`/ko/advanced/package-discovery`,children:`패키지 자동 감지`}),` 등을 통해 전송 처리가 시작되기 전에 로드되도록 합니다. 별칭을 사용하는 알림에서는 `,_jsx(_components.code,{children:`via()`}),`를 `,_jsx(_components.code,{children:`['acme-operations-log']`}),`로, `,_jsx(_components.code,{children:`viaQueues()`}),`의 키도 같은 이름으로 변경합니다. `,_jsxs(_components.strong,{children:[`수신처 조회용 `,_jsx(_components.code,{children:`operationsLog`}),`는 별개의 키`]}),`이므로 변경할 필요가 없습니다. 내장 채널 이름과 충돌하지 않는 이름을 사용하세요.`]}),`\n`,_jsx(_components.p,{children:`Manager는 해석한 채널을 이름별로 보관합니다. 같은 프로세스에서 별칭 생성 처리를 다시 등록해도 이미 생성된 인스턴스는 교체되지 않습니다. 등록 방법을 변경했다면 새로 시작한 애플리케이션이나 워커에서도 검증하세요.`}),`\n`,_jsx(Heading,{level:`2`,id:`fake와-별도로-전송-처리-테스트하기`,children:`fake와 별도로 전송 처리 테스트하기`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`Notification::fake()`}),`는 알림을 보내려는 `,_jsx(_components.strong,{children:`의도`}),`를 검증하기 위한 것입니다. 채널의 `,_jsx(_components.code,{children:`send()`}),`나 라우트 조회가 동작하는지는 확인할 수 없습니다. 전송 테스트에서는 실제 알림 Manager를 사용하고, `,_jsx(_components.code,{children:`LoggerInterface`}),`를 테스트용으로 교체합니다.`]}),`\n`,_jsxs(_components.p,{children:[`다음은 `,_jsxs(_components.a,{href:`/ko/advanced/package-testing`,children:[`Testbench의 `,_jsx(_components.code,{children:`TestCase`})]}),`에서 실행하는 예입니다. `,_jsx(_components.code,{children:`notifyNow()`}),`를 사용하면 `,_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:[`추가로 수신처가 없을 때 예외가 발생하는지, 별칭을 제공하는 경우 새로 시작한 상태에서 해석되는지도 확인합니다. 큐를 거쳐 사용하는 경우에는 별도로 큐 워커를 실행하는 검증용 애플리케이션에서 `,_jsx(_components.code,{children:`operations-log`}),` 큐에 잡이 도착하고 처리되는지도 테스트합니다.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`NotificationSender`}),`는 `,_jsx(_components.code,{children:`ShouldQueue`}),` 알림을 채널별 잡으로 나누고, `,_jsx(_components.code,{children:`viaQueues()`}),`의 키로 큐를 선택합니다. 채널의 `,_jsx(_components.code,{children:`send()`}),`가 예외를 던지면 `,_jsx(_components.code,{children:`NotificationFailed`}),`를 발생시킨 뒤 예외를 다시 던지고, 정상적으로 반환되면 `,_jsx(_components.code,{children:`NotificationSent`}),`를 발생시킵니다. 큐의 재시도 설정은 애플리케이션 설정을 따릅니다. 채널 내부에서 예외를 묻어 버리면 전송에 실패해도 성공으로 처리된다는 점에 주의하세요.`]}),`\n`,_jsx(Heading,{level:`2`,id:`참조한-1차-자료`,children:`참조한 1차 자료`}),`\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:`Laravel 13 공식 문서: 커스텀 알림 채널과 큐`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`https://github.com/laravel/docs/blob/13.x/packages.md#package-discovery`,children:`Laravel 13 공식 문서: 패키지 자동 감지`})}),`\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: 클래스 이름으로부터의 해석`})}),`\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: 채널별 전송, 큐, 이벤트`})}),`\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와 AnonymousNotifiable: 수신처 라우트`})}),`\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: 드라이버 보관과 확장`})}),`\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: 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":"패키지의 커스텀 알림 채널과 전송 검증","description":"Laravel 13의 알림 채널을 패키지에서 제공하는 방법과 클래스 이름 기반 해석, 수신처 라우팅, 큐 처리, 실제 전송 테스트를 설명합니다.","href":"/ko/advanced/package-notification-channels"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"클래스 이름은 전송 방법, 라우트는 수신처","slug":"클래스-이름은-전송-방법-라우트는-수신처","depth":2,"children":[]},{"title":"채널 본체를 패키지에서 제공하기","slug":"채널-본체를-패키지에서-제공하기","depth":2,"children":[]},{"title":"사용하는 쪽에서 알림과 수신처 정의하기","slug":"사용하는-쪽에서-알림과-수신처-정의하기","depth":2,"children":[]},{"title":"짧은 별칭이 필요한 경우","slug":"짧은-별칭이-필요한-경우","depth":2,"children":[]},{"title":"fake와 별도로 전송 처리 테스트하기","slug":"fake와-별도로-전송-처리-테스트하기","depth":2,"children":[]},{"title":"참조한 1차 자료","slug":"참조한-1차-자료","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"narration":{"path":"ko/advanced/package-notification-channels","locale":"ko","estimatedDurationSec":529},"subdomain":"invokable","siteName":"Knowledge of Laravel","title":"패키지의 커스텀 알림 채널과 전송 검증 - 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":1},"it":{"href":"/it/advanced/package-notification-channels","matchLevel":1},"ko":{"href":"/ko/advanced/package-notification-channels","matchLevel":0},"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.004Z","gitLastModified":"2026-10-22T22:21:00.000Z","originalFileLocation":"ko/advanced/package-notification-channels.mdx","locale":"ko"},"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=\"Laravel 13의 알림 채널을 패키지에서 제공하는 방법과 클래스 이름 기반 해석, 수신처 라우팅, 큐 처리, 실제 전송 테스트를 설명합니다.\">\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=\"패키지의 커스텀 알림 채널과 전송 검증 - Knowledge of Laravel\">\u003cmeta data-mint-head property=\"og:description\" content=\"Laravel 13의 알림 채널을 패키지에서 제공하는 방법과 클래스 이름 기반 해석, 수신처 라우팅, 큐 처리, 실제 전송 테스트를 설명합니다.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Knowledge of Laravel\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://kawax.biz/ko/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=%ED%8C%A8%ED%82%A4%EC%A7%80+%EA%B0%9C%EB%B0%9C\u0026amp;title=%ED%8C%A8%ED%82%A4%EC%A7%80%EC%9D%98+%EC%BB%A4%EC%8A%A4%ED%85%80+%EC%95%8C%EB%A6%BC+%EC%B1%84%EB%84%90%EA%B3%BC+%EC%A0%84%EC%86%A1+%EA%B2%80%EC%A6%9D\u0026amp;description=Laravel+13%EC%9D%98+%EC%95%8C%EB%A6%BC+%EC%B1%84%EB%84%90%EC%9D%84+%ED%8C%A8%ED%82%A4%EC%A7%80%EC%97%90%EC%84%9C+%EC%A0%9C%EA%B3%B5%ED%95%98%EB%8A%94+%EB%B0%A9%EB%B2%95%EA%B3%BC+%ED%81%B4%EB%9E%98%EC%8A%A4+%EC%9D%B4%EB%A6%84+%EA%B8%B0%EB%B0%98+%ED%95%B4%EC%84%9D%2C+%EC%88%98%EC%8B%A0%EC%B2%98+%EB%9D%BC%EC%9A%B0%ED%8C%85%2C+%ED%81%90+%EC%B2%98%EB%A6%AC%2C+%EC%8B%A4%EC%A0%9C+%EC%A0%84%EC%86%A1+%ED%85%8C%EC%8A%A4%ED%8A%B8%EB%A5%BC+%EC%84%A4%EB%AA%85%ED%95%A9%EB%8B%88%EB%8B%A4.\u0026amp;theme=cef70bdc0dd1884481ab7c5d\u0026amp;signature=1d42cee2c237db6d8b5dcc0392f187c7f54a5a5a8a90ab66e58d3d65feffa586\">\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=\"패키지의 커스텀 알림 채널과 전송 검증 - Knowledge of Laravel\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Laravel 13의 알림 채널을 패키지에서 제공하는 방법과 클래스 이름 기반 해석, 수신처 라우팅, 큐 처리, 실제 전송 테스트를 설명합니다.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://invokable.mintlify.site/_mintlify/api/og/v2?division=%ED%8C%A8%ED%82%A4%EC%A7%80+%EA%B0%9C%EB%B0%9C\u0026amp;title=%ED%8C%A8%ED%82%A4%EC%A7%80%EC%9D%98+%EC%BB%A4%EC%8A%A4%ED%85%80+%EC%95%8C%EB%A6%BC+%EC%B1%84%EB%84%90%EA%B3%BC+%EC%A0%84%EC%86%A1+%EA%B2%80%EC%A6%9D\u0026amp;description=Laravel+13%EC%9D%98+%EC%95%8C%EB%A6%BC+%EC%B1%84%EB%84%90%EC%9D%84+%ED%8C%A8%ED%82%A4%EC%A7%80%EC%97%90%EC%84%9C+%EC%A0%9C%EA%B3%B5%ED%95%98%EB%8A%94+%EB%B0%A9%EB%B2%95%EA%B3%BC+%ED%81%B4%EB%9E%98%EC%8A%A4+%EC%9D%B4%EB%A6%84+%EA%B8%B0%EB%B0%98+%ED%95%B4%EC%84%9D%2C+%EC%88%98%EC%8B%A0%EC%B2%98+%EB%9D%BC%EC%9A%B0%ED%8C%85%2C+%ED%81%90+%EC%B2%98%EB%A6%AC%2C+%EC%8B%A4%EC%A0%9C+%EC%A0%84%EC%86%A1+%ED%85%8C%EC%8A%A4%ED%8A%B8%EB%A5%BC+%EC%84%A4%EB%AA%85%ED%95%A9%EB%8B%88%EB%8B%A4.\u0026amp;theme=cef70bdc0dd1884481ab7c5d\u0026amp;signature=1d42cee2c237db6d8b5dcc0392f187c7f54a5a5a8a90ab66e58d3d65feffa586\">\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/ko/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=\"/ko/advanced/package-notification-channels.md\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"ko\" href=\"https://kawax.biz/ko/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=\"fr\" href=\"https://kawax.biz/fr/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=\"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/ko/advanced/package-notification-channels#webpage\",\"url\":\"https://kawax.biz/ko/advanced/package-notification-channels\",\"name\":\"패키지의 커스텀 알림 채널과 전송 검증\",\"description\":\"Laravel 13의 알림 채널을 패키지에서 제공하는 방법과 클래스 이름 기반 해석, 수신처 라우팅, 큐 처리, 실제 전송 테스트를 설명합니다.\",\"dateModified\":\"2026-10-22T22:21:00.000Z\",\"isPartOf\":{\"@id\":\"https://kawax.biz#website\"},\"breadcrumb\":{\"@id\":\"https://kawax.biz/ko/advanced/package-notification-channels#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://kawax.biz/ko/advanced/package-notification-channels#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"패키지 개발\",\"item\":\"https://kawax.biz/ko/advanced/package-development\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"패키지의 커스텀 알림 채널과 전송 검증\",\"item\":\"https://kawax.biz/ko/advanced/package-notification-channels\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://kawax.biz/ko/advanced/package-notification-channels#article\",\"headline\":\"패키지의 커스텀 알림 채널과 전송 검증\",\"name\":\"패키지의 커스텀 알림 채널과 전송 검증\",\"description\":\"Laravel 13의 알림 채널을 패키지에서 제공하는 방법과 클래스 이름 기반 해석, 수신처 라우팅, 큐 처리, 실제 전송 테스트를 설명합니다.\",\"url\":\"https://kawax.biz/ko/advanced/package-notification-channels\",\"mainEntityOfPage\":{\"@id\":\"https://kawax.biz/ko/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":"/ko/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","pages":[{"title":"fr","href":"/fr/advanced/package-notification-channels"}]},{"language":"it","pages":[{"title":"it","href":"/it/advanced/package-notification-channels"}]},{"language":"ko","tabs":[{"tab":"My 패키지","pages":[{"title":"My 패키지","href":"/ko/packages/laravel-boost-copilot-cli"}]},{"tab":"튜토리얼","pages":[{"title":"튜토리얼","href":"/ko/introduction"}]},{"tab":"가이드","pages":[{"title":"가이드","href":"/ko/lifecycle"}]},{"tab":"심화 주제","groups":[{"group":"AI 개발","pages":[{"title":"Laravel에서 MCP 서버 만들기","href":"/ko/advanced/mcp-server"},{"title":"Boost의 커스텀 에이전트 만들기","href":"/ko/advanced/boost-custom-agent"},{"title":"AI SDK의 커스텀 프로바이더 만들기","href":"/ko/advanced/ai-sdk-custom-provider"},{"title":"Laravel AI SDK의 에이전트 미들웨어","href":"/ko/advanced/ai-sdk-agent-middleware"}]},{"group":"디자인 패턴","pages":[{"title":"Pipeline 패턴","href":"/ko/advanced/pipeline"},{"title":"Fluent 클래스","href":"/ko/advanced/fluent"},{"title":"Macroable 트레이트","href":"/ko/advanced/macroable"},{"title":"Conditionable 트레이트","href":"/ko/advanced/conditionable"},{"title":"InteractsWithTime 트레이트","href":"/ko/advanced/interacts-with-time"},{"title":"ForwardsCalls 트레이트","href":"/ko/advanced/forwards-calls"},{"title":"tap() 헬퍼와 Tappable 트레이트","href":"/ko/advanced/tap"},{"title":"once() 헬퍼의 내부 구현 — Once·Onceable·PreventsCircularRecursion","href":"/ko/advanced/once-helper"},{"title":"Dumpable 트레이트","href":"/ko/advanced/dumpable"},{"title":"Support Contracts (Arrayable / Jsonable / Htmlable / Responsable)","href":"/ko/advanced/support-contracts"},{"title":"Lottery 클래스","href":"/ko/advanced/lottery"},{"title":"컬렉션의 고차 메시지","href":"/ko/advanced/higher-order-messages"},{"title":"Collection Deep Dive","href":"/ko/advanced/collection-deep-dive"},{"title":"Illuminate\\Support\\Manager — 드라이버 시스템의 해부","href":"/ko/advanced/manager"},{"title":"PHP Reflection API","href":"/ko/advanced/php-reflection"},{"title":"PHP FFI","href":"/ko/advanced/ffi"},{"title":"PHP AST","href":"/ko/advanced/php-ast"}]},{"group":"패키지 개발","pages":[{"title":"Laravel 패키지 개발","href":"/ko/advanced/package-development"},{"title":"패키지 자동 감지의 내부 구조","href":"/ko/advanced/package-discovery"},{"title":"InteractsWithData 트레이트","href":"/ko/advanced/interacts-with-data"},{"title":"지연 서비스 프로바이더","href":"/ko/advanced/deferred-provider"},{"title":"패키지의 버전 호환성 관리","href":"/ko/advanced/package-versioning"},{"title":"GitHub Actions의 핀 고정과 보안","href":"/ko/advanced/github-actions-pinning"},{"title":"패키지의 CHANGELOG와 릴리스 관리","href":"/ko/advanced/package-changelog"},{"title":"Orchestra Testbench로 Laravel 패키지를 테스트하기","href":"/ko/advanced/package-testing"},{"title":"Testbench Workbench로 패키지 개발 진행하기","href":"/ko/advanced/package-workbench"},{"title":"GeneratorCommand — 커스텀 make: 명령어 구현","href":"/ko/advanced/generator-command"},{"title":"Laravel 스타터 킷 만드는 법","sidebarTitle":"스타터 킷 작성","href":"/ko/advanced/starter-kit-creation"},{"title":"패키지의 정적 해석 (PHPStan / Larastan)","href":"/ko/advanced/package-static-analysis"},{"title":"패키지 설정 병합과 캐시","href":"/ko/advanced/package-config-merging"},{"title":"패키지 마이그레이션의 배포와 업데이트","href":"/ko/advanced/package-migrations"},{"title":"패키지 뷰의 덮어쓰기와 업데이트","href":"/ko/advanced/package-views"},{"title":"패키지의 라우트 등록과 캐시","href":"/ko/advanced/package-routes"},{"title":"패키지 캐시와 optimize 통합","href":"/ko/advanced/package-optimization"},{"title":"패키지의 공개 에셋과 업데이트","href":"/ko/advanced/package-assets"},{"title":"패키지 번역의 덮어쓰기와 업데이트","href":"/ko/advanced/package-translations"},{"title":"패키지의 서비스 해석 후 훅","href":"/ko/advanced/package-service-resolution"},{"title":"패키지 진단 정보를 about에 추가하기","href":"/ko/advanced/package-about"},{"title":"패키지의 Artisan 명령어 등록과 의존성 해결","href":"/ko/advanced/package-commands"},{"title":"패키지의 이벤트 리스너 등록과 캐시","href":"/ko/advanced/package-events"},{"title":"패키지 서비스의 라이프사이클 설계","href":"/ko/advanced/package-service-lifetimes"},{"title":"패키지의 미들웨어 등록과 적용 범위","href":"/ko/advanced/package-middleware"},{"title":"패키지의 Blade 확장과 컴파일 캐시","href":"/ko/advanced/package-blade-extensions"},{"title":"패키지의 Storage 드라이버 등록과 재해석","description":"Laravel 13의 FilesystemManager를 분석하여, Storage::extend() 등록, 디스크 인스턴스 보관, 설정 변경 후의 재해석과 fake에 의존하지 않는 검증을 해설합니다.","href":"/ko/advanced/package-filesystem-drivers"},{"title":"패키지의 커스텀 알림 채널과 전송 검증","href":"/ko/advanced/package-notification-channels"},{"title":"패키지의 컨테이너 태그와 플러그인 집약","description":"Laravel 13의 컨테이너 태그로 여러 패키지의 구현을 집약하고, tagged()의 지연 해석, giveTagged()와의 차이, 중복 등록과 라이프사이클을 검증합니다.","href":"/ko/advanced/package-container-tags"},{"title":"패키지의 HTTP 클라이언트와 테스트","href":"/ko/advanced/package-http-client"},{"title":"패키지의 로그 채널 확장과 재해석","href":"/ko/advanced/package-logging"},{"title":"패키지의 커스텀 캐시 스토어와 계약","href":"/ko/advanced/package-cache-drivers"},{"title":"패키지의 메일 트랜스포트 등록과 테스트","href":"/ko/advanced/package-mail-transports"},{"title":"패키지의 컨텍스트 속성과 의존성 해석","href":"/ko/advanced/package-contextual-attributes"},{"title":"패키지의 정기 태스크 등록과 유지보수","href":"/ko/advanced/package-scheduling"},{"title":"패키지의 커스텀 세션 드라이버","href":"/ko/advanced/package-session-drivers"},{"title":"패키지의 데이터베이스 연결 확장","href":"/ko/advanced/package-database-connections"},{"title":"패키지의 동적 관계 등록","href":"/ko/advanced/package-dynamic-relations"},{"title":"패키지의 문자열 유효성 검사 규칙 등록","sidebarTitle":"문자열 유효성 검사 규칙","href":"/ko/advanced/package-validation-extensions"},{"title":"패키지의 응답 Macro와 HTTP 계약","href":"/ko/advanced/package-response-macros"},{"title":"패키지의 서비스 데코레이션과 extend","href":"/ko/advanced/package-service-decoration"},{"title":"패키지의 인가 폴리시 등록과 재정의","href":"/ko/advanced/package-authorization"},{"title":"패키지의 Morph map과 저장 데이터의 호환성","href":"/ko/advanced/package-morph-maps"}]},{"group":"애플리케이션 구조","pages":[{"title":"Laravel 11 이후의 애플리케이션 구조","href":"/ko/advanced/app-structure"},{"title":"구 구조에서 새 구조로의 이관 가이드","sidebarTitle":"이관 가이드","href":"/ko/advanced/app-structure-migration"},{"title":"Laravel 11 이후의 새 앱 구조 FAQ","sidebarTitle":"새 앱 구조 FAQ","href":"/ko/advanced/app-structure-faq"}]},{"group":"Laravel 13 신기능","pages":[{"title":"PHP 어트리뷰트","href":"/ko/advanced/php-attributes"},{"title":"컨트롤러 PHP 어트리뷰트","sidebarTitle":"컨트롤러 어트리뷰트","href":"/ko/advanced/controller-attributes"}]},{"group":"Eloquent 심화","pages":[{"title":"Eloquent Observers와 모델 이벤트","href":"/ko/advanced/eloquent-observers"},{"title":"Eloquent의 스코프","href":"/ko/advanced/eloquent-scopes"},{"title":"Eloquent의 커스텀 캐스트","href":"/ko/advanced/eloquent-casts"},{"title":"Eloquent Bootable Traits","href":"/ko/advanced/eloquent-bootable-traits"},{"title":"커스텀 피벗 모델과 chaperone","href":"/ko/advanced/eloquent-custom-pivot"},{"title":"Eloquent의 afterQuery와 조회 결과의 계약","sidebarTitle":"afterQuery와 결과 가공","href":"/ko/advanced/eloquent-after-query"}]},{"group":"유효성 검증 확장","pages":[{"title":"커스텀 검증 규칙","href":"/ko/advanced/custom-validation-rules"}]},{"group":"인증 확장","pages":[{"title":"커스텀 인증 가드 구현","href":"/ko/advanced/custom-auth-guard"},{"title":"Laravel Fortify와 스타터 킷","href":"/ko/advanced/fortify"}]},{"group":"보안","pages":[{"title":"레이트 리밋 커스터마이즈","href":"/ko/advanced/rate-limiting"}]},{"group":"큐","pages":[{"title":"큐 잡 실행 제어","href":"/ko/advanced/queue-job-control"}]},{"group":"테스트","pages":[{"title":"Pest를 이용한 고급 테스트","href":"/ko/advanced/testing-pest"}]},{"group":"실시간","pages":[{"title":"Mercure 브로드캐스트 드라이버의 내부 구조","href":"/ko/advanced/mercure-broadcasting"}]}]},{"tab":"블로그","pages":[{"title":"블로그","href":"/ko/blog/changelog/202610"}]}]},{"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":"패키지의 커스텀 알림 채널과 전송 검증 - Knowledge of Laravel","buildId":"dpl_DqYu5MPb49gWBBbUGgpHQUmCHY3P","deploymentId":"dpl_DqYu5MPb49gWBBbUGgpHQUmCHY3P","dynamics":["2bfc744e19"],"chunks":["NarrationPlayer-CfOFO133.js","types-CiTgMxws.js","shallow-dY3TMRCk.js"]}