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

Swiftmailer Enqueue Bundle Laravel Package

dnna/swiftmailer-enqueue-bundle

Symfony bundle that spools SwiftMailer emails to an Enqueue message queue and consumes them via swiftmailer:spool:send. Adds configurable queue options, receive timeouts, graceful shutdown via signal extension, and optional requeue/retry handling.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require dnna/swiftmailer-enqueue-bundle
    

    Ensure EnqueueBundle is also installed (dependency):

    composer require php-enqueue/enqueue-bundle
    
  2. Enable the Bundle: Add to config/bundles.php (Symfony 4.4+):

    return [
        // ...
        Enqueue\Bundle\EnqueueBundle::class,
        Dnna\SwiftmailerEnqueueBundle\SwiftmailerEnqueueBundle::class,
    ];
    
  3. Configure Swiftmailer: Update config/packages/swiftmailer.yaml to use the enqueue spool:

    swiftmailer:
        spool: { type: 'enqueue' }
    
  4. Configure the Bundle: Add to config/packages/dnna_swiftmailer_enqueue.yaml:

    dnna_swiftmailer_enqueue:
        queue:
            service_id: enqueue.transport.default.context  # Default Enqueue transport
            key: swiftmailer_spool
            requeue_on_exception: true
            max_requeue_attempts: 3
    
  5. Start Consuming Emails: Run the consumer in a separate process (e.g., via Supervisor or Docker):

    php bin/console swiftmailer:spool:consume
    

    Note: This command is blocking—run it in the background.


First Use Case

Decouple Email Sending from HTTP Requests: Replace synchronous Swiftmailer with an async queue to improve response times. Example:

// In a Laravel controller (using Symfony's Swiftmailer via Laravel's Mail facade)
Mail::to('user@example.com')->send(new WelcomeEmail());

// Emails are now queued via Enqueue, not sent immediately.

Implementation Patterns

Core Workflow

  1. Spooling Emails:

    • All emails sent via Swiftmailer are automatically queued to Enqueue (no manual intervention).
    • Configure the transport (e.g., RabbitMQ, Redis, or Amazon SQS) in config/packages/enqueue.yaml:
      enqueue:
          client:
              transport: redis://localhost
      
  2. Consuming Emails:

    • Run the consumer continuously (e.g., in a Docker container or background process):
      php bin/console swiftmailer:spool:consume --time-limit=300
      
    • Customize consumption with flags:
      --limit=100       # Process 100 messages max
      --timeout=60      # Timeout in seconds
      --verbose         # Debug output
      
  3. Graceful Shutdown:

    • The bundle supports SIGTERM/SIGINT handling. Configure in config/packages/dnna_swiftmailer_enqueue.yaml:
      dnna_swiftmailer_enqueue:
          consumption:
              signal_extension: true
      

Integration Tips

  1. Laravel-Specific Setup:

    • If using Laravel’s Mail facade with Symfony’s Swiftmailer, ensure the bundle is loaded after Laravel’s Swiftmailer configuration:
      // config/app.php
      'providers' => [
          // ...
          Swiftmailer\SwiftmailerServiceProvider::class,
      ],
      
    • Override Laravel’s Swiftmailer spool in config/mail.php:
      'spool' => [
          'driver' => 'enqueue',
      ],
      
  2. Queue Monitoring:

    • Use Enqueue’s CLI tools to inspect the queue:
      php bin/console enqueue:consume --queue=swiftmailer_spool
      
    • Monitor queue length with:
      php bin/console enqueue:stats
      
  3. Error Handling:

    • Log failed emails to a dead-letter queue (DLQ) by configuring a custom transport:
      dnna_swiftmailer_enqueue:
          queue:
              service_id: enqueue.transport.dlq.context
      
  4. Testing:

    • Mock the Enqueue transport in PHPUnit:
      $this->app->make('enqueue.transport.default.context')->method('send')->willReturn(true);
      

Gotchas and Tips

Pitfalls

  1. Blocking Command:

    • swiftmailer:spool:send is blocking by design. Avoid running it in development unless necessary. Use --time-limit to prevent hangs:
      php bin/console swiftmailer:spool:send --time-limit=10
      
  2. Transport Configuration:

    • If the transport (e.g., RabbitMQ) is misconfigured, emails will fail silently. Validate with:
      php bin/console enqueue:setup:transport
      
  3. Requeue Logic:

    • requeue_on_exception defaults to false. Set to true to retry failed emails, but beware of infinite loops with max_requeue_attempts (default: 5).
  4. Signal Handling:

    • signal_extension requires a non-blocking environment (e.g., Docker or Supervisor). Test with:
      kill -SIGTERM <process_id>
      

Debugging

  1. Consumer Logs:

    • Enable verbose mode for detailed output:
      php bin/console swiftmailer:spool:consume --verbose
      
    • Check Symfony’s log directory (var/log/dev.log) for errors.
  2. Queue Inspection:

    • List pending emails:
      php bin/console enqueue:consume --queue=swiftmailer_spool --limit=1
      
  3. Common Errors:

    • "Connection refused": Verify the Enqueue transport (e.g., Redis/RabbitMQ) is running.
    • "Message not found": Ensure the key in dnna_swiftmailer_enqueue matches the queue name.
    • Permission issues: Grant write access to the spool directory (e.g., var/spool).

Extension Points

  1. Custom Transports:

    • Extend the bundle by creating a custom transport service. Example:
      # config/services.yaml
      services:
          App\Swiftmailer\CustomTransport:
              arguments:
                  $transport: '@enqueue.transport.custom.context'
      
      Then bind it to the bundle’s service_id.
  2. Event Listeners:

    • Subscribe to Swiftmailer events (e.g., SentEvent) to log or modify emails:
      use Symfony\Component\Swiftmailer\Event\SentEvent;
      
      $eventDispatcher->addListener(SentEvent::NAME, function (SentEvent $event) {
          // Custom logic (e.g.,
      
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.
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
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui