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 Bundle Laravel Package

accord/mandrill-swiftmailer-bundle

Symfony bundle that adds a SwiftMailer transport for sending email via Mandrill’s API. Configure your Mandrill API key (plus optional async mode and subaccount), register the bundle, then set SwiftMailer’s transport to accord_mandrill.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Bundle

    composer require accord/mandrill-swiftmailer-bundle
    

    Add to AppKernel.php:

    new Accord\MandrillSwiftMailerBundle\AccordMandrillSwiftMailerBundle(),
    
  2. Configure API Key Add your Mandrill API key to config/packages/accord_mandrill_swift_mailer.yaml (or config.yml):

    accord_mandrill_swift_mailer:
        api_key: "%env(MANDRILL_API_KEY)%"  # Use env vars for security
        async: false
        subaccount: ~
    
  3. Set SwiftMailer Transport In config/packages/swiftmailer.yaml (or config.yml):

    swiftmailer:
        transport: accord_mandrill
    
  4. First Use Case Send an email via Laravel’s Mail facade (or Symfony’s SwiftMailer):

    Mail::send('emails.welcome', [], function ($message) {
        $message->to('user@example.com')
                ->subject('Welcome!');
    });
    

Implementation Patterns

Core Workflows

  1. Basic Email Sending Use Laravel’s Mail facade or Symfony’s SwiftMailer as usual. The bundle replaces the default transport with Mandrill’s API.

  2. Async vs. Sync

    • Set async: true in config to queue emails via Mandrill’s async API (reduces latency).
    • Sync (async: false) is default; useful for immediate delivery (e.g., password resets).
  3. Subaccounts Use subaccount in config to route emails to a specific Mandrill subaccount (e.g., for multi-tenant apps).

  4. Templates & Variables Leverage Mandrill’s templating system by passing template_name and template_content to the Swift_Message:

    $message->getHeaders()->addTextHeader('X-MC-Template', 'template_name');
    $message->getHeaders()->addTextHeader('X-MC-Personalization', json_encode([
        'user' => ['name' => 'John']
    ]));
    
  5. Attachments & Inline Images Use SwiftMailer’s built-in methods:

    $message->attach(spl_file_get_contents('/path/to/file.pdf'));
    $message->embed(Swift_Image::fromPath('/path/to/image.jpg'));
    
  6. Event Listeners Hook into Mandrill’s webhooks (e.g., for tracking opens/clicks) by configuring Mandrill’s webhook URL to point to your Laravel endpoint.

Integration Tips

  • Laravel Mailables: Extend Mailable and use SwiftMailer methods directly:
    public function build()
    {
        $this->markdown('emails.welcome')
             ->withSwiftMessage(function ($message) {
                 $message->getHeaders()->addTextHeader('X-MC-Template', 'welcome_template');
             });
    }
    
  • Testing: Use Laravel’s Mail::fake() to mock Mandrill calls in tests.
  • Logging: Enable SwiftMailer logging in config/packages/swiftmailer.yaml for debugging:
    swiftmailer:
        logging: true
    

Gotchas and Tips

Pitfalls

  1. API Key Exposure

    • Never hardcode the API key in config.yml. Use environment variables (%env(MANDRILL_API_KEY)%) or Laravel’s .env.
    • Restrict access: Ensure .env is in your .gitignore.
  2. Async Mode Quirks

    • Async emails (async: true) are sent to Mandrill’s queue but may not be delivered immediately. Use sync mode for critical emails (e.g., OTPs).
    • Monitor Mandrill’s dashboard for queued emails if async fails silently.
  3. Rate Limits

    • Mandrill has rate limits. Exceeding limits may cause delays or errors. Use exponential backoff in retries:
      try {
          Mail::send(...);
      } catch (\Exception $e) {
          if (strpos($e->getMessage(), 'rate limit') !== false) {
              sleep(10); // Backoff
              retry();
          }
      }
      
  4. Subaccount Misconfiguration

    • If subaccount is set but invalid, emails may fail silently. Validate the subaccount exists in Mandrill’s dashboard.
  5. SwiftMailer Deprecations

    • The bundle relies on Symfony’s SwiftMailer (v5.x). Ensure your Laravel version (v5.8+) is compatible. Avoid mixing with newer symfony/mailer.

Debugging

  1. Enable Verbose Logging Add to config/packages/swiftmailer.yaml:

    swiftmailer:
        logging: true
        spool: { type: 'memory' } # Logs all emails in memory (for debugging)
    

    Check logs in storage/logs/laravel.log for Mandrill API responses.

  2. Mandrill API Errors

    • Use Mandrill’s API status endpoint to check for issues:
      $response = Http::get('https://mandrillapp.com/api/1.0/messages/status.json', [
          'key' => config('accord_mandrill_swift_mailer.api_key'),
      ]);
      
    • Common errors:
      • 400 Bad Request: Invalid email format or missing headers.
      • 403 Forbidden: Invalid API key or subaccount.
      • 429 Too Many Requests: Hit rate limits.
  3. Testing Locally

    • Use a local SMTP server (e.g., MailHog) for development to avoid hitting Mandrill’s limits:
      swiftmailer:
          transport: smtp
          host: mailhog
          port: 1025
      

Extension Points

  1. Custom Transport Extend the bundle’s transport to add features (e.g., custom headers, retry logic):

    use Accord\MandrillSwiftMailerBundle\Transport\MandrillTransport;
    
    class CustomMandrillTransport extends MandrillTransport
    {
        public function isStarted()
        {
            // Add custom logic (e.g., check Mandrill uptime)
            return parent::isStarted() && $this->checkMandrillStatus();
        }
    }
    

    Override the service in config/services.yaml:

    services:
        Accord\MandrillSwiftMailerBundle\Transport\MandrillTransport: '@App\CustomMandrillTransport'
    
  2. Event Subscribers Listen to Mandrill’s webhooks (e.g., for tracking) by creating a Symfony event subscriber:

    use Symfony\Component\HttpKernel\Event\GetResponseEvent;
    
    class MandrillWebhookSubscriber
    {
        public function onKernelRequest(GetResponseEvent $event)
        {
            if ($event->isMasterRequest() && $event->getRequest()->getPathInfo() === '/mandrill/webhook') {
                $data = json_decode($event->getRequest()->getContent(), true);
                // Process webhook (e.g., log opens/clicks)
            }
        }
    }
    

    Register the subscriber in config/services.yaml:

    services:
        App\EventSubscriber\MandrillWebhookSubscriber:
            tags: ['kernel.event_subscriber']
    
  3. Fallback Transport Implement a fallback to a local SMTP if Mandrill fails:

    swiftmailer:
        transport: '%env(MAIL_TRANSPORT)%' # Defaults to 'accord_mandrill'
        fallback_transport: '%env(MAIL_FALLBACK_TRANSPORT)%' # e.g., 'smtp'
    

    Use a custom transport factory to switch dynamically.

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