## Getting Started
### **First Steps**
1. **Installation**
Add the package via Composer:
```bash
composer require andrefelipe18/filament-webpush
Publish the config file:
php artisan vendor:publish --provider="Andrefelipe18\FilamentWebpush\FilamentWebpushServiceProvider"
Run migrations (if using the database subscription storage):
php artisan migrate
Basic Setup
Register the package in app/Providers/Filament/AdminPanelProvider.php:
use Andrefelipe18\FilamentWebpush\FilamentWebpushPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
FilamentWebpushPlugin::make(),
]);
}
First Use Case: Sending a Notification
Use the WebPush facade to send a notification to a user:
use Andrefelipe18\FilamentWebpush\Facades\WebPush;
WebPush::to('user@example.com')
->title('New Task Assigned')
->body('You have a new task in Filament.')
->icon('/path/to/icon.png')
->send();
Subscribing Users
Use the WebPushSubscription model to store subscriptions (if using database storage):
$subscription = new WebPushSubscription([
'endpoint' => $endpoint,
'keys' => [
'auth' => $authKey,
'p256dh' => $publicKey,
],
'user_id' => auth()->id(),
]);
$subscription->save();
Sending Notifications
WebPush::to('user@example.com')
->title('Alert')
->body('Something happened!')
->send();
WebPush::to('user@example.com')
->title('New Update')
->body('Check the dashboard.')
->data(['task_id' => 123, 'priority' => 'high'])
->send();
$users = User::where('role', 'admin')->get();
foreach ($users as $user) {
WebPush::to($user->email)
->title('Admin Alert')
->body('New admin action required.')
->send();
}
Handling Push Events
Use the WebPushEvent facade to listen for push events (e.g., subscription changes):
WebPushEvent::listen(function ($event) {
Log::info('Push event triggered:', $event->data);
});
Integration with Filament Actions Trigger notifications from Filament actions:
use Andrefelipe18\FilamentWebpush\Facades\WebPush;
public static function getActions(): array
{
return [
Action::make('Notify User')
->action(function (User $record) {
WebPush::to($record->email)
->title('Action Triggered')
->body('A new action was performed on your record.')
->send();
}),
];
}
Customizing Notification Appearance
Override default notification options via config (config/filament-webpush.php):
'options' => [
'vapid' => [
'public_key' => env('VAPID_PUBLIC_KEY'),
'private_key' => env('VAPID_PRIVATE_KEY'),
'subject' => 'mailto:your-email@example.com',
],
'ttl' => 3600,
'badge' => '/path/to/badge.png',
'actions' => [
[
'action' => 'view',
'title' => 'View',
'icon' => '/path/to/icon.png',
],
],
],
VAPID Keys Missing
VAPID_PUBLIC_KEY and VAPID_PRIVATE_KEY are set in .env:
VAPID_PUBLIC_KEY=your_public_key
VAPID_PRIVATE_KEY=your_private_key
openssl ecparam -name prime256v1 -genkey -noout -out vapid_private.pem
openssl ec -in vapid_private.pem -pubout -out vapid_public.pem
Then convert to base64:
cat vapid_private.pem | base64
cat vapid_public.pem | base64
Subscription Storage
webpush_subscriptions table exists and is migrated.SubscriptionStorage contract:
use Andrefelipe18\FilamentWebpush\Contracts\SubscriptionStorage;
class RedisSubscriptionStorage implements SubscriptionStorage {
// Implement required methods
}
Then bind it in AppServiceProvider:
$this->app->bind(SubscriptionStorage::class, RedisSubscriptionStorage::class);
CORS Issues
self.skipWaiting();
clients.claim();
Rate Limiting
try {
WebPush::to($email)->send();
} catch (\Exception $e) {
if ($e instanceof \GuzzleHttp\Exception\TooManyRequestsException) {
sleep(5); // Retry after delay
WebPush::to($email)->send();
}
}
Browser Compatibility
Enable Logging:
Add to config/filament-webpush.php:
'debug' => env('APP_ENV') === 'local',
Check logs in storage/logs/laravel.log.
Inspect Payloads: Use a tool like Web Push Inspector to validate payloads before sending.
Test with Postman: Manually send a push notification using the VAPID keys to verify the endpoint works:
POST /webpush HTTP/1.1
Host: your-server.com
Content-Type: application/json
Authorization: vapid t=..., k=...
{
"endpoint": "https://fcm.googleapis.com/fcm/send/...",
"keys": {
"p256dh": "...",
"auth": "..."
},
"data": {
"title": "Test",
"body": "This is a test notification."
}
}
Custom Notification Classes
Extend the WebPushNotification class to add custom logic:
use Andrefelipe18\FilamentWebpush\Notifications\WebPushNotification;
class CustomWebPushNotification extends WebPushNotification {
public function __construct($email, array $data = [])
{
$this->data['custom_key'] = 'custom_value';
parent::__construct($email, $data);
}
}
Use it via:
WebPush::to('user@example.com')->notification(new CustomWebPushNotification());
Event Listeners
Listen for subscription events (e.g., SubscriptionCreated, SubscriptionDeleted):
WebPushEvent::listen(function ($event) {
if ($event instanceof SubscriptionCreated) {
// Send welcome notification
WebPush::to($event->subscription->user->email)
->title('Welcome!')
->body('Thanks for subscribing!')
->send();
}
});
Custom Storage
Implement SubscriptionStorage for non-database storage (e.g., DynamoDB, Elasticsearch):
class DynamoDbSubscriptionStorage implements SubscriptionStorage {
public function findByUserId($userId) { /* ... */ }
public function save(Subscription $subscription) { /* ... */ }
public function delete($subscriptionId) { /* ... */ }
}
Override Default Templates Customize the notification UI by overriding the default service worker template:
// resources/js/service-worker.js
self.addEventListener('push', function(event) {
const data = event.data.json();
How can I help you explore Laravel packages today?