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

Push Laravel Package

cmnty/push

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require cmnty/push
    

    Ensure ext-crypto or lib-openssl is installed for optimal performance.

  2. First Use Case: Send a push notification to a user’s browser via a subscription endpoint:

    use Cmnty\Push\Client;
    use Cmnty\Push\AggregatePushService;
    use Cmnty\Push\PushServiceRegistry;
    use Cmnty\Push\GooglePushService;
    use Cmnty\Push\Notification;
    use Cmnty\Push\Subscription;
    use Cmnty\Push\Endpoint;
    use Cmnty\Push\PublicKey;
    use Cmnty\Push\AuthenticationSecret;
    
    // Initialize services
    $pushServiceRegistry = new PushServiceRegistry();
    $pushServiceRegistry->addPushService(new GooglePushService('YOUR_GOOGLE_API_KEY'));
    $pushService = new AggregatePushService($pushServiceRegistry);
    
    // Create client
    $client = new Client($pushService);
    
    // Define notification and subscription
    $notification = new Notification('Hello', 'World!');
    $subscription = new Subscription(
        new Endpoint('https://fcm.googleapis.com/fcm/send/...'),
        PublicKey::createFromBase64UrlEncodedString('PUBLIC_KEY'),
        AuthenticationSecret::createFromBase64UrlEncodedString('AUTH_SECRET')
    );
    
    // Send push
    $client->pushNotification($notification, $subscription);
    
  3. Where to Look First:

    • README.md: For basic usage and dependency requirements.
    • Cmnty\Push\Client: Core class for sending notifications.
    • Cmnty\Push\Crypto: For encryption fallback logic (if ext-crypto/lib-openssl fail).

Implementation Patterns

Usage Patterns

  1. Service Registry: Register multiple push services (e.g., Google FCM, Mozilla Push) in a single PushServiceRegistry to handle cross-platform notifications:

    $pushServiceRegistry = new PushServiceRegistry();
    $pushServiceRegistry->addPushService(new GooglePushService('API_KEY'));
    $pushServiceRegistry->addPushService(new MozillaPushService());
    $aggregateService = new AggregatePushService($pushServiceRegistry);
    
  2. Encryption Strategy: Use AggregateCrypt (default) for automatic fallback to ext-cryptolib-opensslspomky-labs/php-aes-gcm. Override if needed:

    $client = new Client($pushService, null, new Cryptograph(new ExtCryptoCrypt()));
    
  3. Notification Customization: Extend Notification to add payload data (e.g., deep links, images):

    $notification = new Notification('Title', 'Body', [
        'data' => ['url' => '/dashboard', 'icon' => 'https://example.com/icon.png']
    ]);
    
  4. Subscription Management: Store subscriptions in a database (e.g., subscriptions table) and fetch them dynamically:

    $subscription = Subscription::fromArray([
        'endpoint' => 'https://...',
        'keys' => [
            'p256dh' => 'PUBLIC_KEY',
            'auth' => 'AUTH_SECRET'
        ]
    ]);
    

Workflows

  1. User Opt-In Flow:

    • Capture subscription details from the browser’s PushManager.subscribe().
    • Store in your database (e.g., users table with subscription_data JSON column).
    • Retrieve and send notifications later.
  2. Batch Processing: Use AggregatePushService to send notifications to multiple subscriptions in a loop:

    foreach ($userSubscriptions as $subscription) {
        $client->pushNotification($notification, $subscription);
    }
    
  3. Error Handling: Catch Cmnty\Push\Exception\PushException for failed sends (e.g., invalid keys, network issues):

    try {
        $client->pushNotification($notification, $subscription);
    } catch (PushException $e) {
        Log::error("Push failed: " . $e->getMessage());
        // Retry or notify admin
    }
    

Integration Tips

  1. Laravel Integration:

    • Bind the Client to the container in AppServiceProvider:
      $this->app->singleton(Client::class, function ($app) {
          $pushService = new AggregatePushService(
              new PushServiceRegistry([
                  new GooglePushService(config('services.google_push.key'))
              ])
          );
          return new Client($pushService);
      });
      
    • Use dependency injection in controllers:
      public function sendNotification(Client $client) {
          $client->pushNotification($notification, $subscription);
      }
      
  2. Queue Push Jobs: Offload push notifications to a queue (e.g., Laravel Queues) to avoid blocking requests:

    dispatch(new SendPushNotification($notification, $subscription));
    

    Define the job:

    class SendPushNotification implements ShouldQueue {
        use Dispatchable, InteractsWithQueue, Queueable;
    
        public function handle(Client $client) {
            $client->pushNotification($this->notification, $this->subscription);
        }
    }
    
  3. Testing:

    • Mock Client in unit tests:
      $mockClient = Mockery::mock(Client::class);
      $mockClient->shouldReceive('pushNotification')->once();
      
    • Use a test push service (e.g., GooglePushService with a dummy API key).

Gotchas and Tips

Pitfalls

  1. Encryption Dependencies:

    • Missing ext-crypto/lib-openssl: Falls back to spomky-labs/php-aes-gcm, which is slower. Install extensions for production:
      pecl install crypto
      
      or use lib-openssl (Linux: sudo apt-get install php-openssl).
  2. Key Validation:

    • Invalid PublicKey or AuthenticationSecret (e.g., malformed Base64URL) throws InvalidArgumentException. Validate keys before sending:
      try {
          PublicKey::createFromBase64UrlEncodedString($key);
      } catch (InvalidArgumentException $e) {
          // Handle error (e.g., log or reject subscription)
      }
      
  3. Rate Limiting:

    • Google FCM and Mozilla Push have rate limits. Implement exponential backoff for retries:
      $retryAfter = $e->getRetryAfter();
      sleep($retryAfter);
      
  4. CORS/HTTPS:

    • Push subscriptions require HTTPS. Ensure your endpoint uses https:// and CORS headers are configured for the subscription endpoint.
  5. Deprecated Package:

    • Last release in 2016. Use at your own risk. Consider alternatives like minishlink/web-push for active maintenance.

Debugging

  1. Enable Guzzle Debugging: Configure Guzzle to log HTTP requests/responses:

    $client = new Client($pushService, new \GuzzleHttp\Client([
        'debug' => fopen('guzzle.log', 'w'),
    ]));
    
  2. Check Subscription Validity: Verify the subscription endpoint is active and keys are correct:

    $subscription->getEndpoint()->isValid(); // Basic URL validation
    
  3. Payload Inspection: Log the encrypted payload before sending to debug issues:

    $payload = $client->getPushService()->createPayload($notification, $subscription);
    Log::debug('Push payload:', [$payload]);
    

Config Quirks

  1. Google FCM API Key:

    • Use a server key (not client key) for FCM. Store it securely (e.g., Laravel .env):
      GOOGLE_PUSH_KEY=your_server_key_here
      
  2. Mozilla Push:

    • Requires a Push Service ID (not used in the library but needed for Mozilla’s API). Document this in your setup.
  3. Custom Cryptography:

    • Implement Cmnty\Push\Crypto\Crypt for custom encryption (e.g., AWS KMS):
      class AWSCrypt implements Crypt {
          public function encrypt($data, $key) { /* ... */ }
          public function decrypt($data, $key) { /* ... */ }
      }
      
      Then inject into Client:
      $client = new Client($pushService, null, new Cryptograph(new AWSCrypt()));
      

Extension Points

  1. Custom Push Services: Extend Cmnty\Push\PushService for unsupported providers (e.g., Firebase Cloud Messaging v1):
    class FirebaseV1PushService implements PushService {
        public function createPayload(Notification $notification, Subscription $subscription) { /* ... */ }
        public function sendPayload($payload, $endpoint) { /*
    
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.
datacore/hub-sdk
alengo/sulu-http-cache-bundle
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
imbo/imbo-coding-standard
visualbuilder/filament-lottie
servicioslineaonce/starter-kit
atomcoder/laravel-reorderable
irajul/filament-shadcn-theme
agtp/agtp-php
agtp/mod-php
centraldesktop/protobuf-php
trappistes/laravel-custom-fields
splash/sonata-admin
splash/metadata