Mail

Introduction

Laravel provides a clean, simple API over the popular SwiftMailer library. Laravel provides drivers for SMTP, Mailgun, Mandrill, Amazon SES, PHP's mail function, and sendmail, allowing you to quickly get started sending mail through a local or cloud based service of your choice.

Driver Prerequisites

The API based drivers such as Mailgun and Mandrill are often simpler and faster than SMTP servers. All of the API drivers require that the Guzzle HTTP library be installed for your application. You may install Guzzle to your project by adding the following line to your composer.json file:

  1. "guzzlehttp/guzzle": "~5.3|~6.0"

Mailgun Driver

To use the Mailgun driver, first install Guzzle, then set the driver option in your config/mail.php configuration file to mailgun. Next, verify that your config/services.php configuration file contains the following options:

  1. 'mailgun' => [
  2. 'domain' => 'your-mailgun-domain',
  3. 'secret' => 'your-mailgun-key',
  4. ],

Mandrill Driver

To use the Mandrill driver, first install Guzzle, then set the driver option in your config/mail.php configuration file to mandrill. Next, verify that your config/services.php configuration file contains the following options:

  1. 'mandrill' => [
  2. 'secret' => 'your-mandrill-key',
  3. ],

SES Driver

To use the Amazon SES driver, install the Amazon AWS SDK for PHP. You may install this library by adding the following line to your composer.json file's require section:

  1. "aws/aws-sdk-php": "~3.0"

Next, set the driver option in your config/mail.php configuration file to ses. Then, verify that your config/services.php configuration file contains the following options:

  1. 'ses' => [
  2. 'key' => 'your-ses-key',
  3. 'secret' => 'your-ses-secret',
  4. 'region' => 'ses-region', // e.g. us-east-1
  5. ],

Sending Mail

Laravel allows you to store your e-mail messages in views. For example, to organize your e-mails, you could create an emails directory within your resources/views directory:

To send a message, use the send method on the Mail facade. The send method accepts three arguments. First, the name of a view that contains the e-mail message. Secondly, an array of data you wish to pass to the view. Lastly, a Closure callback which receives a message instance, allowing you to customize the recipients, subject, and other aspects of the mail message:

  1. <?php
  2. namespace App\Http\Controllers;
  3. use Mail;
  4. use App\User;
  5. use Illuminate\Http\Request;
  6. use App\Http\Controllers\Controller;
  7. class UserController extends Controller
  8. {
  9. /**
  10. * Send an e-mail reminder to the user.
  11. *
  12. * @param Request $request
  13. * @param int $id
  14. * @return Response
  15. */
  16. public function sendEmailReminder(Request $request, $id)
  17. {
  18. $user = User::findOrFail($id);
  19. Mail::send('emails.reminder', ['user' => $user], function ($m) use ($user) {
  20. $m->from('[email protected]', 'Your Application');
  21. $m->to($user->email, $user->name)->subject('Your Reminder!');
  22. });
  23. }
  24. }

Since we are passing an array containing the user key in the example above, we could display the user's name within our e-mail view using the following PHP code:

  1. <?php echo $user->name; ?>

Note: A $message variable is always passed to e-mail views, and allows the inline embedding of attachments. So, you should avoid passing a message variable in your view payload.

Building The Message

As previously discussed, the third argument given to the send method is a Closure allowing you to specify various options on the e-mail message itself. Using this Closure you may specify other attributes of the message, such as carbon copies, blind carbon copies, etc:

  1. Mail::send('emails.welcome', $data, function ($message) {
  2. $message->from('[email protected]', 'Laravel');
  3. $message->to('[email protected]')->cc('[email protected]');
  4. });

Here is a list of the available methods on the $message message builder instance:

  1. $message->from($address, $name = null);
  2. $message->sender($address, $name = null);
  3. $message->to($address, $name = null);
  4. $message->cc($address, $name = null);
  5. $message->bcc($address, $name = null);
  6. $message->replyTo($address, $name = null);
  7. $message->subject($subject);
  8. $message->priority($level);
  9. $message->attach($pathToFile, array $options = []);
  10. // Attach a file from a raw $data string...
  11. $message->attachData($data, $name, array $options = []);
  12. // Get the underlying SwiftMailer message instance...
  13. $message->getSwiftMessage();

Note: The message instance passed to a Mail::send Closure extends the SwiftMailer message class, allowing you to call any method on that class to build your e-mail messages.

Mailing Plain Text

By default, the view given to the send method is assumed to contain HTML. However, by passing an array as the first argument to the send method, you may specify a plain text view to send in addition to the HTML view:

  1. Mail::send(['html.view', 'text.view'], $data, $callback);

Or, if you only need to send a plain text e-mail, you may specify this using the text key in the array:

  1. Mail::send(['text' => 'view'], $data, $callback);

Mailing Raw Strings

You may use the raw method if you wish to e-mail a raw string directly:

  1. Mail::raw('Text to e-mail', function ($message) {
  2. //
  3. });

Attachments

To add attachments to an e-mail, use the attach method on the $message object passed to your Closure. The attach method accepts the full path to the file as its first argument:

  1. Mail::send('emails.welcome', $data, function ($message) {
  2. //
  3. $message->attach($pathToFile);
  4. });

When attaching files to a message, you may also specify the display name and / or MIME type by passing an array as the second argument to the attach method:

  1. $message->attach($pathToFile, ['as' => $display, 'mime' => $mime]);

Inline Attachments

Embedding An Image In An E-Mail View

Embedding inline images into your e-mails is typically cumbersome; however, Laravel provides a convenient way to attach images to your e-mails and retrieving the appropriate CID. To embed an inline image, use the embed method on the $message variable within your e-mail view. Remember, Laravel automatically makes the $message variable available to all of your e-mail views:

  1. <body>
  2. Here is an image:
  3. <img src="<?php echo $message->embed($pathToFile); ?>">
  4. </body>

Embedding Raw Data In An E-Mail View

If you already have a raw data string you wish to embed into an e-mail message, you may use the embedData method on the $message variable:

  1. <body>
  2. Here is an image from raw data:
  3. <img src="<?php echo $message->embedData($data, $name); ?>">
  4. </body>

Queueing Mail

Queueing A Mail Message

Since sending e-mail messages can drastically lengthen the response time of your application, many developers choose to queue e-mail messages for background sending. Laravel makes this easy using its built-in unified queue API. To queue a mail message, use the queue method on the Mail facade:

  1. Mail::queue('emails.welcome', $data, function ($message) {
  2. //
  3. });

This method will automatically take care of pushing a job onto the queue to send the mail message in the background. Of course, you will need to configure your queues before using this feature.

Delayed Message Queueing

If you wish to delay the delivery of a queued e-mail message, you may use the later method. To get started, simply pass the number of seconds by which you wish to delay the sending of the message as the first argument to the method:

  1. Mail::later(5, 'emails.welcome', $data, function ($message) {
  2. //
  3. });

Pushing To Specific Queues

If you wish to specify a specific queue on which to push the message, you may do so using the queueOn and laterOn methods:

  1. Mail::queueOn('queue-name', 'emails.welcome', $data, function ($message) {
  2. //
  3. });
  4. Mail::laterOn('queue-name', 5, 'emails.welcome', $data, function ($message) {
  5. //
  6. });

Mail & Local Development

When developing an application that sends e-mail, you probably don't want to actually send e-mails to live e-mail addresses. Laravel provides several ways to "disable" the actual sending of e-mail messages.

Log Driver

One solution is to use the log mail driver during local development. This driver will write all e-mail messages to your log files for inspection. For more information on configuring your application per environment, check out the configuration documentation.

Universal To

Another solution provided by Laravel is to set a universal recipient of all e-mails sent by the framework. This way, all the emails generated by your application will be sent to a specific address, instead of the address actually specified when sending the message. This can be done via the to option in your config/mail.php configuration file:

  1. 'to' => [
  2. 'address' => '[email protected]',
  3. 'name' => 'Dev Example'
  4. ],

Mailtrap

Finally, you may use a service like Mailtrap and the smtp driver to send your e-mail messages to a "dummy" mailbox where you may view them in a true e-mail client. This approach has the benefit of allowing you to actually inspect the final e-mails in Mailtrap's message viewer.

Events

Laravel fires the mailer.sending event just before sending mail messages. Remember, this event is fired when the mail is sent, not when it is queued. You may register an event listener in your EventServiceProvider:

  1. /**
  2. * Register any other events for your application.
  3. *
  4. * @param \Illuminate\Contracts\Events\Dispatcher $events
  5. * @return void
  6. */
  7. public function boot(DispatcherContract $events)
  8. {
  9. parent::boot($events);
  10. $events->listen('mailer.sending', function ($message) {
  11. //
  12. });
  13. }