Notifications
Introduction
In addition to support for sending email, Laravel provides support for sending notifications across a variety of delivery channels, including mail, SMS (via Vonage, formerly known as Nexmo), and Slack. Notifications may also be stored in a database so they may be displayed in your web interface.
Typically, notifications should be short, informational messages that notify users of something that occurred in your application. For example, if you are writing a billing application, you might send an "Invoice Paid" notification to your users via the email and SMS channels.
Creating Notifications
In Laravel, each notification is represented by a single class (typically stored in the app/Notifications
directory). Don't worry if you don't see this directory in your application, it will be created for you when you run the make:notification
Artisan command:
php artisan make:notification InvoicePaid
This command will place a fresh notification class in your app/Notifications
directory. Each notification class contains a via
method and a variable number of message building methods (such as toMail
or toDatabase
) that convert the notification to a message optimized for that particular channel.
Sending Notifications
Using The Notifiable Trait
Notifications may be sent in two ways: using the notify
method of the Notifiable
trait or using the Notification
facade. First, let's explore using the trait:
<?php
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use Notifiable;
}
This trait is utilized by the default App\User
model and contains one method that may be used to send notifications: notify
. The notify
method expects to receive a notification instance:
use App\Notifications\InvoicePaid;
$user->notify(new InvoicePaid($invoice));
Remember, you may use the Illuminate\Notifications\Notifiable
trait on any of your models. You are not limited to only including it on your User
model.
Using The Notification Facade
Alternatively, you may send notifications via the Notification
facade. This is useful primarily when you need to send a notification to multiple notifiable entities such as a collection of users. To send notifications using the facade, pass all of the notifiable entities and the notification instance to the send
method:
Notification::send($users, new InvoicePaid($invoice));
Specifying Delivery Channels
Every notification class has a via
method that determines on which channels the notification will be delivered. Notifications may be sent on the mail
, database
, broadcast
, nexmo
, and slack
channels.
If you would like to use other delivery channels such as Telegram or Pusher, check out the community driven Laravel Notification Channels website.
The via
method receives a $notifiable
instance, which will be an instance of the class to which the notification is being sent. You may use $notifiable
to determine which channels the notification should be delivered on:
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return $notifiable->prefers_sms ? ['nexmo'] : ['mail', 'database'];
}
Queueing Notifications
Before queueing notifications you should configure your queue and start a worker.
Sending notifications can take time, especially if the channel needs an external API call to deliver the notification. To speed up your application's response time, let your notification be queued by adding the ShouldQueue
interface and Queueable
trait to your class. The interface and trait are already imported for all notifications generated using make:notification
, so you may immediately add them to your notification class:
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
class InvoicePaid extends Notification implements ShouldQueue
{
use Queueable;
// ...
}
Once the ShouldQueue
interface has been added to your notification, you may send the notification like normal. Laravel will detect the ShouldQueue
interface on the class and automatically queue the delivery of the notification:
$user->notify(new InvoicePaid($invoice));
If you would like to delay the delivery of the notification, you may chain the delay
method onto your notification instantiation:
$when = now()->addMinutes(10);
$user->notify((new InvoicePaid($invoice))->delay($when));
Customizing Notification Channel Queues
If you would like to specify a specific queue that should be used for each notification channel supported by the notification, you may define a viaQueues
method on your notification. This method should return an array of channel name / queue name pairs:
/**
* Determine which queues should be used for each notification channel.
*
* @return array
*/
public function viaQueues()
{
return [
'mail' => 'mail-queue',
'slack' => 'slack-queue',
];
}
On-Demand Notifications
Sometimes you may need to send a notification to someone who is not stored as a "user" of your application. Using the Notification::route
facade method, you may specify ad-hoc notification routing information before sending the notification:
Notification::route('mail', 'taylor@example.com')
->route('nexmo', '5555555555')
->route('slack', 'https://hooks.slack.com/services/...')
->notify(new InvoicePaid($invoice));
Mail Notifications
Formatting Mail Messages
If a notification supports being sent as an email, you should define a toMail
method on the notification class. This method will receive a $notifiable
entity and should return a Illuminate\Notifications\Messages\MailMessage
instance. Mail messages may contain lines of text as well as a "call to action". Let's take a look at an example toMail
method:
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
$url = url('/invoice/'.$this->invoice->id);
return (new MailMessage)
->greeting('Hello!')
->line('One of your invoices has been paid!')
->action('View Invoice', $url)
->line('Thank you for using our application!');
}
Note we are using $this->invoice->id
in our toMail
method. You may pass any data your notification needs to generate its message into the notification's constructor.
In this example, we register a greeting, a line of text, a call to action, and then another line of text. These methods provided by the MailMessage
object make it simple and fast to format small transactional emails. The mail channel will then translate the message components into a nice, responsive HTML email template with a plain-text counterpart. Here is an example of an email generated by the mail
channel:
When sending mail notifications, be sure to set the name
value in your config/app.php
configuration file. This value will be used in the header and footer of your mail notification messages.
Other Notification Formatting Options
Instead of defining the "lines" of text in the notification class, you may use the view
method to specify a custom template that should be used to render the notification email:
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)->view(
'emails.name', ['invoice' => $this->invoice]
);
}
You may specify a plain-text view for the mail message by passing the view name as the second element of an array that is given to the view
method of the MailMessage
:
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)->view(
['emails.name.html', 'emails.name.plain'],
['invoice' => $this->invoice]
);
}
In addition, you may return a full mailable object from the toMail
method:
use App\Mail\InvoicePaid as Mailable;
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return Mailable
*/
public function toMail($notifiable)
{
return (new Mailable($this->invoice))->to($notifiable->email);
}
Error Messages
Some notifications inform users of errors, such as a failed invoice payment. You may indicate that a mail message is regarding an error by calling the error
method when building your message. When using the error
method on a mail message, the call to action button will be red instead of blue:
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Message
*/
public function toMail($notifiable)
{
return (new MailMessage)
->error()
->subject('Notification Subject')
->line('...');
}
Customizing The Sender
By default, the email's sender / from address is defined in the config/mail.php
configuration file. However, you may specify the from address for a specific notification using the from
method:
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->from('test@example.com', 'Example')
->line('...');
}
Customizing The Recipient
When sending notifications via the mail
channel, the notification system will automatically look for an email
property on your notifiable entity. You may customize which email address is used to deliver the notification by defining a routeNotificationForMail
method on the entity:
<?php
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use Notifiable;
/**
* Route notifications for the mail channel.
*
* @param \Illuminate\Notifications\Notification $notification
* @return array|string
*/
public function routeNotificationForMail($notification)
{
// Return email address only...
return $this->email_address;
// Return name and email address...
return [$this->email_address => $this->name];
}
}
Customizing The Subject
By default, the email's subject is the class name of the notification formatted to "title case". So, if your notification class is named InvoicePaid
, the email's subject will be Invoice Paid
. If you would like to specify an explicit subject for the message, you may call the subject
method when building your message:
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->subject('Notification Subject')
->line('...');
}
Customizing The Mailer
By default, the email notification will be sent using the default driver defined in the config/mail.php
configuration file. However, you may specify a different mailer at runtime by calling the mailer
method when building your message:
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->mailer('postmark')
->line('...');
}
Customizing The Templates
You can modify the HTML and plain-text template used by mail notifications by publishing the notification package's resources. After running this command, the mail notification templates will be located in the resources/views/vendor/notifications
directory:
php artisan vendor:publish --tag=laravel-notifications
Previewing Mail Notifications
When designing a mail notification template, it is convenient to quickly preview the rendered mail message in your browser like a typical Blade template. For this reason, Laravel allows you to return any mail message generated by a mail notification directly from a route Closure or controller. When a MailMessage
is returned, it will be rendered and displayed in the browser, allowing you to quickly preview its design without needing to send it to an actual email address:
Route::get('mail', function () {
$invoice = App\Invoice::find(1);
return (new App\Notifications\InvoicePaid($invoice))
->toMail($invoice->user);
});