diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0c50553 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.DS_store +.idea/* \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..97aa03b --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +### Install + +Require this package with composer using the following command: +```bash +composer require clarification/sendgrid-laravel-driver +``` + +After updating composer, add the service provider to the `providers` array in `config/app.php` +```php +Clarification\MailDrivers\Sendgrid\SendgridServiceProvider::class, +``` + +You will also need to add the sendgrid API Key settings to the array in `config/services.php` and set up the environment key +```php +'sendgrid' => [ + 'api_key' => env('SENDGRID_API_KEY'), +], +``` +```bash +SENDGRID_API_KEY=__Your_key_here__ +``` + +Finally you need to set your mail driver to `sendgrid`. You can do this by changing the driver in `config/mail.php` +```php +'driver' => env('MAIL_DRIVER', 'sendgrid'), +``` + +Or by setting the environment variable `MAIL_DRIVER` in your .env file +```bash +MAIL_DRIVER=sendgrid +``` diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..69203d1 --- /dev/null +++ b/composer.json @@ -0,0 +1,23 @@ +{ + "name": "clarification/sendgrid-laravel-driver", + "type": "library", + "description" : "Sendgrid mail driver for Laravel", + "keywords": ["laravel", "mail", "driver", "sendgrid"], + "license": "MIT", + "homepage" : "http://clarification.io", + "authors": [ + { + "name" : "Robin Lidbetter", + "role" : "Developer" + } + ], + "require": { + "illuminate/container": ">=4.2", + "swiftmailer/swiftmailer": "~5.1" + }, + "autoload": { + "psr-4": { + "Clarification\\MailDrivers\\Sendgrid\\": "src" + } + } +} \ No newline at end of file diff --git a/src/SendgridServiceProvider.php b/src/SendgridServiceProvider.php new file mode 100644 index 0000000..9327c3f --- /dev/null +++ b/src/SendgridServiceProvider.php @@ -0,0 +1,41 @@ +app->extend('swift.transport', function(TransportManager $manager) { + $manager->extend('sendgrid', function() { + $config = $this->app['config']->get('services.sendgrid', []); + $client = new Client(Arr::get($config, 'guzzle', [])); + return new SendgridTransport($client, $config['api_key']); + }); + return $manager; + }); + } +} diff --git a/src/Transport/SendgridTransport.php b/src/Transport/SendgridTransport.php new file mode 100644 index 0000000..affd844 --- /dev/null +++ b/src/Transport/SendgridTransport.php @@ -0,0 +1,159 @@ +client = $client; + $this->options = [ + 'headers' => ['Authorization' => 'Bearer ' . $api_key] + ]; + } + + /** + * 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) + { + list($from, $fromName) = $this->getFromAddresses($message); + $payload = $this->options; + $data = [ + 'from' => $from, + 'fromname' => isset($fromName) ? $fromName : null, + 'subject' => $message->getSubject(), + 'html' => $message->getBody() + ]; + $this->setTo($data, $message); + $this->setCc($data, $message); + $this->setBcc($data, $message); + $this->setText($data, $message); + $this->setAttachment($data, $message); + $this->setSmtpApi($data, $message); + if (version_compare(ClientInterface::VERSION, '6') === 1) { + $payload += ['form_params' => $data]; + } else { + $payload += ['body' => $data]; + } + return $this->client->post('https://api.sendgrid.com/api/mail.send.json', $payload); + } + /** + * @param $data + * @param Swift_Mime_Message $message + */ + protected function setTo(&$data, Swift_Mime_Message $message) + { + if ($to = $message->getTo()) { + $data['to'] = array_keys($to); + $data['toname'] = array_values($to); + } + } + /** + * @param $data + * @param Swift_Mime_Message $message + */ + protected function setCc(&$data, Swift_Mime_Message $message) + { + if ($cc = $message->getCc()) { + $data['cc'] = array_keys($cc); + $data['ccname'] = array_values($cc); + } + } + /** + * @param $data + * @param Swift_Mime_Message $message + */ + protected function setBcc(&$data, Swift_Mime_Message $message) + { + if ($bcc = $message->getBcc()) { + $data['bcc'] = array_keys($bcc); + $data['bccname'] = array_values($bcc); + } + } + /** + * Get From Addresses. + * + * @param Swift_Mime_Message $message + * @return array + */ + protected function getFromAddresses(Swift_Mime_Message $message) + { + if ($message->getFrom()) { + foreach ($message->getFrom() as $address => $name) { + return [$address, $name]; + } + } + return []; + } + /** + * Set text contents. + * + * @param $data + * @param Swift_Mime_Message $message + */ + protected function setText(&$data, Swift_Mime_Message $message) + { + foreach ($message->getChildren() as $attachment) { + if (!$attachment instanceof Swift_MimePart) { + continue; + } + $data['text'] = $attachment->getBody(); + } + } + /** + * Set Attachment Files. + * + * @param $data + * @param Swift_Mime_Message $message + */ + protected function setAttachment(&$data, Swift_Mime_Message $message) + { + foreach ($message->getChildren() as $attachment) { + if (!$attachment instanceof Swift_Attachment || !strlen($attachment->getBody()) > self::MAXIMUM_FILE_SIZE) { + continue; + } + $handler = tmpfile(); + fwrite($handler, $attachment->getBody()); + $data['files[' . $attachment->getFilename() . ']'] = $handler; + } + } + /** + * Set Sendgrid SMTP API + * + * @param $data + * @param Swift_Mime_Message $message + */ + protected function setSmtpApi(&$data, Swift_Mime_Message $message) + { + foreach ($message->getChildren() as $attachment) { + if (!$attachment instanceof Swift_Image + || !in_array(self::SMTP_API_NAME, [$attachment->getFilename(), $attachment->getContentType()]) + ) { + continue; + } + $data['x-smtpapi'] = json_encode($attachment->getBody()); + } + } +}