2. Channel — Creating a Multi-Channel Notification System

Samuel
4 min readJun 29, 2024

--

Introduction

In today’s digital world, users expect real-time updates and seamless communication from the applications they use. Whether it’s an order confirmation, a low stock alert, or a new message notification, delivering information promptly and through the user’s preferred channel is crucial for creating a positive user experience.

Laravel’s notification system, combined with its powerful broadcasting features, provides an elegant solution for creating a multi-channel notification system. This system allows you to notify users through various channels, such as email, SMS, and real-time web updates using WebSockets, all from a unified API.

In this tutorial, we’ll explore how to build a multi-channel notification system for an e-commerce application using Laravel 11. We’ll focus on notifying users about new orders placed on the platform. By the end of this tutorial, you’ll understand how to:

- Create and dispatch notifications.
- Configure different notification channels.
- Send notifications via email and SMS.
- Broadcast notifications in real time using Laravel Echo and Pusher.

Project Setup

1. Create a New Laravel Project

Let’s start by creating a fresh Laravel project:

composer create-project laravel/laravel ecommerce-notifications

2. Install Required Packages

For this tutorial, we’ll use Laravel’s built-in mail driver and the Vonage (formerly Nexmo) driver for sending SMS notifications. We’ll also utilize Pusher for broadcasting notifications. Let’s install the necessary packages using Composer:

composer require laravel/vonage-notification-channel guzzlehttp/guzzle pusher/pusher-php-server

3. Configure Notification Channels

Next, configure your Vonage and Pusher credentials in your application’s .envfile. You can obtain your API keys and secrets from the respective service providers. Here’s a sample configuration:

VONAGE_KEY=your-vonage-api-key
VONAGE_SECRET=your-vonage-api-secret
VONAGE_SMS_FROM=15555555555 # Your Vonage phone number

PUSHER_APP_ID=your-pusher-app-id
PUSHER_APP_KEY=your-pusher-key
PUSHER_APP_SECRET=your-pusher-secret
PUSHER_APP_CLUSTER=your-pusher-cluster

4. Database Setup

We’ll be using database notifications to store a record of sent notifications. Use the following Artisan command to generate a migration for the notificationstable:

php artisan make:notifications-table

Run the migrations to create the table:

php artisan migrate

Creating a Notification

1. Create a Notification Class

Let’s create a notification class for new orders using the Artisan command:

php artisan make:notification NewOrderNotification

This command will generate a `NewOrderNotification` class within the `app/Notifications` directory.

2. Define Notification Channels

In the `via` method of the notification class, specify the channels you want to use for delivering the notification. In this example, we’ll use the `mail`, `vonage` (SMS), and `broadcast` channels:

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\VonageMessage;

class NewOrderNotification extends Notification implements ShouldQueue
{
use Queueable;

/**
* The order instance.
*/
public $order;

/**
* Create a new notification instance.
*/
public function __construct($order)
{
$this->order = $order;
}

/**
* Get the notification's delivery channels.
*
* @return array<int, string>
*/
public function via(object $notifiable): array
{
return ['mail', 'vonage', 'broadcast'];
}
}

3. Define Channel-Specific Messages

Now, define the methods for formatting the notification for each channel:

// ... (Existing code from step 2)

/**
* Get the mail representation of the notification.
*/
public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)
->subject('New Order Placed')
->greeting('Hello ' . $notifiable->name)
->line('A new order has been placed on your e-commerce platform.')
->line('Order ID: ' . $this->order->id)
->action('View Order Details', url('/orders/' . $this->order->id))
->line('Thank you for using our application!');
}

/**
* Get the Vonage / SMS representation of the notification.
*/
public function toVonage(object $notifiable): VonageMessage
{
return (new VonageMessage)
->content('New order placed on your platform. Order ID: ' . $this->order->id);
}

/**
* Get the array representation of the notification.
*
* @return array<string, mixed>
*/
public function toArray(object $notifiable): array
{
return [
'order_id' => $this->order->id,
];
}

In the above code:

- `toMail` formats the notification for the mail channel using the `MailMessage` class.
- `toVonage` formats the notification for the SMS channel using the `VonageMessage` class.
- `toArray` defines the data payload for the `database` and `broadcast` channels.

Dispatching the Notification

To dispatch the notification, use the `notify` method on a user instance. In a real-world scenario, you would typically dispatch this notification after a successful order placement. For this example, let’s create a simple route to dispatch the notification:

use App\Models\User;
use App\Notifications\NewOrderNotification;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

Route::post('/test-notification', function (Request $request) {
$user = User::first();
$order = (object)['id' => 123]; // Sample order data for demonstration

$user->notify(new NewOrderNotification($order));

return 'Notification sent!';
});

This route retrieves the first user, creates a sample order object, and dispatches the `NewOrderNotification` to the user.

Receiving Broadcast Notifications

1. Install Laravel Echo and Pusher

Install Laravel Echo, a JavaScript library for subscribing to channels and listening for events, and the Pusher JS SDK:

npm install - save-dev laravel-echo pusher-js

2. Configure Echo

In your `resources/js/bootstrap.js` file, configure a new Echo instance to use Pusher:

import Echo from 'laravel-echo';

window.Pusher = require('pusher-js');

window.Echo = new Echo({
broadcaster: 'pusher',
key: import.meta.env.VITE_PUSHER_APP_KEY,
cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER,
forceTLS: true
});

Ensure you have added the corresponding `VITE_PUSHER_*` variables in your `.env` file, as mentioned in the Project Setup.

3. Listen for Notifications

In your frontend JavaScript code, subscribe to the user’s private channel and listen for the notification:

Echo.private(`App.Models.User.${userId}`) // Replace userId with the actual user ID
.notification((notification) => {
console.log(notification.type); // Outputs "App\Notifications\NewOrderNotification"
console.log(notification.order_id); // Outputs the order ID
});

Conclusion

Congratulations! You have successfully implemented a multi-channel notification system for your e-commerce application using Laravel 11. Users are now notified via email, SMS, and real-time web updates whenever a new order is placed. This flexible notification system provides a powerful foundation for keeping your users informed about various events that occur in your application.

Remember to explore other notification channels, customize notification formatting, and implement additional features like marking notifications as read to further enhance your user experience.

Happy Coding!

--

--

Samuel

Versatile Full-Stack Developer | PHP, Python3, WordPress | Author & GuardGeo Owner | Passionate about secure, efficient coding and continuous growth.