Self-Hosted WebPush Notifications with Laravel PHP

Have you ever wished you could send updates directly to your website visitors, even when they’re not browsing your site? Well, with Web Push Notifications, you can! This guide will show you how to build a self-hosted system using Php / Laravel with the awesome Web Push PHP library, giving you complete control over your notifications.

In this guide, we’ll walk you through the process of setting up self-hosted web push notifications using Laravel PHP, a popular PHP framework, and the laravel-notification-channels/webpush library.

Step 1: Installation

First, you need to install the laravel-notification-channels/webpush package via Composer. Open your terminal and navigate to your Laravel project directory, then run the following command:

composer require laravel-notification-channels/webpush

Step 2: Publish configuration file

publish the configuration file using the following Artisan command:

php artisan vendor:publish --provider="NotificationChannels\WebPush\WebPushServiceProvider"

Step 3: Generating VAPID Keys

This command will set VAPID_PUBLIC_KEY and VAPID_PRIVATE_KEYin your .env file.

php artisan webpush:vapid

These keys must be safely stored and should not change.

Step 4: Create Service Worker File

create a file “service-worker.js” in the “public” folder with the following code

self.addEventListener("push", (event) => {
    const notification = event.data.json();

    event.waitUntil(
        self.registration.showNotification(notification.title, {
            body: notification.body,
            icon: notification.icon,
            actions: notification.actions
        })
    )
});


self.addEventListener("notificationclick", (event) => {
    event.waitUntil(
        clients.openWindow(event.action || '/')
    )
})

This service worker file listens for push events and displays notifications when received. It also handles notification click events by closing the notification and opening a specified URL when clicked.

Step 4: Subscribe Users to Notifications

Now, you need to implement client-side JavaScript code to subscribe users to your notification service. This code typically runs on your website or web application.

const subscribe = async () => {
try {
const serviceWorkerRegistration = await navigator.serviceWorker.register('/service-worker.js');
const subscription = await serviceWorkerRegistration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: 'VAPID_PUBLIC_KEY' // get from step 3
});

//store device subscription token to User's Table Column name "device_token"
axios.post('/store-device-token', {
device_token: subscription.toJSON()
})

} catch (error) {
console.error('Error subscribing to push notifications:', error);
alert('Error subscribing to push notifications. Please try again.');
}
};

Step 5: Add Route & Method to Store Token

Route::post('/store-device-token', [UserController::class, 'storeDeviceToken']);

** Don’t forget to add new column “device_token” to the “Users” Table

public function storeDeviceToken(Request $request)
    {
        // Validate the incoming request data
        $validatedData = $request->validate([
            'token' => 'required|string' // Assuming the token is sent as 'token' in the request
        ]);

        // Get the authenticated user
        $user = auth()->user();

        // Update the user's device_token column with the received token
        $user->update(['device_token' => $validatedData['token']]);

        return response()->json(['message' => 'Device token stored successfully'], 200);
    }

Step 6: Now Send Notification

Create a new notification class using Artisan command:

php artisan make:notification NewPostNotification

In the NewPostNotification class, define the content of your notification. For example:

// app/Notifications/NewPostNotification.php

namespace App\Notifications;

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

class NewPostNotification extends Notification
{
use Queueable;

public function via($notifiable)
{
return ['webpush'];
}

public function toWebPush($notifiable, $notification)
{
return (new WebPushMessage())
->title('New Post Published')
->body('Check out our latest post!')
->icon('/path/to/icon.png')
->action('View Post', 'view_post

In your controller or wherever you want to send the notification, dispatch the notification to users:

use App\Models\User;
use App\Notifications\NewPostNotification;

$user = User::find($userId); // Replace $userId with the user's ID
$user->notify(new NewPostNotification());

you read more about this package: https://github.com/laravel-notification-channels/webpush

Conclusion

By following these steps, you can send notifications from self hosted webpush with your Laravel backend to users who have subscribed to your web push notification service. This allows you to keep your users informed about important updates, such as new posts, in real-time.

Leave a Reply

Your email address will not be published. Required fields are marked *