CINXE.COM

Laravel Bootcamp

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Laravel Bootcamp</title> <!-- Primary Meta Tags --> <meta name="title" content="Laravel Bootcamp - Learn the PHP Framework for Web Artisans"> <meta name="description" content="Together let's walk through building and deploying a modern Laravel application from scratch."> <!-- Open Graph / Facebook --> <meta property="og:type" content="website"> <meta property="og:url" content="https://bootcamp.laravel.com/"> <meta property="og:title" content="Laravel Bootcamp - Learn the PHP Framework for Web Artisans"> <meta property="og:description" content="Together let's walk through building and deploying a modern Laravel application from scratch."> <meta property="og:image" content="https://bootcamp.laravel.com/img/og-image.jpg"> <!-- Twitter --> <meta property="twitter:card" content="summary_large_image"> <meta property="twitter:url" content="https://bootcamp.laravel.com/"> <meta property="twitter:title" content="Laravel - Learn the PHP Framework for Web Artisans"> <meta property="twitter:description" content="Together let's walk through building and deploying a modern Laravel application from scratch."> <meta property="twitter:image" content="https://bootcamp.laravel.com/img/og-image.jpg"> <!-- Favicon --> <link rel="apple-touch-icon" sizes="180x180" href="/img/favicon/apple-touch-icon.png"> <link rel="icon" type="image/png" sizes="32x32" href="/img/favicon/favicon-32x32.png"> <link rel="icon" type="image/png" sizes="16x16" href="/img/favicon/favicon-16x16.png"> <link rel="manifest" href="/img/favicon/site.webmanifest"> <link rel="mask-icon" href="/img/favicon/safari-pinned-tab.svg" color="#ff2d20"> <link rel="shortcut icon" href="/img/favicon/favicon.ico"> <meta name="msapplication-TileColor" content="#ff2d20"> <meta name="msapplication-config" content="/img/favicon/browserconfig.xml"> <meta name="theme-color" content="#ffffff"> <meta name="color-scheme" content="light"> <!-- Fonts --> <link rel="stylesheet" href="https://use.typekit.net/ins2wgm.css"> <!-- Scripts & Styles --> <link rel="stylesheet" href="https://bootcamp.laravel.com/build/assets/app.1fe37668.css" /><script type="module" src="https://bootcamp.laravel.com/build/assets/app.f1116ac0.js"></script> <!-- Fathom - beautiful, simple website analytics --> <script src="https://cdn.usefathom.com/script.js" data-site="KRRQTWHM" defer></script> <!-- / Fathom --> <script> window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => { if (localStorage.theme === 'system') { if (e.matches) { document.documentElement.classList.add('dark'); } else { document.documentElement.classList.remove('dark'); } } }); function updateTheme() { if (!('theme' in localStorage)) { localStorage.theme = 'system'; } switch (localStorage.theme) { case 'system': if (window.matchMedia('(prefers-color-scheme: dark)').matches) { document.documentElement.classList.add('dark'); } else { document.documentElement.classList.remove('dark'); } document.documentElement.setAttribute('color-theme', 'system'); break; case 'dark': document.documentElement.classList.add('dark'); document.documentElement.setAttribute('color-theme', 'dark'); break; case 'light': document.documentElement.classList.remove('dark'); document.documentElement.setAttribute('color-theme', 'light'); break; } } updateTheme(); </script> </head> <body x-data="{ navIsOpen: false }" class="font-sans text-gray-900 antialiased" > <a id="skip-to-content-link" href="#main-content" class="absolute bg-gray-100 px-4 py-2 top-3 left-3 text-gray-700 shadow-xl" > Skip to content </a> <div class="min-h-screen dark:bg-dark-700"> <div class="relative lg:flex lg:items-start"> <aside id="sidebar" class="min-h-screen hidden fixed top-0 bottom-0 left-0 z-20 h-full w-16 bg-gradient-to-b from-gray-100 to-white transition-all duration-300 overflow-hidden lg:sticky lg:w-80 lg:shrink-0 lg:flex lg:flex-col lg:justify-end lg:items-end 2xl:max-w-lg 2xl:w-full dark:from-dark-800 dark:to-dark-700" > <div class="relative min-h-0 flex-1 flex flex-col xl:w-80"> <a href="/" class="flex items-center py-8 px-4 lg:px-8 xl:px-16"> <img class="w-8 h-8 shrink-0 transition-all duration-300 lg:w-12 lg:h-12" :class="{ 'w-12 h-12': navIsOpen }" src="/img/logomark.min.svg" alt="Laravel" width="50" height="52" > <span class="hidden lg:block ml-4 text-red-500 text-3xl font-medium">Bootcamp</span> </a> <div class="overflow-y-auto overflow-x-hidden px-4 lg:overflow-hidden lg:px-8 xl:px-16"> <nav id="indexed-nav" class="hidden lg:block lg:mt-4"> <div class="docs_sidebar"> <ul> <li> <h2><a id="introduction" href="#introduction" class="heading-permalink" aria-hidden="true" title="Permalink">#</a><a href="/introduction">Introduction</a></h2> </li> <li> <h2><a id="build-chirper-with-blade" href="#build-chirper-with-blade" class="heading-permalink" aria-hidden="true" title="Permalink">#</a>Build Chirper with Blade</h2> <ul> <li> <a href="/blade/installation">Installation</a> </li> <li> <a href="/blade/creating-chirps">Creating Chirps</a> </li> <li> <a href="/blade/showing-chirps">Showing Chirps</a> </li> <li> <a href="/blade/editing-chirps">Editing Chirps</a> </li> <li> <a href="/blade/deleting-chirps">Deleting Chirps</a> </li> <li> <a href="/blade/notifications-and-events">Notifications &amp; Events</a> </li> </ul> </li> <li> <h2><a id="build-chirper-with-livewire" href="#build-chirper-with-livewire" class="heading-permalink" aria-hidden="true" title="Permalink">#</a>Build Chirper with Livewire</h2> <ul> <li> <a href="/livewire/installation">Installation</a> </li> <li> <a href="/livewire/creating-chirps">Creating Chirps</a> </li> <li> <a href="/livewire/showing-chirps">Showing Chirps</a> </li> <li> <a href="/livewire/editing-chirps">Editing Chirps</a> </li> <li> <a href="/livewire/deleting-chirps">Deleting Chirps</a> </li> <li> <a href="/livewire/notifications-and-events">Notifications &amp; Events</a> </li> </ul> </li> <li> <h2><a id="build-chirper-with-inertia" href="#build-chirper-with-inertia" class="heading-permalink" aria-hidden="true" title="Permalink">#</a>Build Chirper with Inertia</h2> <ul> <li> <a href="/inertia/installation">Installation</a> </li> <li> <a href="/inertia/creating-chirps">Creating Chirps</a> </li> <li> <a href="/inertia/showing-chirps">Showing Chirps</a> </li> <li> <a href="/inertia/editing-chirps">Editing Chirps</a> </li> <li> <a href="/inertia/deleting-chirps">Deleting Chirps</a> </li> <li> <a href="/inertia/notifications-and-events">Notifications &amp; Events</a> </li> </ul> </li> <li> <h2><a id="deploying" href="#deploying" class="heading-permalink" aria-hidden="true" title="Permalink">#</a><a href="/deploying">Deploying</a></h2> </li> <li> <h2><a id="conclusion" href="#conclusion" class="heading-permalink" aria-hidden="true" title="Permalink">#</a><a href="/conclusion">Conclusion</a></h2> </li> </ul> </div> </nav> </div> <div class="flex-grow flex flex-col justify-end"> <div class="hidden 2xl:block mb-12 pl-16"> <svg x-data="{ initializeAnimation: false, init() { setTimeout(() => { this.initializeAnimation = true; }, 0); }, }" :class="initializeAnimation ? 'animate-cube' : ''" class="text-red-600 ml-8" width="46" height="53" viewBox="0 0 46 53" fill="none" xmlns="http://www.w3.org/2000/svg" > <path d="m23.102 1 22.1 12.704v25.404M23.101 1l-22.1 12.704v25.404" stroke="currentColor" stroke-width="1.435" stroke-linejoin="bevel"/><path d="m45.202 39.105-22.1 12.702L1 39.105" stroke="currentColor" stroke-width="1.435" stroke-linejoin="bevel"/><path transform="matrix(.86698 .49834 .00003 1 1 13.699)" stroke="currentColor" stroke-width="1.435" stroke-linejoin="bevel" d="M0 0h25.491v25.405H0z"/><path transform="matrix(.86698 -.49834 -.00003 1 23.102 26.402)" stroke="currentColor" stroke-width="1.435" stroke-linejoin="bevel" d="M0 0h25.491v25.405H0z"/><path transform="matrix(.86701 -.49829 .86701 .49829 1 13.702)" stroke="currentColor" stroke-width="1.435" stroke-linejoin="bevel" d="M0 0h25.491v25.491H0z"/> </svg> <svg x-data="{ initializeAnimation: false, init() { setTimeout(() => { this.initializeAnimation = true; }, 2000); }, }" :class="initializeAnimation ? 'animate-cube' : ''" class="text-red-600 mt-6 ml-32" width="46" height="53" viewBox="0 0 46 53" fill="none" xmlns="http://www.w3.org/2000/svg" > <path d="m23.102 1 22.1 12.704v25.404M23.101 1l-22.1 12.704v25.404" stroke="currentColor" stroke-width="1.435" stroke-linejoin="bevel"/><path d="m45.202 39.105-22.1 12.702L1 39.105" stroke="currentColor" stroke-width="1.435" stroke-linejoin="bevel"/><path transform="matrix(.86698 .49834 .00003 1 1 13.699)" stroke="currentColor" stroke-width="1.435" stroke-linejoin="bevel" d="M0 0h25.491v25.405H0z"/><path transform="matrix(.86698 -.49834 -.00003 1 23.102 26.402)" stroke="currentColor" stroke-width="1.435" stroke-linejoin="bevel" d="M0 0h25.491v25.405H0z"/><path transform="matrix(.86701 -.49829 .86701 .49829 1 13.702)" stroke="currentColor" stroke-width="1.435" stroke-linejoin="bevel" d="M0 0h25.491v25.491H0z"/> </svg> <svg x-data="{ initializeAnimation: false, init() { setTimeout(() => { this.initializeAnimation = true; }, 1000); }, }" :class="initializeAnimation ? 'animate-cube' : ''" class="text-red-600 mt-12" width="46" height="53" viewBox="0 0 46 53" fill="none" xmlns="http://www.w3.org/2000/svg" > <path d="m23.102 1 22.1 12.704v25.404M23.101 1l-22.1 12.704v25.404" stroke="currentColor" stroke-width="1.435" stroke-linejoin="bevel"/><path d="m45.202 39.105-22.1 12.702L1 39.105" stroke="currentColor" stroke-width="1.435" stroke-linejoin="bevel"/><path transform="matrix(.86698 .49834 .00003 1 1 13.699)" stroke="currentColor" stroke-width="1.435" stroke-linejoin="bevel" d="M0 0h25.491v25.405H0z"/><path transform="matrix(.86698 -.49834 -.00003 1 23.102 26.402)" stroke="currentColor" stroke-width="1.435" stroke-linejoin="bevel" d="M0 0h25.491v25.405H0z"/><path transform="matrix(.86701 -.49829 .86701 .49829 1 13.702)" stroke="currentColor" stroke-width="1.435" stroke-linejoin="bevel" d="M0 0h25.491v25.491H0z"/> </svg> </div> </div> </div> </aside> <header id="header" class="lg:hidden" @keydown.window.escape="navIsOpen = false" @click.away="navIsOpen = false" > <div class="relative mx-auto w-full py-10 bg-white transition duration-200 dark:bg-dark-700"> <div class="mx-auto px-8 sm:px-16 flex items-center justify-between"> <a href="/" class="flex items-center"> <img class="" src="/img/logomark.min.svg" alt="Laravel"> <span class="hidden sm:block ml-5 text-red-500 text-3xl font-medium">Bootcamp</span> </a> <div class="flex-1 flex items-center justify-end"> <button id="header__sun" onclick="toSystemMode()" title="Switch to system theme" class="relative w-10 h-10 focus:outline-none focus:shadow-outline text-gray-500"> <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-sun" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none"></path> <circle cx="12" cy="12" r="4"></circle> <path d="M3 12h1m8 -9v1m8 8h1m-9 8v1m-6.4 -15.4l.7 .7m12.1 -.7l-.7 .7m0 11.4l.7 .7m-12.1 -.7l-.7 .7"></path> </svg> </button> <button id="header__moon" onclick="toLightMode()" title="Switch to light mode" class="relative w-10 h-10 focus:outline-none focus:shadow-outline text-gray-500"> <svg style="width:24px;height:24px" viewBox="0 0 24 24"> <path fill="currentColor" d="M17.75,4.09L15.22,6.03L16.13,9.09L13.5,7.28L10.87,9.09L11.78,6.03L9.25,4.09L12.44,4L13.5,1L14.56,4L17.75,4.09M21.25,11L19.61,12.25L20.2,14.23L18.5,13.06L16.8,14.23L17.39,12.25L15.75,11L17.81,10.95L18.5,9L19.19,10.95L21.25,11M18.97,15.95C19.8,15.87 20.69,17.05 20.16,17.8C19.84,18.25 19.5,18.67 19.08,19.07C15.17,23 8.84,23 4.94,19.07C1.03,15.17 1.03,8.83 4.94,4.93C5.34,4.53 5.76,4.17 6.21,3.85C6.96,3.32 8.14,4.21 8.06,5.04C7.79,7.9 8.75,10.87 10.95,13.06C13.14,15.26 16.1,16.22 18.97,15.95M17.33,17.97C14.5,17.81 11.7,16.64 9.53,14.5C7.36,12.31 6.2,9.5 6.04,6.68C3.23,9.82 3.34,14.64 6.35,17.66C9.37,20.67 14.19,20.78 17.33,17.97Z" /> </svg> </button> <button id="header__indeterminate" onclick="toDarkMode()" title="Switch to dark mode" class="relative w-10 h-10 focus:outline-none focus:shadow-outline text-gray-500"> <svg style="width:24px;height:24px" viewBox="0 0 24 24"> <path fill="currentColor" d="M12 2A10 10 0 0 0 2 12A10 10 0 0 0 12 22A10 10 0 0 0 22 12A10 10 0 0 0 12 2M12 4A8 8 0 0 1 20 12A8 8 0 0 1 12 20V4Z" /> </svg> </button> <button class="ml-2 relative w-10 h-10 p-2 text-red-600 lg:hidden focus:outline-none focus:shadow-outline" aria-label="Menu" @click.prevent="navIsOpen = !navIsOpen"> <svg x-show="! navIsOpen" x-transition.opacity class="absolute inset-0 mt-2 ml-2 w-6 h-6" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line></svg> <svg x-show="navIsOpen" x-transition.opacity x-cloak class="absolute inset-0 mt-2 ml-2 w-6 h-6" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg> </button> </div> </div> <span :class="{ 'shadow-sm': navIsOpen }" class="absolute inset-0 z-20 pointer-events-none"></span> </div> <div x-show="navIsOpen" x-transition:enter="duration-150" x-transition:leave="duration-100 ease-in" x-cloak > <nav x-show="navIsOpen" x-cloak class="absolute w-full transform origin-top shadow-sm z-10" x-transition:enter="duration-150 ease-out" x-transition:enter-start="opacity-0 -translate-y-8 scale-75" x-transition:enter-end="opacity-100 scale-100" x-transition:leave="duration-100 ease-in" x-transition:leave-start="opacity-100 scale-100" x-transition:leave-end="opacity-0 -translate-y-8 scale-75" > <div class="relative p-8 bg-white docs_sidebar dark:bg-dark-600"> <ul> <li> <h2><a id="introduction" href="#introduction" class="heading-permalink" aria-hidden="true" title="Permalink">#</a><a href="/introduction">Introduction</a></h2> </li> <li> <h2><a id="build-chirper-with-blade" href="#build-chirper-with-blade" class="heading-permalink" aria-hidden="true" title="Permalink">#</a>Build Chirper with Blade</h2> <ul> <li> <a href="/blade/installation">Installation</a> </li> <li> <a href="/blade/creating-chirps">Creating Chirps</a> </li> <li> <a href="/blade/showing-chirps">Showing Chirps</a> </li> <li> <a href="/blade/editing-chirps">Editing Chirps</a> </li> <li> <a href="/blade/deleting-chirps">Deleting Chirps</a> </li> <li> <a href="/blade/notifications-and-events">Notifications &amp; Events</a> </li> </ul> </li> <li> <h2><a id="build-chirper-with-livewire" href="#build-chirper-with-livewire" class="heading-permalink" aria-hidden="true" title="Permalink">#</a>Build Chirper with Livewire</h2> <ul> <li> <a href="/livewire/installation">Installation</a> </li> <li> <a href="/livewire/creating-chirps">Creating Chirps</a> </li> <li> <a href="/livewire/showing-chirps">Showing Chirps</a> </li> <li> <a href="/livewire/editing-chirps">Editing Chirps</a> </li> <li> <a href="/livewire/deleting-chirps">Deleting Chirps</a> </li> <li> <a href="/livewire/notifications-and-events">Notifications &amp; Events</a> </li> </ul> </li> <li> <h2><a id="build-chirper-with-inertia" href="#build-chirper-with-inertia" class="heading-permalink" aria-hidden="true" title="Permalink">#</a>Build Chirper with Inertia</h2> <ul> <li> <a href="/inertia/installation">Installation</a> </li> <li> <a href="/inertia/creating-chirps">Creating Chirps</a> </li> <li> <a href="/inertia/showing-chirps">Showing Chirps</a> </li> <li> <a href="/inertia/editing-chirps">Editing Chirps</a> </li> <li> <a href="/inertia/deleting-chirps">Deleting Chirps</a> </li> <li> <a href="/inertia/notifications-and-events">Notifications &amp; Events</a> </li> </ul> </li> <li> <h2><a id="deploying" href="#deploying" class="heading-permalink" aria-hidden="true" title="Permalink">#</a><a href="/deploying">Deploying</a></h2> </li> <li> <h2><a id="conclusion" href="#conclusion" class="heading-permalink" aria-hidden="true" title="Permalink">#</a><a href="/conclusion">Conclusion</a></h2> </li> </ul> </div> </nav> </div> </header> <section class="flex-1 dark:bg-dark-700"> <span class="hidden dark:hidden fixed -bottom-[350px] ml-[300px] bg-radial-gradient opacity-[.15] pointer-events-none lg:inline-flex w-[800px] h-[600px]"></span> <div class="px-8 sm:px-16 lg:px-24"> <div class="max-w-screen-lg flex flex-col items-end transition-colors dark:border-gray-700 lg:mt-8 lg:flex-row-reverse"> <div class="fixed top-8 hidden lg:flex items-center justify-center"> <button id="header__sun" onclick="toSystemMode()" title="Switch to system theme" class="relative w-10 h-10 focus:outline-none focus:shadow-outline text-gray-500"> <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-sun" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none"></path> <circle cx="12" cy="12" r="4"></circle> <path d="M3 12h1m8 -9v1m8 8h1m-9 8v1m-6.4 -15.4l.7 .7m12.1 -.7l-.7 .7m0 11.4l.7 .7m-12.1 -.7l-.7 .7"></path> </svg> </button> <button id="header__moon" onclick="toLightMode()" title="Switch to light mode" class="relative w-10 h-10 focus:outline-none focus:shadow-outline text-gray-500"> <svg style="width:24px;height:24px" viewBox="0 0 24 24"> <path fill="currentColor" d="M17.75,4.09L15.22,6.03L16.13,9.09L13.5,7.28L10.87,9.09L11.78,6.03L9.25,4.09L12.44,4L13.5,1L14.56,4L17.75,4.09M21.25,11L19.61,12.25L20.2,14.23L18.5,13.06L16.8,14.23L17.39,12.25L15.75,11L17.81,10.95L18.5,9L19.19,10.95L21.25,11M18.97,15.95C19.8,15.87 20.69,17.05 20.16,17.8C19.84,18.25 19.5,18.67 19.08,19.07C15.17,23 8.84,23 4.94,19.07C1.03,15.17 1.03,8.83 4.94,4.93C5.34,4.53 5.76,4.17 6.21,3.85C6.96,3.32 8.14,4.21 8.06,5.04C7.79,7.9 8.75,10.87 10.95,13.06C13.14,15.26 16.1,16.22 18.97,15.95M17.33,17.97C14.5,17.81 11.7,16.64 9.53,14.5C7.36,12.31 6.2,9.5 6.04,6.68C3.23,9.82 3.34,14.64 6.35,17.66C9.37,20.67 14.19,20.78 17.33,17.97Z" /> </svg> </button> <button id="header__indeterminate" onclick="toDarkMode()" title="Switch to dark mode" class="relative w-10 h-10 focus:outline-none focus:shadow-outline text-gray-500"> <svg style="width:24px;height:24px" viewBox="0 0 24 24"> <path fill="currentColor" d="M12 2A10 10 0 0 0 2 12A10 10 0 0 0 12 22A10 10 0 0 0 22 12A10 10 0 0 0 12 2M12 4A8 8 0 0 1 20 12A8 8 0 0 1 12 20V4Z" /> </svg> </button> </div> </div> <section class="pt-8 pb-8 md:pt-16 md:pb-16 flex"> <section class="docs_main flex-1 max-w-full"> <div id="main-content"> <div class="prose dark:prose-invert relative"> <aside class="table-of-contents-sidebar-wrapper not-prose"><aside class="table-of-contents-sidebar not-prose"><h2>On this page</h2><ul class="table-of-contents"> <li> <a href="#creating-the-notification">Creating the notification</a> </li> <li> <a href="#creating-an-event">Creating an event</a> </li> <li> <a href="#dispatching-the-event">Dispatching the event</a> </li> <li> <a href="#creating-an-event-listener">Creating an event listener</a> </li> <li> <a href="#testing-it-out">Testing it out</a> <ul> <li> <a href="#sending-emails-in-production">Sending emails in production</a> </li> </ul> </li> </ul></aside></aside> <h1><b>07.</b> Notifications &amp; Events</h1> <p>Let's take Chirper to the next level by sending <a href="https://laravel.com/docs/notifications#introduction">email notifications</a> when a new Chirp is created.</p> <p>In addition to support for sending email, Laravel provides support for sending notifications across a variety of delivery channels, including email, SMS, and Slack. Plus, a variety of community built notification channels have been created to send notification over dozens of different channels! Notifications may also be stored in a database so they may be displayed in your web interface.</p> <h2><a id="creating-the-notification" href="#creating-the-notification" class="heading-permalink" aria-hidden="true" title="Permalink">#</a>Creating the notification</h2> <p>Artisan can, once again, do all the hard work for us with the following command:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="shell" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BFC7D5;">php </span><span style="color: #BFC7D5;">artisan</span><span style="color: #BFC7D5;"> </span><span style="color: #BFC7D5;">make:notification</span><span style="color: #BFC7D5;"> </span><span style="color: #BFC7D5;">NewChirp</span></div></code></pre> </div> <p>This will create a new notification at <code>app/Notifications/NewChirp.php</code> that is ready for us to customize.</p> <p>Let's open the <code>NewChirp</code> class and allow it to accept the <code>Chirp</code> that was just created, and then customize the message to include the author's name and a snippet from the message:</p> <div class="code-container"> <div class="code-container-filename">app/Notifications/NewChirp.php</div> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight has-add-lines has-remove-lines has-diff-lines has-summaries' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #D3423E;">&lt;?php</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #C792EA;">namespace</span><span style="color: #BFC7D5;"> App\Notifications;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span>&nbsp;</div><div class='line line-add line-has-background' style='background-color: #99b76d23'><span style="color:#C3E88D; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">+</span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> App\Models\</span><span style="color: #FFCB8B;">Chirp</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Bus\</span><span style="color: #FFCB8B;">Queueable</span><span style="color: #BFC7D5;">;</span></div><div class='line line-add line-has-background' style='background-color: #99b76d23'><span style="color:#C3E88D; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">+</span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Support\</span><span style="color: #FFCB8B;">Str</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Contracts\Queue\</span><span style="color: #FFCB8B;">ShouldQueue</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Notifications\Messages\</span><span style="color: #FFCB8B;">MailMessage</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Notifications\</span><span style="color: #FFCB8B;">Notification</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span>&nbsp;</div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #C792EA;">class</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB6B;">NewChirp</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">extends</span><span style="color: #BFC7D5;"> </span><span style="color: #A9C77D;">Notification</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;">{</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">Queueable</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span>&nbsp;</div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #697098;">/**</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #697098;"> * Create a new notification instance.</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #697098;"> </span><span style="color: #697098;">*/</span></div><div class='line line-remove line-has-background' style='background-color: #ef535033'><span style="color:#f07178; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">-</span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">public</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">__construct</span><span style="color: #D9F5DD;">()</span></div><div class='line line-add line-has-background' style='background-color: #99b76d23'><span style="color:#C3E88D; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">+</span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">public</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">__construct</span><span style="color: #D9F5DD;">(</span><span style="color: #C792EA;">public</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">Chirp</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$chirp</span><span style="color: #D9F5DD;">)</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> }</span></div><details><summary style='cursor: pointer; display: block'><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-start' style='user-select: none; color: #4c5374'></span>&nbsp;<span class='summary-hide-when-open' style='color:#4c5374'>...</span></div></summary><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #697098;">/**</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #697098;"> * Get the notification&#39;s delivery channels.</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #697098;"> *</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #697098;"> * </span><span style="color: #C792EA;">@return</span><span style="color: #697098;"> </span><span style="color: #C792EA;">array</span><span style="color: #697098;">&lt;</span><span style="color: #C792EA;">int</span><span style="color: #697098;">, string&gt;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #697098;"> </span><span style="color: #697098;">*/</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">public</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">via</span><span style="color: #D9F5DD;">(</span><span style="color: #C792EA;">object</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$notifiable</span><span style="color: #D9F5DD;">)</span><span style="color: #89DDFF;">:</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">array</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> [</span><span style="color: #D9F5DD;">&#39;</span><span style="color: #C3E88D;">mail</span><span style="color: #D9F5DD;">&#39;</span><span style="color: #BFC7D5;">];</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> }</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-end' style='user-select: none; color: #4c5374'></span>&nbsp;</div></details><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #697098;">/**</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #697098;"> * Get the mail representation of the notification.</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #697098;"> </span><span style="color: #697098;">*/</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">public</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">toMail</span><span style="color: #D9F5DD;">(</span><span style="color: #C792EA;">object</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$notifiable</span><span style="color: #D9F5DD;">)</span><span style="color: #89DDFF;">:</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">MailMessage</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> (</span><span style="color: #89DDFF;">new</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">MailMessage</span><span style="color: #BFC7D5;">)</span></div><div class='line line-remove line-has-background' style='background-color: #ef535033'><span style="color:#f07178; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">-</span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">line</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">&#39;</span><span style="color: #C3E88D;">The introduction to the notification.</span><span style="color: #D9F5DD;">&#39;</span><span style="color: #BFC7D5;">)</span></div><div class='line line-remove line-has-background' style='background-color: #ef535033'><span style="color:#f07178; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">-</span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">action</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">&#39;</span><span style="color: #C3E88D;">Notification Action</span><span style="color: #D9F5DD;">&#39;</span><span style="color: #BFC7D5;">, </span><span style="color: #82AAFF;">url</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">&#39;</span><span style="color: #C3E88D;">/</span><span style="color: #D9F5DD;">&#39;</span><span style="color: #BFC7D5;">))</span></div><div class='line line-add line-has-background' style='background-color: #99b76d23'><span style="color:#C3E88D; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">+</span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">subject</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">&quot;</span><span style="color: #C3E88D;">New Chirp from {</span><span style="color: #FF5572;">$this</span><span style="color: #89DDFF;">-&gt;chirp-&gt;user-&gt;name</span><span style="color: #C3E88D;">}</span><span style="color: #D9F5DD;">&quot;</span><span style="color: #BFC7D5;">)</span></div><div class='line line-add line-has-background' style='background-color: #99b76d23'><span style="color:#C3E88D; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">+</span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">greeting</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">&quot;</span><span style="color: #C3E88D;">New Chirp from {</span><span style="color: #FF5572;">$this</span><span style="color: #89DDFF;">-&gt;chirp-&gt;user-&gt;name</span><span style="color: #C3E88D;">}</span><span style="color: #D9F5DD;">&quot;</span><span style="color: #BFC7D5;">)</span></div><div class='line line-add line-has-background' style='background-color: #99b76d23'><span style="color:#C3E88D; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">+</span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">line</span><span style="color: #BFC7D5;">(</span><span style="color: #FFCB8B;">Str</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">limit</span><span style="color: #BFC7D5;">(</span><span style="color: #FF5572;">$this</span><span style="color: #89DDFF;">-&gt;chirp-&gt;message</span><span style="color: #BFC7D5;">, </span><span style="color: #F78C6C;">50</span><span style="color: #BFC7D5;">))</span></div><div class='line line-add line-has-background' style='background-color: #99b76d23'><span style="color:#C3E88D; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">+</span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">action</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">&#39;</span><span style="color: #C3E88D;">Go to Chirper</span><span style="color: #D9F5DD;">&#39;</span><span style="color: #BFC7D5;">, </span><span style="color: #82AAFF;">url</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">&#39;</span><span style="color: #C3E88D;">/</span><span style="color: #D9F5DD;">&#39;</span><span style="color: #BFC7D5;">))</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">line</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">&#39;</span><span style="color: #C3E88D;">Thank you for using our application!</span><span style="color: #D9F5DD;">&#39;</span><span style="color: #BFC7D5;">);</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> }</span></div><details><summary style='cursor: pointer; display: block'><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-start' style='user-select: none; color: #4c5374'></span>&nbsp;<span class='summary-hide-when-open' style='color:#4c5374'>...</span></div></summary><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #697098;">/**</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #697098;"> * Get the array representation of the notification.</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #697098;"> *</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #697098;"> * </span><span style="color: #C792EA;">@return</span><span style="color: #697098;"> </span><span style="color: #C792EA;">array</span><span style="color: #697098;">&lt;</span><span style="color: #C792EA;">string</span><span style="color: #697098;">, mixed&gt;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #697098;"> </span><span style="color: #697098;">*/</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">public</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">toArray</span><span style="color: #D9F5DD;">(</span><span style="color: #C792EA;">object</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$notifiable</span><span style="color: #D9F5DD;">)</span><span style="color: #89DDFF;">:</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">array</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> [</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> ];</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> }</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-end' style='user-select: none; color: #4c5374'></span>&nbsp;</div></details><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;">}</span></div></code></pre> </div> <p>We could send the notification directly from the <code>store</code> method on our <code>ChirpController</code> class, but that adds more work for the controller, which in turn can slow down the request, especially as we'll be querying the database and sending emails.</p> <p>Instead, let's dispatch an event that we can listen for and process in a background queue to keep our application snappy.</p> <h2><a id="creating-an-event" href="#creating-an-event" class="heading-permalink" aria-hidden="true" title="Permalink">#</a>Creating an event</h2> <p>Events are a great way to decouple various aspects of your application, since a single event can have multiple listeners that do not depend on each other.</p> <p>Let's create our new event with the following command:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="shell" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BFC7D5;">php </span><span style="color: #BFC7D5;">artisan</span><span style="color: #BFC7D5;"> </span><span style="color: #BFC7D5;">make:event</span><span style="color: #BFC7D5;"> </span><span style="color: #BFC7D5;">ChirpCreated</span></div></code></pre> </div> <p>This will create a new event class at <code>app/Events/ChirpCreated.php</code>.</p> <p>Since we'll be dispatching events for each new Chirp that is created, let's update our <code>ChirpCreated</code> event to accept the newly created <code>Chirp</code> so we may pass it on to our notification:</p> <div class="code-container"> <div class="code-container-filename">app/Events/ChirpCreated.php</div> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight has-add-lines has-remove-lines has-diff-lines has-summaries' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #D3423E;">&lt;?php</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span>&nbsp;</div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #C792EA;">namespace</span><span style="color: #BFC7D5;"> App\Events;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span>&nbsp;</div><div class='line line-add line-has-background' style='background-color: #99b76d23'><span style="color:#C3E88D; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">+</span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> App\Models\</span><span style="color: #FFCB8B;">Chirp</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Broadcasting\</span><span style="color: #FFCB8B;">Channel</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Broadcasting\</span><span style="color: #FFCB8B;">InteractsWithSockets</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Broadcasting\</span><span style="color: #FFCB8B;">PresenceChannel</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Broadcasting\</span><span style="color: #FFCB8B;">PrivateChannel</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Contracts\Broadcasting\</span><span style="color: #FFCB8B;">ShouldBroadcast</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Foundation\Events\</span><span style="color: #FFCB8B;">Dispatchable</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Queue\</span><span style="color: #FFCB8B;">SerializesModels</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span>&nbsp;</div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #C792EA;">class</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB6B;">ChirpCreated</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;">{</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">Dispatchable</span><span style="color: #BFC7D5;">, </span><span style="color: #FFCB8B;">InteractsWithSockets</span><span style="color: #BFC7D5;">, </span><span style="color: #FFCB8B;">SerializesModels</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span>&nbsp;</div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #697098;">/**</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #697098;"> * Create a new event instance.</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #697098;"> </span><span style="color: #697098;">*/</span></div><div class='line line-remove line-has-background' style='background-color: #ef535033'><span style="color:#f07178; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">-</span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">public</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">__construct</span><span style="color: #D9F5DD;">()</span></div><div class='line line-add line-has-background' style='background-color: #99b76d23'><span style="color:#C3E88D; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">+</span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">public</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">__construct</span><span style="color: #D9F5DD;">(</span><span style="color: #C792EA;">public</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">Chirp</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$chirp</span><span style="color: #D9F5DD;">)</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> }</span></div><details><summary style='cursor: pointer; display: block'><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-start' style='user-select: none; color: #4c5374'></span>&nbsp;<span class='summary-hide-when-open' style='color:#4c5374'>...</span></div></summary><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #697098;">/**</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #697098;"> * Get the channels the event should broadcast on.</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #697098;"> </span><span style="color: #697098;">*/</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">public</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">broadcastOn</span><span style="color: #D9F5DD;">()</span><span style="color: #89DDFF;">:</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">array</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> [</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">new</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">PrivateChannel</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">&#39;</span><span style="color: #C3E88D;">channel-name</span><span style="color: #D9F5DD;">&#39;</span><span style="color: #BFC7D5;">),</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> ];</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> }</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-end' style='user-select: none; color: #4c5374'></span>&nbsp;</div></details><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;">}</span></div></code></pre> </div> <h2><a id="dispatching-the-event" href="#dispatching-the-event" class="heading-permalink" aria-hidden="true" title="Permalink">#</a>Dispatching the event</h2> <p>Now that we have our event class, we're ready to dispatch it any time a Chirp is created. You may <a href="https://laravel.com/docs/events#dispatching-events">dispatch events</a> anywhere in your application lifecycle, but as our event relates to the creation of an Eloquent model, we can configure our <code>Chirp</code> model to dispatch the event for us.</p> <div class="code-container"> <div class="code-container-filename">app/Models/Chirp.php</div> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight has-add-lines has-diff-lines' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span style="color: #D3423E;">&lt;?php</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span>&nbsp;</div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span style="color: #C792EA;">namespace</span><span style="color: #BFC7D5;"> App\Models;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span>&nbsp;</div><div class='line line-add line-has-background' style='background-color: #99b76d23'><span style="color:#C3E88D; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">+</span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> App\Events\</span><span style="color: #FFCB8B;">ChirpCreated</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Database\Eloquent\Factories\</span><span style="color: #FFCB8B;">HasFactory</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Database\Eloquent\</span><span style="color: #FFCB8B;">Model</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Database\Eloquent\Relations\</span><span style="color: #FFCB8B;">BelongsTo</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span>&nbsp;</div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span style="color: #C792EA;">class</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB6B;">Chirp</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">extends</span><span style="color: #BFC7D5;"> </span><span style="color: #A9C77D;">Model</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span style="color: #BFC7D5;">{</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">HasFactory</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span>&nbsp;</div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">protected</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$fillable</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> [</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">&#39;</span><span style="color: #C3E88D;">message</span><span style="color: #D9F5DD;">&#39;</span><span style="color: #BFC7D5;">,</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span style="color: #BFC7D5;"> ];</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span>&nbsp;</div><div class='line line-add line-has-background' style='background-color: #99b76d23'><span style="color:#C3E88D; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">+</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">protected</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$dispatchesEvents</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">=</span><span style="color: #BFC7D5;"> [</span></div><div class='line line-add line-has-background' style='background-color: #99b76d23'><span style="color:#C3E88D; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">+</span><span style="color: #BFC7D5;"> </span><span style="color: #D9F5DD;">&#39;</span><span style="color: #C3E88D;">created</span><span style="color: #D9F5DD;">&#39;</span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">ChirpCreated</span><span style="color: #89DDFF;">::</span><span style="color: #C792EA;">class</span><span style="color: #BFC7D5;">,</span></div><div class='line line-add line-has-background' style='background-color: #99b76d23'><span style="color:#C3E88D; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">+</span><span style="color: #BFC7D5;"> ];</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span>&nbsp;</div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">public</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">user</span><span style="color: #D9F5DD;">()</span><span style="color: #89DDFF;">:</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">BelongsTo</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">return</span><span style="color: #BFC7D5;"> </span><span style="color: #FF5572;">$this</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">belongsTo</span><span style="color: #BFC7D5;">(</span><span style="color: #FFCB8B;">User</span><span style="color: #89DDFF;">::</span><span style="color: #C792EA;">class</span><span style="color: #BFC7D5;">);</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span style="color: #BFC7D5;"> }</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span style="color: #BFC7D5;">}</span></div></code></pre> </div> <p>Now any time a new <code>Chirp</code> is created, the <code>ChirpCreated</code> event will be dispatched.</p> <h2><a id="creating-an-event-listener" href="#creating-an-event-listener" class="heading-permalink" aria-hidden="true" title="Permalink">#</a>Creating an event listener</h2> <p>Now that we're dispatching an event, we're ready to listen for that event and send our notification.</p> <p>Let's create a listener that subscribes to our <code>ChirpCreated</code> event:</p> <div class="code-container"> <pre><code data-theme="olaolu-palenight" data-lang="sail" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #BFC7D5;">php artisan make:listener SendChirpCreatedNotifications --event=ChirpCreated</span></div></code></pre> </div> <p>The new listener will be placed at <code>app/Listeners/SendChirpCreatedNotifications.php</code>. Let's update the listener to send our notifications.</p> <div class="code-container"> <div class="code-container-filename">app/Listeners/SendChirpCreatedNotifications.php</div> <pre><code data-theme="olaolu-palenight" data-lang="php" class='torchlight has-add-lines has-remove-lines has-diff-lines has-summaries' style='background-color: #292D3E; --theme-selection-background: #7580B850;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #D3423E;">&lt;?php</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span>&nbsp;</div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #C792EA;">namespace</span><span style="color: #BFC7D5;"> App\Listeners;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span>&nbsp;</div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> App\Events\</span><span style="color: #FFCB8B;">ChirpCreated</span><span style="color: #BFC7D5;">;</span></div><div class='line line-add line-has-background' style='background-color: #99b76d23'><span style="color:#C3E88D; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">+</span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> App\Models\</span><span style="color: #FFCB8B;">User</span><span style="color: #BFC7D5;">;</span></div><div class='line line-add line-has-background' style='background-color: #99b76d23'><span style="color:#C3E88D; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">+</span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> App\Notifications\</span><span style="color: #FFCB8B;">NewChirp</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Contracts\Queue\</span><span style="color: #FFCB8B;">ShouldQueue</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #C792EA;">use</span><span style="color: #BFC7D5;"> Illuminate\Queue\</span><span style="color: #FFCB8B;">InteractsWithQueue</span><span style="color: #BFC7D5;">;</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span>&nbsp;</div><div class='line line-remove line-has-background' style='background-color: #ef535033'><span style="color:#f07178; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">-</span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #C792EA;">class</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB6B;">SendChirpCreatedNotifications</span></div><div class='line line-add line-has-background' style='background-color: #99b76d23'><span style="color:#C3E88D; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">+</span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;">class SendChirpCreatedNotifications </span><span style="color: #C792EA;">implements</span><span style="color: #BFC7D5;"> </span><span style="color: #A9C77D;">ShouldQueue</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;">{</span></div><details><summary style='cursor: pointer; display: block'><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-start' style='user-select: none; color: #4c5374'></span>&nbsp;<span class='summary-hide-when-open' style='color:#4c5374'>...</span></div></summary><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #697098;">/**</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #697098;"> * Create the event listener.</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #697098;"> </span><span style="color: #697098;">*/</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">public</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #89DDFF;">__construct</span><span style="color: #D9F5DD;">()</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> {</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-middle' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> }</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-end' style='user-select: none; color: #4c5374'></span>&nbsp;</div></details><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #697098;">/**</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #697098;"> * Handle the event.</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #697098;"> </span><span style="color: #697098;">*/</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">public</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">function</span><span style="color: #BFC7D5;"> </span><span style="color: #82AAFF;">handle</span><span style="color: #D9F5DD;">(</span><span style="color: #FFCB8B;">ChirpCreated</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$event</span><span style="color: #D9F5DD;">)</span><span style="color: #89DDFF;">:</span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">void</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> {</span></div><div class='line line-remove line-has-background' style='background-color: #ef535033'><span style="color:#f07178; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">-</span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #697098;">//</span></div><div class='line line-add line-has-background' style='background-color: #99b76d23'><span style="color:#C3E88D; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">+</span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #C792EA;">foreach</span><span style="color: #BFC7D5;"> (</span><span style="color: #FFCB8B;">User</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">whereNot</span><span style="color: #BFC7D5;">(</span><span style="color: #D9F5DD;">&#39;</span><span style="color: #C3E88D;">id</span><span style="color: #D9F5DD;">&#39;</span><span style="color: #BFC7D5;">, </span><span style="color: #BEC5D4;">$event</span><span style="color: #89DDFF;">-&gt;chirp-&gt;user_id</span><span style="color: #BFC7D5;">)</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">cursor</span><span style="color: #BFC7D5;">() </span><span style="color: #C792EA;">as</span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$user</span><span style="color: #BFC7D5;">) {</span></div><div class='line line-add line-has-background' style='background-color: #99b76d23'><span style="color:#C3E88D; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">+</span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> </span><span style="color: #BEC5D4;">$user</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">notify</span><span style="color: #BFC7D5;">(</span><span style="color: #89DDFF;">new</span><span style="color: #BFC7D5;"> </span><span style="color: #FFCB8B;">NewChirp</span><span style="color: #BFC7D5;">(</span><span style="color: #BEC5D4;">$event</span><span style="color: #89DDFF;">-&gt;chirp</span><span style="color: #BFC7D5;">));</span></div><div class='line line-add line-has-background' style='background-color: #99b76d23'><span style="color:#C3E88D; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">+</span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> }</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;"> }</span></div><div class='line'><span style="color:#4c5374; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> </span><span class='summary-caret summary-caret-empty' style='user-select: none; color: #4c5374'></span><span style="color: #BFC7D5;">}</span></div></code></pre> </div> <p>We've marked our listener with the <code>ShouldQueue</code> interface, which tells Laravel that the listener should be run in a <a href="https://laravel.com/docs/queues">queue</a>. By default, the &quot;database&quot; queue will be used to process jobs asynchronously. To begin processing queued jobs, you should run the <code>php artisan queue:work</code> Artisan command in your terminal.</p> <p>We've also configured our listener to send notifications to every user in the platform, except the author of the Chirp. In reality, this might annoy users, so you may want to implement a &quot;following&quot; feature so users only receive notifications for accounts they follow.</p> <p>We've used a <a href="https://laravel.com/docs/eloquent#cursors">database cursor</a> to avoid loading every user into memory at once.</p> <aside class="mb-10 max-w-2xl mx-auto px-4 py-8 shadow-lg lg:flex lg:items-center bg-white dark:bg-dark-700"><div class="w-20 h-20 mb-6 flex items-center justify-center shrink-0 bg-purple-600 lg:mb-0"><img src="/img/callouts/lightbulb.min.svg" class="opacity-75"></img></div><div class="lg:ml-6 prose-p:m-0"><p> In a production application you should add the ability for your users to unsubscribe from notifications like these.</p></div></aside> <h2><a id="testing-it-out" href="#testing-it-out" class="heading-permalink" aria-hidden="true" title="Permalink">#</a>Testing it out</h2> <p>You may utilize local email testing tools like <a href="https://github.com/axllent/mailpit">Mailpit</a> and <a href="https://usehelo.com/">HELO</a> to catch any emails coming from your application so you may view them. If you are developing via Docker and Laravel Sail then Mailpit is included for you.</p> <p>Alternatively, you may configure Laravel to write mail to a log file by editing the <code>.env</code> file in your project and changing the <code>MAIL_MAILER</code> environment variable to <code>log</code>. By default, emails will be written to a log file located at <code>storage/logs/laravel.log</code>.</p> <p>We've configured our notification not to send to the Chirp author, so be sure to register at least two users accounts. Then, go ahead and post a new Chirp to trigger a notification.</p> <p>If you're using Mailpit, navigate to <a href="http://localhost:8025/">http://localhost:8025/</a>, where you will find the notification for the message you just chirped!</p> <img src="/img/screenshots/mailpit.png" alt="Mailpit" class="rounded-lg border dark:border-none shadow-lg" /> <h3><a id="sending-emails-in-production" href="#sending-emails-in-production" class="heading-permalink" aria-hidden="true" title="Permalink">#</a>Sending emails in production</h3> <p>To send real emails in production, you will need an SMTP server, or a transactional email provider, such as Mailgun, Postmark, or Amazon SES. Laravel supports all of these out of the box. For more information, take a look at the <a href="https://laravel.com/docs/mail#introduction">Mail documentation</a>.</p> <p><a href="/deploying">Continue to learn about deploying your application...</a></p> </div> <script> // Set the active navigation state... Array.from(document.querySelectorAll('#header a, #sidebar a')).forEach(link => { if (link.hostname === location.hostname && (link.pathname === location.pathname || (link.pathname === '/introduction' && location.pathname === '/')) ) { link.classList.add('active') if (link.parentNode.tagName === 'LI') { link.parentNode.parentNode.parentNode.classList.add('sub--on') } } }) // Make the navigation headings expandable... Array.from(document.querySelectorAll('.docs_sidebar h2')).forEach(el => { if (el.children.length > 1) { return } el.addEventListener('click', (e) => { const active = el.parentNode.classList.contains('sub--on'); [...document.querySelectorAll('.docs_sidebar ul li')].forEach(el => el.classList.remove('sub--on')); if (! active) { el.parentNode.classList.add('sub--on'); } }) }) // Highlight the active section in the table of contents... function setActiveTableOfContents () { const links = Array.from(document.querySelectorAll('.table-of-contents a')) const lastVisible = links .slice() .reverse() .find(link => { const el = document.querySelector(link.hash) return el.getBoundingClientRect().top <= 56; }) ?? links[0] links.forEach(link => { if (link === lastVisible) { link.classList.add('active') } else { link.classList.remove('active') } }) } setActiveTableOfContents() window.addEventListener('scroll', setActiveTableOfContents, { passive: true }) </script> </div> </section> </section> </div> </section> </div> <footer class="relative mt-12 pt-12 bg-gradient-to-b from-gray-50 to-white dark:from-dark-800 dark:to-dark-700"> <div class="max-w-screen-2xl mx-auto w-full px-8"> <div> <a href="https://laravel.com" class="inline-flex"> <img class="h-14" src="/img/logo.min.svg" alt="Laravel" loading="lazy"> </a> </div> <div class="mt-6 sm:mt-12"> <p class="max-w-sm text-xs text-gray-700 sm:text-sm dark:text-gray-500">Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel attempts to take the pain out of development by easing common tasks used in most web projects.</p> <ul class="mt-6 flex items-center space-x-3"> <li> <a href="https://twitter.com/laravelphp"> <img id="footer__twitter_dark" class="hidden dark:inline-block w-6 h-6" src="/img/social/twitter.dark.min.svg" alt="Twitter" loading="lazy" width="24" height="20"> <img id="footer__twitter" class="inline-block dark:hidden w-6 h-6" src="/img/social/twitter.min.svg" alt="Twitter" loading="lazy" width="24" height="20"> </a> </li> <li> <a href="https://github.com/laravel"> <img id="footer__github_dark" class="hidden dark:inline-block w-6 h-6" src="/img/social/github.dark.min.svg" alt="GitHub" loading="lazy" width="24" height="24"> <img id="footer__github" class="inline-block dark:hidden w-6 h-6" src="/img/social/github.min.svg" alt="GitHub" loading="lazy" width="24" height="24"> </a> </li> <li> <a href="https://discord.gg/mPZNm7A"> <img id="footer__discord_dark" class="hidden dark:inline-block w-6 h-6" src="/img/social/discord.dark.min.svg" alt="Discord" loading="lazy" width="21" height="24"> <img id="footer__discord" class="inline-block dark:hidden w-6 h-6" src="/img/social/discord.min.svg" alt="Discord" loading="lazy" width="21" height="24"> </a> </li> <li> <a href="https://www.youtube.com/laravelphp"> <img id="footer__youtube_dark" class="hidden dark:inline-block w-6 h-6" src="/img/social/youtube.dark.min.svg" alt="YouTube" loading="lazy" width="169" height="150"> <img id="footer__youtube" class="inline-block dark:hidden w-6 h-6" src="/img/social/youtube.min.svg" alt="YouTube" loading="lazy" width="169" height="150"> </a> </li> </ul> </div> <div class="mt-10 border-t pt-6 pb-16 border-gray-200 dark:border-dark-500"> <p class="text-xs text-gray-700 dark:text-gray-400"> Laravel is a Trademark of Laravel Holdings Inc.<br /> Copyright &copy; Laravel Holdings Inc. </p> <p class="mt-6 text-xs text-gray-700 dark:text-gray-400"> Code highlighting provided by <a href="https://torchlight.dev">Torchlight</a> </p> </div> </div> </footer> </div> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10