PHPackages                             pachristo/pwa\_ip\_push\_notify - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. pachristo/pwa\_ip\_push\_notify

ActiveLibrary

pachristo/pwa\_ip\_push\_notify
===============================

Production-ready PWA + IP-based Push Notifications for Laravel

v1.0.5(6mo ago)09MITPHPPHP ^8.1

Since Nov 2Pushed 6mo agoCompare

[ Source](https://github.com/pachristo/PWA-IP-PUSH-NOTIFY)[ Packagist](https://packagist.org/packages/pachristo/pwa_ip_push_notify)[ RSS](/packages/pachristo-pwa-ip-push-notify/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (2)Versions (7)Used By (0)

PWA IP Push Notify - Advanced PWA &amp; Push Notifications
==========================================================

[](#pwa-ip-push-notify---advanced-pwa--push-notifications)

Production-ready PWA and Push Notification system for Laravel with IP-based user tracking.

Features
--------

[](#features)

✅ **PWA Support**

- Service Worker with offline caching
- Install prompt for mobile/desktop
- Web App Manifest

✅ **Advanced Push Notifications**

- Database-backed subscriptions
- IP-based user tracking (no login required)
- Rich notifications (images, actions, badges)
- Scheduled notifications
- Click tracking
- Statistics &amp; analytics

✅ **Production Ready**

- Database migrations
- Queue support ready
- CLI commands
- Comprehensive API
- Error handling &amp; logging

Installation
------------

[](#installation)

### 1. Install Package

[](#1-install-package)

Add to your Laravel project's `composer.json`:

```
{
    "repositories": [
        {
            "type": "path",
            "url": "./pwa-ip-push-notify"
        }
    ],
    "require": {
        "pachristo/pwa_ip_push_notify": "*"
    }
}
```

Then run:

```
composer require pachristo/pwa_ip_push_notify
```

### 2. Publish Assets &amp; Run Migrations

[](#2-publish-assets--run-migrations)

```
php artisan pwa-push:install
php artisan migrate
```

This will publish:

- `/public/pwa-push/` - PWA assets
- `/config/pwa-push.php` - Configuration
- `/database/migrations/` - Database tables

### 3. Add Assets to Layout

[](#3-add-assets-to-layout)

Add the following to your layout file (e.g., `resources/views/layouts/app.blade.php`):

```

    Your App

    {{-- @include('pwa-push::components.modal') --}}

    @stack('scripts')

```

**Important Notes:**

- ⚠️ **Required**: `@stack('scripts')` must be present in your layout (before ``)
- The modal uses `@push('scripts')` to inject JavaScript
- Without `@stack('scripts')`, the modal buttons won't work

**Alternative: Manual Setup**

If you want to load assets manually:

```

    @stack('scripts')

        if ('serviceWorker' in navigator) {
            navigator.serviceWorker.register('/pwa-push/sw.js')
                .then(reg => console.log('Service Worker registered', reg))
                .catch(err => console.log('Service Worker registration failed', err));
        }

```

**For Alpine.js Users:**

The modal component uses Alpine.js. If you don't have it installed:

```

```

Or install via npm:

```
npm install alpinejs
```

Configuration
-------------

[](#configuration)

Edit `/config/pwa-push.php` or use environment variables:

```
PWA_PUSH_NAME="YourApp"
PWA_PUSH_THEME="#216895"
PWA_PUSH_BG="#f0f2f5"
PWA_PUSH_TITLE="New Update"
PWA_PUSH_BODY="You have new notifications"
PWA_PUSH_VAPID_SUBJECT="mailto:admin@yourapp.com"
PWA_PUSH_CLEANUP_DAYS=30
PWA_PUSH_MAX_SUBS_PER_IP=5
```

Usage
-----

[](#usage)

### Send Push Notification via Code

[](#send-push-notification-via-code)

```
use Pachristo\PwaIpPushNotify\Services\PushService;

$pushService = app(PushService::class);

// Send to specific IP
$result = $pushService->sendToIp('192.168.1.1', [
    'title' => 'Match Starting!',
    'body' => 'Manchester United vs Liverpool - 15:00',
    'icon' => '/images/football.png',
    'image' => '/images/match-preview.jpg',
    'url' => '/matches/123',
    'actions' => [
        ['action' => 'view', 'title' => 'View Match'],
        ['action' => 'close', 'title' => 'Close'],
    ],
]);

// Send to ALL active subscriptions
$result = $pushService->sendToAll([
    'title' => 'Breaking News!',
    'body' => 'New predictions available',
    'url' => '/predictions',
]);
```

### Send via CLI

[](#send-via-cli)

```
# Send to specific IP
php artisan pwa-push:send --title="Match Alert" --body="Starting now" --ip=192.168.1.1

# Send to all users
php artisan pwa-push:send --title="New Tips" --body="Check them out" --all

# With image and URL
php artisan pwa-push:send \
    --title="VIP Tips Ready" \
    --body="3 matches added" \
    --url="/vip-tips" \
    --image="/images/vip.jpg" \
    --all
```

### Send via API

[](#send-via-api)

```
// Send custom notification
fetch('/pwa-push/send-custom', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
    },
    body: JSON.stringify({
        title: 'New Prediction',
        body: 'Over 2.5 Goals - 85% confidence',
        url: '/predictions/today',
        target: 'all' // or 'ip'
    })
});
```

API Endpoints
-------------

[](#api-endpoints)

### Public Endpoints

[](#public-endpoints)

- `GET /pwa-push/vapid` - Get VAPID public key
- `POST /pwa-push/subscribe` - Subscribe to push notifications
- `POST /pwa-push/unsubscribe` - Unsubscribe
- `GET /pwa-push/my-subscriptions` - Get current IP subscriptions
- `GET /pwa-push/send` - Test notification (current IP)

### Admin Endpoints

[](#admin-endpoints)

- `POST /pwa-push/send-custom` - Send custom notification
- `GET /pwa-push/statistics` - Get system statistics

Database Tables
---------------

[](#database-tables)

### `push_subscriptions`

[](#push_subscriptions)

Stores all push subscriptions with IP tracking:

- `ip_address` - User's IP address (indexed)
- `endpoint` - Push subscription endpoint
- `public_key`, `auth_token` - Encryption keys
- `is_active` - Active status
- `notification_count` - Total sent
- `last_notification_at` - Last activity

### `push_notifications`

[](#push_notifications)

Stores notification records:

- `title`, `body` - Content
- `icon`, `image`, `badge` - Assets
- `url` - Click target
- `actions` - Action buttons (JSON)
- `status` - pending, sending, sent, failed
- `scheduled_at` - For scheduled sends

### `push_notification_logs`

[](#push_notification_logs)

Tracks delivery and clicks:

- `push_notification_id` - Related notification
- `push_subscription_id` - Related subscription
- `status` - sent, failed, clicked
- `sent_at`, `clicked_at` - Timestamps

Advanced Features
-----------------

[](#advanced-features)

### Get Statistics

[](#get-statistics)

```
$stats = app(PushService::class)->getStatistics();
/*
[
    'total_subscriptions' => 1500,
    'active_subscriptions' => 1200,
    'unique_ips' => 800,
    'total_notifications_sent' => 5000,
    'total_clicks' => 2500,
]
*/
```

### Cleanup Inactive Subscriptions

[](#cleanup-inactive-subscriptions)

```
# Auto cleanup (30 days inactive)
php artisan pwa-push:cleanup

# Custom days
php artisan pwa-push:cleanup --days=60
```

### Query Subscriptions

[](#query-subscriptions)

```
use Pachristo\PwaIpPushNotify\Models\PushSubscription;

// Get all subscriptions for an IP
$subs = PushSubscription::getByIp('192.168.1.1');

// Get all active subscriptions
$active = PushSubscription::getActive();

// Deactivate a subscription
$sub->deactivate();
```

Example: Football Tips App
--------------------------

[](#example-football-tips-app)

```
// When new predictions are added
public function notifyNewPredictions($match)
{
    $pushService = app(PushService::class);

    $pushService->sendToAll([
        'title' => '⚽ New Prediction Available',
        'body' => "{$match->home_team} vs {$match->away_team} - {$match->prediction}",
        'icon' => '/images/ball-icon.png',
        'image' => $match->preview_image,
        'url' => route('predictions.show', $match->id),
        'badge' => '/images/badge.png',
        'actions' => [
            ['action' => 'view', 'title' => '👀 View Details'],
            ['action' => 'share', 'title' => '📤 Share'],
        ],
        'data' => [
            'match_id' => $match->id,
            'odds' => $match->odds,
        ],
    ]);
}

// When match starts (5 minutes before)
public function notifyMatchStarting($match)
{
    $pushService = app(PushService::class);

    // Only notify users who viewed this match
    $interestedIPs = $match->views()->pluck('ip_address');

    foreach ($interestedIPs as $ip) {
        $pushService->sendToIp($ip, [
            'title' => '🚨 Match Starting Soon!',
            'body' => "{$match->home_team} vs {$match->away_team} in 5 minutes",
            'url' => route('matches.live', $match->id),
            'require_interaction' => true,
            'tag' => "match-{$match->id}", // Replaces previous notifications
        ]);
    }
}
```

Testing Installation
--------------------

[](#testing-installation)

### 1. Verify Package is Loaded

[](#1-verify-package-is-loaded)

```
php artisan about
# Look for: Pachristo\PwaIpPushNotify\PwaIpPushNotifyServiceProvider
```

### 2. Check Commands

[](#2-check-commands)

```
php artisan list pwa-push
# Should show: pwa-push:install, pwa-push:send, pwa-push:cleanup
```

### 3. Verify Assets

[](#3-verify-assets)

```
# Check public files
ls -la public/pwa-push/
# Should show: manifest.json, sw.js, style.css

# Check config
ls -la config/pwa-push.php

# Check migrations ran
php artisan migrate:status | grep push
```

### 4. Test Component Registration

[](#4-test-component-registration)

```
php artisan tinker
>>> view()->exists('pwa-push::components.modal')
# Should return: true
>>> exit
```

### 5. Test in Browser

[](#5-test-in-browser)

1. Visit your app in browser (must be HTTPS or localhost)
2. Click the "Enable Push Notifications" button
3. Allow notifications when prompted
4. Send test notification:

```
php artisan pwa-push:send --title="Test" --body="Hello World!" --all
```

Troubleshooting
---------------

[](#troubleshooting)

### Notifications not working?

[](#notifications-not-working)

1. **Check HTTPS**: Push notifications require secure context (HTTPS or localhost)
2. **Verify migrations**: `php artisan migrate:status | grep push`
3. **Check subscriptions**: `php artisan tinker` → `PushSubscription::count()`
4. **Test VAPID keys**: `ls storage/app/push/vapid.json`
5. **Check browser console**: Open DevTools → Console for errors
6. **Verify service worker**: DevTools → Application → Service Workers

### Component not found error?

[](#component-not-found-error)

```
# Clear all caches
php artisan config:clear
php artisan view:clear
php artisan cache:clear
composer dump-autoload

# Verify component is registered
php artisan tinker
>>> app('blade.compiler')->getClassComponentAliases()['pwa-push-modal'] ?? 'Not found'
```

### Modal buttons not working?

[](#modal-buttons-not-working)

**Check if `@stack('scripts')` is in your layout:**

```

    @stack('scripts')

```

The modal uses `@push('scripts')` to inject JavaScript. Without `@stack('scripts')`, the Install and Allow Push buttons won't work.

### Service Worker not registering?

[](#service-worker-not-registering)

1. Check browser console for errors
2. Verify file exists: `public/pwa-push/sw.js`
3. Must be served over HTTPS (or localhost)
4. Check scope: Service worker scope is `/`

### Assets not loading?

[](#assets-not-loading)

```
# Re-publish assets
php artisan vendor:publish --tag=pwa-push --force

# Verify public directory
ls -la public/pwa-push/
```

### Clear cache if needed

[](#clear-cache-if-needed)

```
php artisan config:clear
php artisan view:clear
php artisan cache:clear
php artisan route:clear
composer dump-autoload
```

License
-------

[](#license)

MIT License - Free to use in your projects!

PWA-IP-PUSH-NOTIFY
==================

[](#pwa-ip-push-notify)

###  Health Score

33

—

LowBetter than 75% of packages

Maintenance67

Regular maintenance activity

Popularity4

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

6

Last Release

192d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/7f87e3993bd820b5e15d859adb597ec1c236e927f9d90bc91ff89ee608373f64?d=identicon)[pachristo](/maintainers/pachristo)

---

Top Contributors

[![pachristo](https://avatars.githubusercontent.com/u/55316294?v=4)](https://github.com/pachristo "pachristo (8 commits)")

### Embed Badge

![Health badge](/badges/pachristo-pwa-ip-push-notify/health.svg)

```
[![Health](https://phpackages.com/badges/pachristo-pwa-ip-push-notify/health.svg)](https://phpackages.com/packages/pachristo-pwa-ip-push-notify)
```

###  Alternatives

[anourvalar/eloquent-serialize

Laravel Query Builder (Eloquent) serialization

11320.2M21](/packages/anourvalar-eloquent-serialize)[namu/wirechat

A Laravel Livewire messaging app for teams with private chats and group conversations.

54324.5k](/packages/namu-wirechat)[statamic-rad-pack/runway

Eloquently manage your database models in Statamic.

135192.6k5](/packages/statamic-rad-pack-runway)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
