【问题标题】:Creating own mail provider for Laravel 5.4为 Laravel 5.4 创建自己的邮件提供程序
【发布时间】:2017-12-07 16:29:19
【问题描述】:

有时我们必须集成自定义邮件提供程序。但是 Laravel 有一个固定的列表。他们在这里:

  • SMTP
  • 发送邮件
  • ses
  • 邮筒
  • 山魈
  • Sparkpost

您可以在framework/src/Illuminate/Mail/TransportManager.php 中找到这些驱动程序的说明

问题在于这些指令是固定的。当然,您可以修改供应商文件,但将是一个肮脏的黑客。因此,在答案中,我将提供一些说明如何以正确的方式实现您自己的自定义邮件驱动程序。

【问题讨论】:

    标签: php laravel laravel-5.4


    【解决方案1】:

    首先我们必须为我们的邮件创建自定义Transport

    我们的邮件程序将通过一些 API 接口与另一台服务器通信。下面的文件是一个模型,所以我把它放到了我的模型文件夹中。如果您没有单独的模型文件夹,您可以将文件放入app 目录。

    我们称之为SmithTransport.php

    <?php 
    
    use GuzzleHttp\ClientInterface;
    use Illuminate\Mail\Transport\Transport;
    
    class SmithTransport extends Transport
    {
        protected $client;
    
        protected $key;
    
        protected $domain;
    
        protected $url;
    
        public function __construct(ClientInterface $client, $key, $domain)
        {
            $this->key = $key;
            $this->client = $client;
            $this->setDomain($domain);
        }
    
        public function send(Swift_Mime_Message $message, &$failedRecipients = null)
        {
            $this->beforeSendPerformed($message);
    
            $options = ['auth' => ['api', $this->key]];
    
            $message->setBcc([]);
    
            $from_email = '';
            $from_name = '';
            $to_email = '';
            $to_name = '';
    
            foreach ($message->getFrom() as $email => $name) {
                $from_email = $email;
                $from_name = $name;
            }
    
            foreach ($message->getTo() as $email => $name) {
                $to_email = $email;
                $to_name = $name;
            }
    
            $options['form_params'] = [
                'from_email' => $from_email,
                'from_name'  => $from_name,
                'to_email'   => $to_email,
                'to_name'    => $to_name,
                'subject'    => $message->getSubject(),
                'body'       => $message->getBody()
            ];
    
            return $this->client->post($this->url, $options);
        }
    
        public function getKey()
        {
            return $this->key;
        }
    
        public function setKey($key)
        {
            return $this->key = $key;
        }
    
        public function getDomain()
        {
            return $this->domain;
        }
    
        public function setDomain($domain)
        {
            $this->url = 'https://api.mymailer.com/send?key=' . $this->key;
    
            return $this->domain = $domain;
        }
    }
    

    下一步是扩展TransportManager。因为我们必须为我们的自定义传输添加说明。

    因此,如果您没有单独的模型目录,它将是模型目录中的SmithTransportManager.phpapp 目录。

    <?php
    
    use Illuminate\Mail\TransportManager;
    
    class SmithTransportManager extends TransportManager
    {
        protected function createSmithDriver()
        {
            $config = $this->app['config']->get('services.smith', []);
    
            return new SmithTransport(
                $this->guggle($config),
                $config['secret'], $config['domain']
            );
        }
    
    }
    

    下一步是扩展现有的MailServiceProvider

    所以我们的提供者将在app/Providers/MailServiceProvider.php

    <?php namespace App\Providers;
    
    use Illuminate\Mail\MailServiceProvider as MailProvider;
    
    class MailServiceProvider extends MailProvider
    {
        protected function registerSwiftTransport()
        {
            $this->app->singleton('swift.transport', function ($app) {
                return new \SmithTransportManager($app);
            });
        }
    
    }
    

    最后一步是修改配置文件。

    config/app.php

    你必须删除(或注释行)标准Illuminate\Mail\MailServiceProvider::class,

    并将App\Providers\MailServiceProvider::class, 添加到providers 部分。

    config/services.php 中我们必须添加配置getter:

    'smith' => [
        'domain' => env('SMITH_DOMAIN'),
        'secret' => env('SMITH_SECRET'),
    ],
    

    就是这样!希望它有所帮助,因为我在其他地方的文档中没有找到任何关于自定义 MailTransport 的信息。

    【讨论】:

    • guggle 在 5.6 中表示 Guzzle>
    • @JamieRoss 这个答案是根据使用 Laravel5.4 设计的真实示例编写的。我不确定从那以后发生了什么变化
    • 对于 laravel 5.6 或更高版本,您只需删除 Swift_Mime_Message 并将其替换为 \Swift_Mime_SimpleMessage
    • 这在Laravel 5.5 上完美运行,但是如何识别发送的 Api 邮件中的错误? Guzzle 抛出异常?示例: client->post(...);返回 $result->getBody() == 'OK'; } ...if (count(Mail::failures()) &gt; 0) { 会起作用吗? 0) { $this->danger("发送电子邮件到$to时出错"); } else { $this->info("邮件发送到 $to"); }
    • @bermick 部分。如果您使用的是 SendGrid 模板而不是 Blade,那么您需要实现额外的逻辑来为其准备数据
    猜你喜欢
    • 2014-03-15
    • 1970-01-01
    • 1970-01-01
    • 2014-12-15
    • 2016-11-10
    • 2017-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多