使用Laravel Mail Facade从多个Mailgun域发送

Wil*_*ney 5 email dns queue laravel mailgun

我正在使用Laravel 4 Mail::queue()通过内置的Mailgun驱动程序发送电子邮件。问题是我希望能够从多个Mailgun域发送电子邮件,但是必须在中设置该域app/config/services.php。由于正在使用Mail::queue(),所以我看不到如何动态设置该配置变量。

有什么办法可以满足我的要求吗?理想情况下,我希望能够在调用时传递域Mail::queue()(Mailgun api密钥对于我要从中发送的所有域都是相同的)。

Mir*_*c21 9

我曾经Macros添加动态配置。我不记得这是否可以在 Laravel 4 中完成但适用于 5。

在服务提供者中注册宏 ( AppServiceProvider)

public function boot()
{
    Mail::macro('setConfig', function (string $key, string $domain) {

        $transport = $this->getSwiftMailer()->getTransport();
        $transport->setKey($key);
        $transport->setDomain($domain);

        return $this;
    });
}
Run Code Online (Sandbox Code Playgroud)

然后我可以这样使用:

\Mail::setConfig($mailgunKey, $mailgunDomain)->to(...)->send(...)
Run Code Online (Sandbox Code Playgroud)

在你的情况下

\Mail::setConfig($mailgunKey, $mailgunDomain)->to(...)->queue(...)
Run Code Online (Sandbox Code Playgroud)


Bog*_*dan 5

在运行时切换 Laravel Mailer 的配置细节并不难,但是我不知道使用Mail::queueFacade可以通过什么方式来完成。它可以通过组合来实现Queue::pushMail::send(这是Mail::queue无论如何不会)。

Mail::queue外观的问题在于$message传递给闭包的参数是类型的Illuminate\Mail\Message,我们需要修改邮件传输,它只能通过Swift_Mailer实例访问(并且在Message类中是只读的)。

您需要创建一个负责发送电子邮件的类,使用使用您想要的域的 Mailgun 传输实例:

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);
    }

}
Run Code Online (Sandbox Code Playgroud)

现在您可以像这样对电子邮件进行排队:

use Illuminate\Support\SerializableClosure;

...

Queue::push('SendQueuedMail', ['domain.com', 'view', $data, serialize(new SerializableClosure(function ($message)
{
    // do your email sending stuff here
}))]);
Run Code Online (Sandbox Code Playgroud)

虽然它没有使用Mail::queue,但这个替代方案同样紧凑且易于阅读。此代码未经测试,但应该可以工作。


Vik*_*mer 5

这适用于 Laravel 5.4:

// Get the existing SwiftMailer
$swiftMailer = Mail::getSwiftMailer();

// Update the domain in the transporter (Mailgun)
$transport = $swiftMailer->getTransport();
$transport->setDomain('YOUR-DOMAIN.HERE');

// Use the updated version
$mailer = Swift_Mailer::newInstance($transport);
Mail::setSwiftMailer($mailer);
Run Code Online (Sandbox Code Playgroud)