Qué son las notificaciones
El sistema de notificaciones de Laravel envía notificaciones a distintos canales (correo, SMS, Slack, base de datos, etc.) mediante una API unificada.
Diferencias entre Mail y Notification
| Comparación | Mail | Notification |
|---|
| Uso principal | Correos HTML enriquecidos | Notificaciones breves |
| Canales | Solo correo | Correo, base de datos, Slack, SMS, etc. |
| Plantillas | Totalmente libres | Formato de mensaje sencillo |
Cuando quieres enviar un mismo aviso por varios canales (por ejemplo, el pago de una factura confirmado), las Notifications son la opción idónea.
Crear una clase de notificación
Genera la clase con el comando Artisan make:notification.
php artisan make:notification InvoicePaid
Se ubica en app/Notifications/. Incluye el método via() y métodos para generar el mensaje por cada canal.
Cómo enviar notificaciones
Con el trait Notifiable
App\Models\User incluye por defecto el trait Notifiable. Envía notificaciones con el método notify().
use App\Notifications\InvoicePaid;
$user->notify(new InvoicePaid($invoice));
Puedes añadir Notifiable a cualquier modelo, no solo a User.
Con el facade Notification
Para enviar a varios usuarios a la vez, utiliza el facade Notification.
use Illuminate\Support\Facades\Notification;
Notification::send($users, new InvoicePaid($invoice));
Para enviar inmediatamente sin pasar por la cola, usa sendNow().
Notification::sendNow($developers, new DeploymentCompleted($deployment));
Indicar los canales
En el método via() devuelves un array con los canales que se van a usar.
public function via(object $notifiable): array
{
return ['mail', 'database'];
}
También puedes elegir canal según la preferencia del usuario.
public function via(object $notifiable): array
{
return $notifiable->prefers_sms ? ['vonage'] : ['mail', 'database'];
}
Canales principales disponibles:
| Canal | Clave | Descripción |
|---|
| Correo | mail | Envía la notificación por correo |
| Base de datos | database | La guarda en la BD para mostrarla en la interfaz |
| Broadcast | broadcast | Notificaciones en tiempo real (WebSocket) |
| SMS | vonage | Envío de SMS a través de Vonage (antes Nexmo) |
| Slack | slack | Publica en un canal de Slack |
Notificaciones por correo
En toMail() devuelve una instancia de MailMessage.
use Illuminate\Notifications\Messages\MailMessage;
public function toMail(object $notifiable): MailMessage
{
$url = url('/invoice/'.$this->invoice->id);
return (new MailMessage)
->greeting('¡Hola!')
->line('Hemos recibido el pago de tu factura.')
->action('Ver factura', $url)
->line('Gracias por confiar en nosotros.');
}
Métodos habituales de MailMessage:
| Método | Descripción |
|---|
greeting() | Saludo inicial |
line() | Una línea del cuerpo |
action() | Botón con enlace |
subject() | Asunto |
from() | Remitente |
mailer() | Mailer a utilizar |
Para notificar un error, añade error() y el botón cambia a rojo.
return (new MailMessage)
->error()
->subject('Ha fallado el pago')
->line('No se ha podido procesar el pago de la factura.');
}
Notificaciones de correo en Markdown
También puedes usar plantillas Markdown enriquecidas. Genera la clase con la opción --markdown.
php artisan make:notification InvoicePaid --markdown=mail.invoice.paid
Usa toMarkdownMail() en lugar de toMail().
use Illuminate\Notifications\Messages\MailMessage;
public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)
->markdown('mail.invoice.paid', [
'url' => url('/invoice/'.$this->invoice->id),
'invoice' => $this->invoice,
]);
}
Notificaciones en base de datos
El canal de base de datos guarda las notificaciones en la BD para mostrarlas en la interfaz de la aplicación.
Preparar la tabla
Crea la tabla notifications.
php artisan make:notifications-table
php artisan migrate
Definir toArray
Devuelve los datos a guardar como array desde toArray().
public function toArray(object $notifiable): array
{
return [
'invoice_id' => $this->invoice->id,
'amount' => $this->invoice->amount,
'message' => 'Hemos recibido el pago de tu factura.',
];
}
Estos datos se guardan como JSON en la columna data de la tabla notifications.
Obtener las notificaciones
Con la relación notifications del trait Notifiable puedes obtenerlas.
$user = App\Models\User::find(1);
foreach ($user->notifications as $notification) {
echo $notification->type;
echo $notification->data['message'];
}
Para las no leídas, utiliza unreadNotifications.
foreach ($user->unreadNotifications as $notification) {
echo $notification->data['message'];
}
Marcar como leídas
Con markAsRead() marcas la notificación como leída.
// De una en una
foreach ($user->unreadNotifications as $notification) {
$notification->markAsRead();
}
// Todas de golpe
$user->unreadNotifications->markAsRead();
// Actualizar en bloque con una query
$user->unreadNotifications()->update(['read_at' => now()]);
Notificaciones encoladas
Si el envío es lento, añade la interfaz ShouldQueue y el trait Queueable. La clase generada con make:notification ya los importa.
<?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;
// ...
}
Con ShouldQueue, al llamar a notify() la notificación se encola automáticamente.
$user->notify(new InvoicePaid($invoice));
Puedes retrasar el envío.
$user->notify(
(new InvoicePaid($invoice))->delay(now()->plus(minutes: 10))
);
Envío simultáneo a varios canales
Basta con devolver varios canales en via() y definir el método correspondiente a cada uno para enviar la misma notificación a varios canales a la vez.
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class InvoicePaid extends Notification implements ShouldQueue
{
use Queueable;
public function __construct(
private readonly Invoice $invoice,
) {}
public function via(object $notifiable): array
{
// Enviar tanto por correo como a la base de datos
return ['mail', 'database'];
}
public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)
->subject('Hemos recibido el pago de tu factura')
->line('Se ha confirmado el pago de la factura #'.$this->invoice->id.'.')
->action('Ver factura', url('/invoice/'.$this->invoice->id));
}
public function toArray(object $notifiable): array
{
return [
'invoice_id' => $this->invoice->id,
'amount' => $this->invoice->amount,
];
}
}
Notificaciones bajo demanda
Para notificar a usuarios que no tienen cuenta en la aplicación, utiliza Notification::route().
use Illuminate\Support\Facades\Notification;
Notification::route('mail', '[email protected]')
->route('vonage', '5555551212')
->notify(new InvoicePaid($invoice));
Resumen
| Objetivo | Cómo hacerlo |
|---|
| Crear una notificación | php artisan make:notification ClassName |
| Notificar a un usuario | $user->notify(new MyNotification()) |
| Notificar a varios usuarios | Notification::send($users, new MyNotification()) |
| Enviar por correo | Devuelve mail en via() y define toMail() |
| Guardar en BD | Devuelve database en via() y define toArray() |
| Enviar de forma asíncrona | Implementa ShouldQueue |
| Enviar a varios canales | Devuelve varias claves en via() |