Мне нужно добавить новый транспортный драйвер в почтовый пакет Laravel, чтобы я мог отправлять электронную почту через внешнюю службу (Mailjet), которая по умолчанию не поддерживается.
Написание драйвера транспорта не будет проблемой, но я не могу найти способ подключиться и добавить новый, поэтому я могу продолжать использовать почтовую программу Laravel как обычно. Я не могу найти документацию по расширению Mailer.
Единственный способ, с помощью которого я могу придумать, – заменить замену MailServiceProvider
Laravel на config/app.php
моим собственным поставщиком услуг, который я мог бы использовать для регистрации моего собственного TransportManager
и моего собственного транспортного драйвера.
Есть ли лучший способ добавить еще один транспортный драйвер?
Ну, мне удалось заставить его работать так, как я предложил в своем вопросе (написав собственный ServiceProvider
и TransportManager
чтобы я мог предоставить драйвер). Это то, что я сделал для всех, кто мог бы это понять:
config / app.php – Замените MailServiceProvider
Laravel своим собственным
// ... 'providers' => [ // ... // Illuminate\Mail\MailServiceProvider::class, App\MyMailer\MailServiceProvider::class, // ...
app / MyMailer / MailServiceProvider.php – создайте поставщика услуг, который расширяет MailServiceProvider
Laravel и переопределяет метод registerSwiftTransport()
<?php namespace App\MyMailer; class MailServiceProvider extends \Illuminate\Mail\MailServiceProvider { public function registerSwiftTransport() { $this->app['swift.transport'] = $this->app->share(function ($app) { // Note: This is my own implementation of transport manager as shown below return new TransportManager($app); }); } }
app / MyMailer / TransportManager.php – createMailjetDriver
метод createMailjetDriver
который делает мой драйвер MailjetTransport
доступным для Laravel's Mailer
<?php namespace App\MyMailer; use App\MyMailer\Transport\MailjetTransport; class TransportManager extends \Illuminate\Mail\TransportManager { protected function createMailjetDriver() { $config = $this->app['config']->get('services.mailjet', []); return new MailjetTransport( $this->getHttpClient($config), $config['api_key'], $config['secret_key'] ); } }
app / MyMailer / Transport / MailjetTransport.php – Мой собственный Транспортный драйвер, отправляющий электронные письма через Mailjet.
Обновлен, чтобы содержать мою реализацию драйвера транспорта Mailjet. Использование руководства Mailjet для отправки базовой электронной почты через их API в качестве базы .
<?php namespace App\MyMailer\Transport; use GuzzleHttp\ClientInterface; use Illuminate\Mail\Transport\Transport; use Swift_Mime_Message; class MailjetTransport extends Transport { /** * Guzzle HTTP client. * * @var ClientInterface */ protected $client; /** * The Mailjet "API key" which can be found at https://app.mailjet.com/transactional * * @var string */ protected $apiKey; /** * The Mailjet "Secret key" which can be found at https://app.mailjet.com/transactional * * @var string */ protected $secretKey; /** * The Mailjet end point we're using to send the message. * * @var string */ protected $endPoint = 'https://api.mailjet.com/v3/send'; /** * Create a new Mailjet transport instance. * * @param \GuzzleHttp\ClientInterface $client * @param $apiKey * @param $secretKey */ public function __construct(ClientInterface $client, $apiKey, $secretKey) { $this->client = $client; $this->apiKey = $apiKey; $this->secretKey = $secretKey; } /** * Send the given Message. * * Recipient/sender data will be retrieved from the Message API. * The return value is the number of recipients who were accepted for delivery. * * @param Swift_Mime_Message $message * @param string[] $failedRecipients An array of failures by-reference * * @return int */ public function send(Swift_Mime_Message $message, &$failedRecipients = null) { $this->beforeSendPerformed($message); $payload = [ 'header' => ['Content-Type', 'application/json'], 'auth' => [$this->apiKey, $this->secretKey], 'json' => [] ]; $this->addFrom($message, $payload); $this->addSubject($message, $payload); $this->addContent($message, $payload); $this->addRecipients($message, $payload); return $this->client->post($this->endPoint, $payload); } /** * Add the from email and from name (If provided) to the payload. * * @param Swift_Mime_Message $message * @param array $payload */ protected function addFrom(Swift_Mime_Message $message, &$payload) { $from = $message->getFrom(); $fromAddress = key($from); if ($fromAddress) { $payload['json']['FromEmail'] = $fromAddress; $fromName = $from[$fromAddress] ?: null; if ($fromName) { $payload['json']['FromName'] = $fromName; } } } /** * Add the subject of the email (If provided) to the payload. * * @param Swift_Mime_Message $message * @param array $payload */ protected function addSubject(Swift_Mime_Message $message, &$payload) { $subject = $message->getSubject(); if ($subject) { $payload['json']['Subject'] = $subject; } } /** * Add the content/body to the payload based upon the content type provided in the message object. In the unlikely * event that a content type isn't provided, we can guess it based on the existence of HTML tags in the body. * * @param Swift_Mime_Message $message * @param array $payload */ protected function addContent(Swift_Mime_Message $message, &$payload) { $contentType = $message->getContentType(); $body = $message->getBody(); if (!in_array($contentType, ['text/html', 'text/plain'])) { $contentType = strip_tags($body) != $body ? 'text/html' : 'text/plain'; } $payload['json'][$contentType == 'text/html' ? 'Html-part' : 'Text-part'] = $message->getBody(); } /** * Add to, cc and bcc recipients to the payload. * * @param Swift_Mime_Message $message * @param array $payload */ protected function addRecipients(Swift_Mime_Message $message, &$payload) { foreach (['To', 'Cc', 'Bcc'] as $field) { $formatted = []; $method = 'get' . $field; $contacts = (array) $message->$method(); foreach ($contacts as $address => $display) { $formatted[] = $display ? $display . " <$address>" : $address; } if (count($formatted) > 0) { $payload['json'][$field] = implode(', ', $formatted); } } } }
В моем файле .env
меня есть:
MAIL_DRIVER=mailjet
.., который позволяет мне использовать почтовый пакет Laravel (через фасад или инъекцию зависимости) как обычно:
\Mail::send('view', [], function($message) { $message->to('me@domain.com'); $message->subject('Test'); });