symfony/mailgun-mailer
Symfony Mailer integration for Mailgun. Send emails via Mailgun using SMTP, HTTP, or API transports by setting MAILER_DSN with your Mailgun key, domain, and optional region. Suitable for Symfony apps needing reliable Mailgun delivery.
While this package is Symfony-first, Laravel developers can still leverage it in specific edge cases (e.g., legacy Symfony microservices or hybrid apps). Here’s how to integrate it minimally:
Install via Composer (in a Symfony-compatible context):
composer require symfony/mailgun-mailer
Configure in .env (Symfony-style DSN):
MAILER_DSN=mailgun+api://YOUR_MAILGUN_API_KEY:YOUR_DOMAIN@default?region=us
YOUR_MAILGUN_API_KEY with your Mailgun API key.YOUR_DOMAIN with your Mailgun sending domain (e.g., example.com).region is optional (defaults to us; use eu for EU region).First Use Case: Send an Email
Use Symfony’s MailerInterface in a Laravel service (requires Symfony’s Mailer component):
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mailer\Envelope;
use Symfony\Component\Mime\Email;
public function sendWelcomeEmail(MailerInterface $mailer, string $to)
{
$email = (new Email())
->from('noreply@example.com')
->to($to)
->subject('Welcome!')
->text('Hello!');
$envelope = new Envelope(
new Address($to),
'noreply@example.com',
['X-Mailgun-Variables' => '{"user": "John"}']
);
$mailer->send($email, $envelope);
}
MailerInterface via Laravel’s container (see Implementation Patterns).DSN Configuration:
region values.Laravel-Symfony Bridge:
spatie/laravel-symfony-mail to integrate Symfony’s Mailer into Laravel’s ecosystem.MailerInterface in Laravel’s SwiftMailer abstraction.Debugging:
APP_DEBUG=true in .env) to inspect Mailgun transport logs.If your Laravel app interacts with a Symfony microservice (e.g., for emails), use this package in the Symfony service and expose a REST API or message queue (e.g., Laravel Horizon) for Laravel to trigger emails.
Example Workflow:
SendEmail job to a queue.symfony/mailgun-mailer to send emails.job-id to Laravel for tracking.To use Symfony’s MailerInterface in Laravel, register it in a service provider:
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mailer\Transport\MailgunTransportFactory;
public function register()
{
$this->app->singleton(MailerInterface::class, function ($app) {
$dsn = config('mail.mailers.mailgun.dsn');
$transport = MailgunTransportFactory::fromDsn($dsn);
return new MailerInterface($transport);
});
}
Config (config/mail.php):
'mailers' => [
'mailgun' => [
'dsn' => env('MAILER_DSN', 'mailgun+api://key:domain@default'),
],
],
If you must use this package in Laravel, create a custom mail facade:
use Illuminate\Support\Facades\Facade;
class SymfonyMailFacade extends Facade
{
protected static function getFacadeAccessor()
{
return 'symfony.mailer';
}
}
Register the MailerInterface as a singleton (as above) and bind it to symfony.mailer.
Mailgun-Specific Features:
Envelope to add Mailgun variables or tags:
$envelope = new Envelope(
new Address($to),
'noreply@example.com',
['X-Mailgun-Variables' => json_encode(['user_id' => 123])]
);
Fallback Transports:
Configure a fallback transport in Symfony’s Mailer for resilience:
$mailer = new Mailer([
new Transport($mailgunTransport),
new Transport(new SmtpTransport('backup-smtp.example.com', 587)),
]);
Testing:
TestMailer for unit tests:
$mailer = new TestMailer();
$mailer->send($email);
$this->assertCount(1, $mailer->getSentEmails());
MailerInterface in Laravel’s tests:
$this->mock(MailerInterface::class)->shouldReceive('send');
Environment-Specific Configs:
Use Laravel’s config/mail.php to switch transports dynamically:
'mailers' => [
'mailgun' => [
'dsn' => env('MAILER_DSN', 'mailgun+api://key:domain@default'),
'region' => env('MAILGUN_REGION', 'us'),
],
],
Dependency Conflicts:
mailer Version Mismatch: Laravel 10 uses symfony/mailer:^6.4, but this package requires ^7.4|^8.0. Resolving this may require:
symfony/mailer dependency.HTTP/1.1 Enforcement:
HttpClient to respect HTTP/1.1:
$client = new HttpClient([
'http_version' => '1.1',
]);
Message Object Preservation:
Message object when sending. If you rely on Laravel’s SwiftMessage modifications (e.g., setBody()), ensure compatibility:
// Laravel's SwiftMessage
$message = (new \Swift_Message())
->setSubject('Test')
->setFrom(['from@example.com'])
->setTo(['to@example.com'])
->setBody('Hello');
// Convert to Symfony's Email (if needed)
$email = Email::fromSwiftMessage($message);
Region-Specific Issues:
region=eu) may have stricter IP requirements. Ensure your Laravel server’s IP is whitelisted in Mailgun’s dashboard.region parameter in the DSN is case-sensitive (us vs. US).Debugging Mailgun Errors:
Mailer may not surface these errors clearly.Response object:
try {
$mailer->send($email);
} catch (\Symfony\Component\Mailer\Exception\TransportException $e) {
$response = $e->getResponse();
// Log $response->getContent() for Mailgun error details
}
Mailer to log transport interactions:
$mailer = new Mailer($transport, [
'logger' => new \Monolog\Logger('mailer
How can I help you explore Laravel packages today?