Sending from multiple Mailgun domains using Laravel Mail facade
dns, email, laravel, mailgun, queue
Solution
Switching the configuration details of the Laravel Mailer at runtime is not that hard, however I don't know of any way it can be done using the `Mail::queue` facade. It can be done by using a combination of `Queue::push` and `Mail::send` (which is what `Mail::queue` does anyway).
The problem with the `Mail::queue` facade is that the `$message` parameter passed to the closure, is of type `Illuminate\Mail\Message` and we need to modify the mailer transport, which is only accessible through the `Swift_Mailer` instance (and that is readonly within the `Message` class).
You need to create a class responsible for sending the email, using a Mailgun transport instance that uses the domain you want:
use Illuminate\Mail\Transport\MailgunTransport;
use Illuminate\Support\SerializableClosure;
class SendQueuedMail {
public function fire($job, $params)
{
// Get the needed parameters
list($domain, $view, $data, $callback) = $params;
// Backup your default mailer
$backup = Mail::getSwiftMailer();
// Setup your mailgun transport
$transport = new MailgunTransport(Config::get('services.mailgun.secret'), $domain);
$mailer = new Swift_Mailer($transport);
// Set the new mailer with the domain
Mail::setSwiftMailer($mailer);
// Send your message
Mail::send($view, $data, unserialize($callback)->getClosure());
// Restore the default mailer instance
Mail::setSwiftMailer($backup);
}
}
And now you can queue emails like this:
use Illuminate\Support\SerializableClosure;
...
Queue::push('SendQueuedMail', ['domain.com', 'view', $data, serialize(new SerializableClosure(function ($message)
{
// do your email sending stuff here
}))]);
While it's not using `Mail::queue`, this alternative is just as compact and easy to read. This code is not tested but should work.
Problem
I'm using the Laravel 4's `Mail::queue()` to send emails, using the built in Mailgun driver. The problem is that there are multiple Mailgun domains I would like to be able to send emails from, but the domain must be set in `app/config/services.php`. Since I'm using `Mail::queue()`, I can't see how to dynamically set that configuration variable. Is there any way to do what I'm asking? Ideally, I'd like to be able to pass in the domain when I call `Mail::queue()` (the Mailgun api key is the same for all the domains I want to send from).