cspoo/swiftmailer-mailgun-bundle
Installation:
composer require cspoo/swiftmailer-mailgun-bundle php-http/guzzle5-adapter
For Laravel (not Symfony), manually register the bundle in config/app.php under providers:
'providers' => [
// ...
cspoo\Swiftmailer\MailgunBundle\cspooSwiftmailerMailgunBundle::class,
],
Configuration:
Add Mailgun credentials to .env:
MAILGUN_KEY=key-3xxxxxxxxxxxx
MAILGUN_DOMAIN=yourdomain.mailgun.org
Publish the config file (if using Laravel):
php artisan vendor:publish --provider="cspoo\Swiftmailer\MailgunBundle\cspooSwiftmailerMailgunBundle" --tag="config"
Update config/mailgun.php with your settings.
First Use Case:
Send an email via Laravel's Mail facade:
use Illuminate\Support\Facades\Mail;
Mail::raw('Test email via Mailgun', function($message) {
$message->to('recipient@example.com')
->subject('Test Mailgun');
});
Transport Integration:
The bundle replaces Swiftmailer's default transport with Mailgun's HTTP API. Configure it in config/mail.php:
'default' => env('MAIL_DRIVER', 'mailgun'),
'mailgun' => [
'transport' => 'mailgun',
'host' => env('MAILGUN_DOMAIN'),
'username' => env('MAILGUN_KEY'),
'password' => '',
'port' => 465,
'encryption' => null,
'timeout' => null,
'options' => [
'domain' => env('MAILGUN_DOMAIN'),
],
],
Queueing Emails: Use Laravel's queue system with Mailgun:
Mail::to('user@example.com')->queue(new YourMailClass());
Ensure your queue worker (php artisan queue:work) is running.
Customizing Headers/Attachments: Leverage Swiftmailer's methods:
Mail::send([], [], function($message) {
$message->getHeaders()->addTextHeader('X-Custom-Header', 'value');
$message->attach($pathToFile);
});
Event Listeners:
Listen for mail events (e.g., Sent, Failed) via Laravel's events:
Mail::send([], [], function($message) {
event(new MailSent($message));
});
Dynamic Domains/Keys: Fetch credentials dynamically (e.g., from a database) by overriding the bundle's service provider:
$this->app->bind('cspoo_swiftmailer.mailgun', function($app) {
return new MailgunTransport(
$app['config']['mailgun.key'],
$app['config']['mailgun.domain']
);
});
Testing:
Use Laravel's Mail::fake() for unit tests:
Mail::fake();
Mail::send([], [], function($message) {
// Test logic
});
Mail::assertSent(YourMailClass::class);
Authentication Errors:
MAILGUN_KEY and MAILGUN_DOMAIN are correct (case-sensitive).Rate Limits: Mailgun enforces rate limits. Monitor usage via:
curl -s https://api.mailgun.net/v3/yourdomain.mailgun.org/statistics | jq
SSL/TLS Issues:
'options' => [
'curl' => [
CURLOPT_SSL_VERIFYPEER => false,
],
],
php-http/guzzle6-adapter for newer Laravel versions.Queue Delays: Mailgun may throttle queued emails. Use Mailgun’s webhooks to track delays.
config/mail.php:
'log' => [
'driver' => 'single',
'path' => storage_path('logs/mail.log'),
'level' => 'debug',
],
accepting, delivered, and failed events to debug in real-time:
# config/mailgun.php
webhook_url: 'https://your-app.com/mailgun-webhook'
Custom Transport:
Extend cspoo\Swiftmailer\MailgunBundle\Transport\MailgunTransport to add features like:
X-Mailgun-Tag: newsletter).Event Handling: Subscribe to Mailgun webhooks in Laravel:
Route::post('/mailgun-webhook', function (Request $request) {
MailgunWebhook::handle($request->input());
});
Fallback Transport: Combine with other transports (e.g., SMTP) for redundancy:
'mailgun' => [
'transport' => env('MAIL_DRIVER') === 'mailgun' ? 'mailgun' : 'smtp',
// ...
],
Service Provider Binding: If using Laravel 5.5+, the bundle auto-discovers. For older versions, manually bind:
$this->app->bind(
'swift.transport.mailgun',
function($app) {
return new MailgunTransport(
$app['config']['mail.mailgun.key'],
$app['config']['mail.mailgun.domain']
);
}
);
Environment Variables:
Use Laravel’s env() helper in config:
'key' => env('MAILGUN_KEY', 'fallback-key'),
'domain' => env('MAILGUN_DOMAIN', 'fallback-domain'),
How can I help you explore Laravel packages today?