The Ultimate Guide to Laravel Reverb: Real-Time Notifications

Prosper Otemuyiwa - Apr 9 - - Dev Community

You learned a lot about using Laravel Reverb in the first part of this guide. Now, you’ll learn how to add real-time notifications seamlessly to your Laravel apps.

If you've used Laravel Nova, you're likely familiar with the Notification Center. But what if you didn't need to build one from scratch? Imagine being able to add a real-time notification center to your app in less than five minutes.

If you're eager to explore the code immediately, you can view the completed code on GitHub. Let's dive in!

Introducing Novu

Novu is a notification infrastructure tool, built for engineering teams to help them build and set up rich product notification experiences.

Novu provides embeddable Notification Center components, APIs, SDKs and more to help you manage product communication across multiple channels. It provides a full notification infrastructure that provides robust analytics, digest, notification center components, multi-channel notifications and hundreds of notification providers.

Set Up Novu

The first step is to sign up on Novu.

Now, run the following command to install the Novu Laravel SDK:



composer require novu/novu-laravel


Enter fullscreen mode Exit fullscreen mode

Publish the configuration file using this command:



php artisan vendor:publish --tag="novu-laravel-config"


Enter fullscreen mode Exit fullscreen mode

A configuration file named novu.php with some sensible defaults will be placed in your config directory. Open up your .env file and add the NOVU_API_KEY variable to it.

Note: Grab your API key from Settings in your Novu dashboard.

Before we can start sending and receiving notifications in our app, we need to set up a few things:

  • Create a Novu workflow for sending notifications,
  • Create a subscriber - recipient of notifications,
  • Add a Novu Notification Center component inside our view to display real-time notifications.

Create a Novu Workflow

A workflow is a blueprint for notifications. It includes the following:

  • Workflow name and Identifier
  • Channels: - Email, SMS, Chat, In-App and Push.
  • Channel Notification Content Editor

Follow the steps below to create a workflow:

  • Click Workflow on the left sidebar of your Novu dashboard.
  • Click the Add a Workflow button on the top left. You can select a Blank workflow or use one of the existing templates.
  • The name of the new workflow is currently “Untitled”. Rename it to Laravel In-App Notifications
  • Select In-App as the channel you want to add.

Select Channel5. Click on the recently added “In-App” channel and add the following text to it. Once you’re done, click “Update” to save your configuration.

In-App Content EditingThe {{deliveryStatus }}, and {{deliveryHandler}} are custom variables. This means that we can pass them to our payload before we trigger a notification.

You’ll see this when we add the code to trigger a notification.

Create a subscriber

If you click “Subscriber” on the left sidebar of the Novu dashboard, you’ll see the subscriber list. As a first time Novu user, it will be an empty list. Subscribers are your app users.

This implies that when a user registers an account in our app, we must also add them as a subscriber in Novu.

Subscriber creationFor a test run, open your terminal and run the following script to create a subscriber:



curl --location '<https://api.novu.co/v1/subscribers>' \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json' \
  --header 'Authorization: ApiKey <NOVU_API_KEY>' \
  --data-raw '{
    "firstName": "John",
    "lastName": "Doe",
    "email": "johndoe@domain.com",
    "phone": "+1234567890"
    }'


Enter fullscreen mode Exit fullscreen mode

Note: You can use the details of the user that is already signed up on the app. Refresh the Subscribers page on your Novu dashboard. You should see the recently added subscriber. The one you added via the terminal!

The optimal approach is to add a subscriber through backend code. Just as the user is being added to the database, invoke the code to add the user as a subscriber on Novu. Let’s do that in our app.

We utilized the Laravel JetStream kit. Therefore, our authentication and login logic should be located within the app/Actions/Fortify directory.

Open up app/Actions/Fortify/CreateNewUser.php and modify the class to include Novu logic to create a subscriber on Novu from the user’s details.



<?php

namespace App\Actions\Fortify;

use App\Models\User;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Laravel\Fortify\Contracts\CreatesNewUsers;
use Laravel\Jetstream\Jetstream;

class CreateNewUser implements CreatesNewUsers
{
    use PasswordValidationRules;

    /**
     * Validate and create a newly registered user.
     *
     * @param  array<string, string>  $input
     */
    public function create(array $input): User
    {
        Validator::make($input, [
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'password' => $this->passwordRules(),
            'terms' => Jetstream::hasTermsAndPrivacyPolicyFeature() ? ['accepted', 'required'] : '',
        ])->validate();

        $user = User::create([
            'name' => $input['name'],
            'email' => $input['email'],
            'password' => Hash::make($input['password']),
        ]);

        // Create subscriber on Novu
        novu()->createSubscriber([
            'subscriberId' => $user->id,
            'email' => $user->email,
            'firstName' => $user->name,
        ])->toArray();

        return $user;
    }
}


Enter fullscreen mode Exit fullscreen mode

Reload your app, create a brand new user and check the Novu subscribers section of your dashboard.

Subscribers pageList of SubscribersSet up & Display Novu Notification Center in your Laravel App

Head over to resources/views/components directory.

Create a notification-center.blade.php file in the directory and add the following code to it:



<notification-center-component
      style="{{ $style ?? '' }}"
      application-identifier="{!! $appId ?? '' !!}"
      subscriber-id="{!! $subscriberId ?? '' !!}"
    ></notification-center-component>

<script type="text/javascript">
    let nc = document.getElementsByTagName('notification-center-component')[0];
    nc.onLoad = () => console.log('notification center loaded!');
</script>


Enter fullscreen mode Exit fullscreen mode

Head over to resources/views/layouts/app.blade.php file. At the scripts section, add the following to invoke the Novu Notification Center component:



<script src="<https://novu-web-component.netlify.app/index.js>" type="text/javascript" defer></script>


Enter fullscreen mode Exit fullscreen mode

In the body, call the notification center blade component like so:



...
<div class="min-h-screen bg-gray-100 dark:bg-gray-900">
            @livewire('navigation-menu')


            @if (isset($header))


            <header class="bg-white dark:bg-gray-800 shadow">
                    <div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
                        {{ $header }}  
                    </div>
                    <div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
                        <x-notification-center app-id="MavBpIkktq7-" 
                                    subscriber-id="{{ auth()->user()->id }}" 
                                    style="display: inline-flex;">
                        </x-notification-center>
                    </div>
                </header>
            @endif

            <livewire:delivery-history />


            <main>
                {{ $slot }}
            </main>

</div>
...


Enter fullscreen mode Exit fullscreen mode

From the code above, you can see that we added the following:



<div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
      <x-notification-center app-id="MavBpIkktq7-" 
                  subscriber-id="{{ auth()->user()->id }}" 
                  style="display: inline-flex;">
      </x-notification-center>
</div>


Enter fullscreen mode Exit fullscreen mode

Note: I have added the APP ID & Subscriber ID. The value of the APP ID is from the Novu Settings dashboard while the Subscriber ID is the ID of the logged in user.

Now you should have something like this on your dashboard showing the notification bell:

Dashboard showing the notification bellNotification bellTrigger Real-time Notifications in your Laravel App

Open up app/Livewire/DeliveryHistory.php file. Here, we will add Novu code to trigger notification when a new delivery status is entered.

Add the code to the submitStatus() function like so:



public function submitStatus()
{
        PackageSent::dispatch(auth()->user()->name, $this->status, Carbon::now());

        /**
         *  Trigger Novu to fire the in-app notifications
         */
        novu()->triggerEvent([
            'name' => 'laravel-in-app-notifications',
            'payload' => [
                'deliveryStatus' => $this->status,
                'deliveryHandler' => auth()->user()->name
            ],
            'to' => [
                'subscriberId' => auth()->user()->id,
            ]
        ])->toArray();

        $this->reset('status');
}


Enter fullscreen mode Exit fullscreen mode

The value of the name is the workflow trigger ID. Open up the Novu workflow we created on Novu dashboard, you will be able to identify the trigger ID like so:

Workflow Trigger IDNext, we included both deliveryStatus and deliveryHandler as payload items in the trigger code call. This allows our workflow to receive and display them as part of the notification content in the Notification Center.

Finally, we add the ID of the subscriber that we want to see the real-time notification when it has been triggered. This should always be the ID of the logged-in-user so that they can see the notification once it comes into the app.

One more thing…

Open up routes/channel.php and modify it to the code below:



<?php

use Illuminate\Support\Facades\Broadcast;

Broadcast::channel('delivery', function ($user) {
    return true;
});


Enter fullscreen mode Exit fullscreen mode

We need to do this (return true always regardless of whoever is logged in) else we won’t be allowed to enter a status because the user that is logged in is no longer of ID 1.

Reload your app and attempt to add a status. You'll notice the notification appear in real time in the Notification Center. It's quick, instantaneous, and visually pleasing!

You can try different things in the Notification center pop up:

  • You can mark an individual message as read.
  • You can delete one individual message
  • You can mark all as read at once.

Novu makes it a breeze to add as many notification channels as possible without having to incorporate the logic of each notification provider. Write once, run as many channels as possible!

Check out the documentation on all the many things you can do with Novu’s Notification Center

Conclusion

We've covered how to use Laravel Reverb, from setup and configuration to building a real-time app. You've also learned how to leverage Novu in setting up effective, scalable real-time in-app notifications.

Laravel and Novu are powerful tools. When combined, they provide everything you need to build fast, robust, scalable, and real-time apps. I'm excited to see your next app.

If you have any questions, feel free to explore our documentation and quickstarts. You can also find me on Discord and Twitter. Don't hesitate to reach out.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .