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

Mandrill Swiftmailer Laravel Package

accord/mandrill-swiftmailer

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require accord/mandrill-swiftmailer
    

    Add to config/mail.php under transports:

    'mandrill' => [
        'driver' => 'mandrill',
        'api_key' => env('MANDRILL_API_KEY'),
        'async' => env('MANDRILL_ASYNC', false),
    ],
    
  2. First Use Case: Configure Laravel’s mail service in config/app.php:

    'mail' => [
        'driver' => 'mandrill',
        // ... other config
    ],
    

    Send an email via Laravel’s Mail facade:

    Mail::send([], [], function ($message) {
        $message->to('user@example.com')
                ->subject('Test Email')
                ->setBody('Hello, world!');
    });
    

Key Files to Review

  • config/mail.php (Transport configuration)
  • app/Providers/AppServiceProvider.php (Mail service binding, if customized)
  • vendor/accord/mandrill-swiftmailer (Core transport logic)

Implementation Patterns

Core Workflow

  1. Transport Initialization: Use Laravel’s built-in mail configuration to auto-instantiate the transport:

    $transport = new \Accord\MandrillSwiftMailer\MandrillTransport($dispatcher);
    $transport->setApiKey(config('mail.mandrill.api_key'));
    $transport->setAsync(config('mail.mandrill.async', false));
    
  2. Integrating with Laravel’s Mail System:

    • Default Usage: Leverage Laravel’s Mail facade for sending emails (as shown above).
    • Custom Mailables: Extend Mailable class and use MandrillTransport for advanced features:
      public function build()
      {
          $message = $this->view('emails.welcome');
          $message->withSwiftMessage(function ($swiftMessage) {
              $swiftMessage->getHeaders()
                  ->addTextHeader('X-MC-Autotext', true);
          });
          return $message;
      }
      
  3. Bulk Sending: Enable async mode in config and batch emails:

    Mail::raw('Bulk content', function ($message) use ($recipients) {
        foreach ($recipients as $email) {
            $message->to($email);
        }
        $message->getHeaders()
            ->addTextHeader('X-MC-Autotext', true);
    })->setAsync(true);
    
  4. Event Handling: Listen to mail.sent events to log or process Mandrill-specific metadata:

    Mail::sent(function ($message) {
        if ($message->getTransport() instanceof \Accord\MandrillSwiftMailer\MandrillTransport) {
            // Access Mandrill-specific data (e.g., message ID)
        }
    });
    

Advanced Patterns

  • Dynamic API Key: Use environment variables or a service container to inject the API key:
    $transport->setApiKey(app('mandrill.api_key'));
    
  • Fallback Transport: Combine with other transports (e.g., log or smtp) for resilience:
    'transports' => [
        'mandrill' => [
            'driver' => 'mandrill',
            'api_key' => env('MANDRILL_API_KEY'),
            'fallback' => 'log', // Fallback to log if Mandrill fails
        ],
    ],
    

Gotchas and Tips

Pitfalls

  1. Deprecation Warning:

    • The package is unmaintained. Prioritize migrating to symfony/mailer with the Mandrill bridge if possible.
    • Monitor for breaking changes in SwiftMailer 6+ (this package targets older versions).
  2. Async Mode Quirks:

    • Async mode (setAsync(true)) uses Mandrill’s background sending but does not queue emails locally. Emails are sent immediately to Mandrill’s queue.
    • No retry logic: Failed async sends will not be retried by this package. Use Mandrill’s webhooks or a job queue (e.g., Laravel Queues) for retries.
  3. Header Conflicts:

    • Custom headers like X-MC-* may conflict with Laravel’s default headers. Validate headers before sending:
      if ($message->getHeaders()->has('X-MC-Autotext')) {
          // Safe to proceed
      }
      
  4. Rate Limits:

    • Mandrill enforces rate limits. Async mode helps, but monitor your sending volume.
    • Tip: Use Laravel’s throttle middleware for API calls if integrating directly with Mandrill’s API.

Debugging

  1. Enable Logging: Configure Monolog to log Mandrill transport interactions:

    'logging' => [
        'default' => 'single',
        'channels' => [
            'single' => [
                'driver' => 'single',
                'level' => 'debug',
                'handler' => env('LOG_HANDLER', 'stream'),
                'path' => storage_path('logs/laravel.log'),
            ],
        ],
    ],
    

    Check logs for MandrillTransport entries.

  2. Validate API Key:

    • Test the API key manually via Mandrill’s API or use a debug transport:
      $transport = new \Accord\MandrillSwiftMailer\MandrillTransport($dispatcher);
      $transport->setApiKey('invalid_key'); // Force error to test error handling
      
  3. SwiftMailer Events:

    • Listen for messageSent events to debug failures:
      $dispatcher->addListener('messageSent', function ($event) {
          if ($event->getTransport() instanceof \Accord\MandrillSwiftMailer\MandrillTransport) {
              error_log('Mandrill sent: ' . $event->getMessage()->getId());
          }
      });
      

Extension Points

  1. Custom Headers: Extend the transport to add default Mandrill headers:

    class CustomMandrillTransport extends \Accord\MandrillSwiftMailer\MandrillTransport
    {
        public function __construct($dispatcher)
        {
            parent::__construct($dispatcher);
            $this->addDefaultHeaders();
        }
    
        protected function addDefaultHeaders()
        {
            $this->getSwiftMessage()->getHeaders()
                ->addTextHeader('X-MC-Autotext', true)
                ->addTextHeader('X-MC-GoogleAnalytics', 'yourdomain.com');
        }
    }
    
  2. Webhook Integration: Use Mandrill’s message events to trigger Laravel jobs:

    // In your Mandrill webhook endpoint
    $event = $request->input('event');
    if ($event === 'send') {
        EmailSentJob::dispatch($request->input('msg'));
    }
    
  3. Testing: Mock the transport in PHPUnit:

    $mockTransport = $this->createMock(\Accord\MandrillSwiftMailer\MandrillTransport::class);
    $mockTransport->method('send')->willReturn(true);
    $this->app->instance(\Swift_Transport::class, $mockTransport);
    

Configuration Quirks

  1. Async Mode:

    • Async mode only works with Mandrill’s API. If Mandrill’s async endpoint is unavailable, emails will fail silently.
    • Workaround: Disable async mode or implement a local queue fallback.
  2. Environment Variables:

    • Ensure MANDRILL_API_KEY is set in .env and never committed to version control.
    • Use Laravel’s env() helper or a dedicated config file for sensitive data.
  3. SwiftMailer Version:

    • This package is tested with SwiftMailer 5.x. Upgrading SwiftMailer may break compatibility. Pin the version in composer.json:
      "swiftmailer/swiftmailer": "5.4.*"
      
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.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware