Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Pusher Laravel Package

bentools/pusher

Send Web Push notifications to multiple recipients across providers (Chrome/GCM, Mozilla) using async/parallel Guzzle requests. Supports multiple API keys, ping/notification/server messages, and per-recipient delivery reporting for unsubscribes. Unmaintained.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require bentools/pusher
    

    Ensure guzzlehttp/guzzle (v6.x) is installed as a dependency.

  2. Basic Configuration Add service provider to config/app.php:

    'providers' => [
        // ...
        Bentools\Pusher\PusherServiceProvider::class,
    ],
    

    Publish config (optional):

    php artisan vendor:publish --provider="Bentools\Pusher\PusherServiceProvider"
    

    Configure config/pusher.php with API keys for GCM/Mozilla.

  3. First Push

    use Bentools\Pusher\Pusher;
    use Bentools\Pusher\Message\TextMessage;
    
    $pusher = app(Pusher::class);
    $push = $pusher->createPush()
        ->addMessage(new TextMessage('Hello, world!'))
        ->addRecipient('user@example.com', 'GCM', ['endpoint' => '...', 'keys' => [...]]);
    
    $pusher->push($push);
    

Key Entry Points

  • Pusher facade: Main service for creating and sending pushes.
  • Push object: Central container for messages, recipients, and handlers.
  • Message interfaces: Define payload structure (e.g., TextMessage, PingMessage).
  • Handler classes: Abstract delivery logic (e.g., GcmHandler, MozillaHandler).

Implementation Patterns

Core Workflow

  1. Create a Push

    $push = $pusher->createPush()
        ->addMessage($message)
        ->addRecipient($endpoint, $handlerType, $subscriptionData);
    
    • Use addMessage() for multiple payloads (e.g., text + data).
    • Recipients can share the same message or have message-specific variants.
  2. Asynchronous Processing Leverage Guzzle’s async requests for bulk pushes:

    $pushes = collect([$push1, $push2, $push3]);
    $promises = $pushes->map(fn($push) => $pusher->push($push));
    $results = Promise\all($promises);
    
  3. Handler Chaining Route messages to multiple providers:

    $push->addHandler('GCM', ['apiKey' => 'key1'])
         ->addHandler('Mozilla', ['apiKey' => 'key2']);
    
  4. State Management Check push status post-delivery:

    $push->getStatus(); // 'pending' | 'done'
    $push->getFailedRecipients(); // Array of un delivered endpoints
    

Integration Tips

  • Laravel Queues: Dispatch pushes to a queue for delayed/batched processing:
    PushJob::dispatch($push)->onQueue('push-notifications');
    
  • Event Listeners: Subscribe to PushSent/PushFailed events for analytics:
    event(new PushSent($push));
    
  • Database Persistence: Store Push objects in a table (e.g., pushes) with JSON columns for recipients/handlers.

Common Use Cases

Scenario Implementation
User-specific alerts Attach recipient data to messages.
Bulk notifications Use async handlers for parallel sends.
A/B testing Route identical messages via different handlers.
Unsubscribe tracking Log failedRecipients to a blacklist.

Gotchas and Tips

Pitfalls

  1. Handler Configuration

    • Issue: Missing or invalid API keys cause silent failures.
    • Fix: Validate handlers before pushing:
      $handler = $push->getHandler('GCM');
      if (!$handler->isValid()) throw new \RuntimeException('Invalid GCM key');
      
  2. Recipient Format

    • Issue: Mozilla/GCM expect specific endpoint/key formats (e.g., VAPID keys for Mozilla).
    • Fix: Sanitize inputs:
      $endpoint = str_replace('https://', '', $endpoint);
      
  3. Async Race Conditions

    • Issue: Promises may resolve out of order, causing partial updates.
    • Fix: Use Promise\settle() for tracking individual failures:
      $results = Promise\settle($promises);
      foreach ($results as $result) {
          if ($result['state'] === 'rejected') {
              log($result['reason']);
          }
      }
      
  4. Message Size Limits

    • Issue: GCM/Mozilla enforce payload size limits (~4KB).
    • Fix: Compress messages or split into chunks.

Debugging

  • Enable Guzzle Logging:
    $client = new \GuzzleHttp\Client(['handler' => \GuzzleHttp\HandlerStack::create()]);
    $pusher->setHttpClient($client);
    
  • Inspect Push Objects:
    dd($push->getMessage(), $push->getRecipients(), $push->getHandlers());
    

Extension Points

  1. Custom Handlers Extend Bentools\Pusher\Handler\AbstractHandler:

    class SlackHandler extends AbstractHandler {
        protected function sendPush(Push $push): PromiseInterface {
            return $this->httpClient->postAsync('https://slack.com/api/chat.postMessage', [
                'json' => ['text' => $push->getMessage()->getContent()]
            ]);
        }
    }
    
  2. Message Types Implement Bentools\Pusher\Message\MessageInterface:

    class JsonMessage implements MessageInterface {
        public function getContent(): string {
            return json_encode($this->data);
        }
    }
    
  3. Middleware Attach to Pusher for pre/post-processing:

    $pusher->addMiddleware(function (Push $push) {
        $push->addMetadata(['source' => 'laravel']);
    });
    

Configuration Quirks

  • Default Handler: If no handler is specified, the push fails silently. Always explicitly set handlers.
  • Key Rotation: Use multiple handler instances for high-availability:
    $push->addHandler('GCM', ['apiKey' => 'key1'])
         ->addHandler('GCM', ['apiKey' => 'key2']);
    

Maintenance Notes

  • Forking: Since the package is archived, consider forking to:
    • Update Guzzle 6 → 7 compatibility.
    • Add support for modern WebPush standards (e.g., web-push-php v7).
  • Alternatives: Evaluate spatie/laravel-webpush for Laravel-specific integrations.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
directorytree/privacy-filter-classifier
directorytree/privacy-filter
babenkoivan/elastic-client
innmind/static-analysis
innmind/coding-standard
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit