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

Notifier Bundle Laravel Package

coka/notifier-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install via Composer:
    composer require coka/notifier-bundle
    
  2. Enable the Bundle in config/bundles.php:
    return [
        // ...
        CedrickOka\NotifierBundle\OkaNotifierBundle::class => ['all' => true],
    ];
    
  3. Configure Notifiers in config/packages/oka_notifier.yaml:
    oka_notifier:
        notifiers:
            default:
                type: 'webhook' # or 'email', 'slack', etc.
                config:
                    url: 'https://your-webhook-endpoint.com'
    
  4. First Use Case: Trigger a notification via a service:
    use CedrickOka\NotifierBundle\Notifier\NotifierInterface;
    
    class SomeService {
        public function __construct(private NotifierInterface $notifier) {}
    
        public function sendAlert() {
            $this->notifier->notify('default', [
                'message' => 'Test notification',
                'priority' => 'high'
            ]);
        }
    }
    

Implementation Patterns

Core Workflows

  1. Service Discovery:

    • Register notifiers in oka_notifier.yaml under notifiers key.
    • Use dependency injection to inject NotifierInterface and call notify($name, $payload).
  2. Payload Structure:

    • Standardize payloads with message, priority (e.g., low, medium, high), and optional metadata.
    • Example:
      $this->notifier->notify('slack', [
          'message' => 'Deployment failed',
          'priority' => 'critical',
          'metadata' => ['commit' => 'abc123', 'env' => 'production']
      ]);
      
  3. Dynamic Notifier Switching:

    • Use environment variables or config to switch notifiers dynamically:
      # config/packages/oka_notifier.yaml
      oka_notifier:
          notifiers:
              production: { type: 'slack', config: { ... } }
              staging:    { type: 'email', config: { ... } }
      
    • Inject the correct notifier name via config or runtime logic.
  4. Event-Driven Notifications:

    • Listen to Laravel events (e.g., job.failed) and trigger notifications:
      use Illuminate\Queue\Events\JobFailed;
      
      Event::listen(JobFailed::class, function (JobFailed $event) {
          $notifier->notify('slack', [
              'message' => 'Job failed: ' . $event->job->payload['command'],
              'priority' => 'high'
          ]);
      });
      
  5. Custom Notifier Types:

    • Extend AbstractNotifier to create new notifier types (e.g., PushoverNotifier).
    • Register in oka_notifier.yaml:
      oka_notifier:
          notifiers:
              pushover:
                  type: 'pushover'
                  config: { token: '...', user: '...' }
      

Gotchas and Tips

Pitfalls

  1. Missing Configuration:

    • Forgetting to define notifiers in oka_notifier.yaml will throw RuntimeException.
    • Fix: Validate config early (e.g., in a Command or ServiceProvider constructor).
  2. Payload Validation:

    • Not all notifiers support the same payload fields. For example, webhook may ignore priority.
    • Fix: Document required fields per notifier type in your team’s style guide.
  3. Dependency Injection:

    • If injecting NotifierInterface directly, ensure the correct notifier is bound in the container.
    • Fix: Use tagged services or factory patterns for dynamic notifier resolution.
  4. Rate Limiting:

    • High-frequency notifications (e.g., logs) may hit API limits (e.g., Slack’s rate limits).
    • Fix: Implement a Queue or RateLimiter decorator around the notifier.
  5. Testing:

    • Notifiers often require external APIs (e.g., Slack, Email). Mock them in tests:
      $notifier = $this->createMock(NotifierInterface::class);
      $notifier->expects($this->once())
               ->method('notify')
               ->with('slack', ['message' => 'Test']);
      $this->app->instance(NotifierInterface::class, $notifier);
      

Debugging Tips

  1. Log Payloads: Add a LoggerNotifier decorator to log all notifications:

    class LoggerNotifier implements NotifierInterface {
        public function __construct(private NotifierInterface $notifier, private LoggerInterface $logger) {}
    
        public function notify(string $name, array $payload): void {
            $this->logger->info('Notifier: ' . $name, ['payload' => $payload]);
            $this->notifier->notify($name, $payload);
        }
    }
    

    Register it in services.yaml:

    services:
        CedrickOka\NotifierBundle\Notifier\NotifierInterface:
            class: App\Notifier\LoggerNotifier
            arguments:
                $notifier: '@oka_notifier.notifier.default'
                $logger: '@logger'
    
  2. Check HTTP Responses: For webhook notifiers, inspect HTTP responses to debug failures:

    $client = new \GuzzleHttp\Client();
    $response = $client->post($config['url'], [
        'json' => $payload,
        'headers' => ['Authorization' => 'Bearer ' . $config['token']]
    ]);
    if ($response->getStatusCode() !== 200) {
        throw new \RuntimeException('Notification failed: ' . $response->getBody());
    }
    
  3. Environment-Specific Config: Use Symfony’s %env% or Laravel’s .env for sensitive config:

    oka_notifier:
        notifiers:
            slack:
                type: 'slack'
                config:
                    token: '%env(SLACK_TOKEN)%'
                    channel: '%env(SLACK_CHANNEL)%'
    

Extension Points

  1. Custom Notifier Logic: Override AbstractNotifier::send() to add retries or fallback logic:

    class RetryNotifier extends AbstractNotifier {
        public function send(array $payload): void {
            $retries = 3;
            while ($retries--) {
                try {
                    parent::send($payload);
                    return;
                } catch (\Exception $e) {
                    if ($retries === 0) throw $e;
                    sleep(2 ** $retries); // Exponential backoff
                }
            }
        }
    }
    
  2. Priority-Based Routing: Route notifications based on priority to different notifiers:

    class PriorityNotifier implements NotifierInterface {
        public function __construct(
            private NotifierInterface $highPriorityNotifier,
            private NotifierInterface $lowPriorityNotifier
        ) {}
    
        public function notify(string $name, array $payload): void {
            if ($payload['priority'] === 'high') {
                $this->highPriorityNotifier->notify($name, $payload);
            } else {
                $this->lowPriorityNotifier->notify($name, $payload);
            }
        }
    }
    
  3. Template-Based Messages: Use Twig or Blade templates for dynamic messages:

    $this->notifier->notify('email', [
        'subject' => '{{ event }} failed',
        'body' => 'Check logs at {{ url }}',
        'context' => [
            'event' => 'Deployment',
            'url' => 'https://example.com/logs'
        ]
    ]);
    

    Note: Requires custom notifier implementation to render templates.

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.
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle
dmstr/api-platform-utils-bundle
dmstr/api-configuration-bundle
chrisdev/ux-components
baks-dev/finances
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle