Saltar contenido

Notificaciones

Introducción

Además de soporte para el envío de emails, Laravel proporciona soporte para el envío de notificaciones a través de una variedad de canales, incluyendo email, SMS (a través de Vonage, anteriormente conocido como Nexmo), y Slack. Además, existe una gran variedad de canales de notificación construidos por la comunidad para enviar notificaciones a través de docenas de canales diferentes. Las notificaciones también pueden almacenarse en una base de datos para que puedan mostrarse en su interfaz web.

Normalmente, las notificaciones son mensajes cortos e informativos que avisen a los usuarios de algo que ha ocurrido en tu aplicación. Por ejemplo, si estás escribiendo una aplicación de facturación, podrías enviar una notificación de "Factura pagada" a tus usuarios a través de los canales de email y SMS.

Generación de Notificaciones

En Laravel, cada notificación está representada por una única clase que normalmente se almacena en el directorio app/Notifications. No te preocupes si no ves este directorio en tu aplicación - será creado para automaticamente cuando ejecutes el comando make:notification Artisan:

php artisan make:notification InvoicePaid

Este comando colocará una nueva clase de notificación en el directorio app/Notifications. Cada clase de notificación contiene un método via y un número variable de métodos de construcción de mensajes, como toMail o toDatabase, que convierten la notificación en un mensaje adaptado a ese canal en particular.

Envío de notificaciones

Uso del Rasgo Notificable

Las notificaciones pueden enviarse de dos formas: utilizando el método notify del trait Notifiable o utilizando la facade Notification. El trait Notifiable se incluye por defecto en el modelo App\Models\User de su aplicación:

<?php
 
namespace App\Models;
 
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
 
class User extends Authenticatable
{
use Notifiable;
}

El método notify que proporciona este trait espera recibir una instancia de notificación:

use App\Notifications\InvoicePaid;
 
$user->notify(new InvoicePaid($invoice));

Nota
Recuerda que puedes utilizar el trait Notifiable en cualquiera de tus modelos. No estás limitado a incluirlo sólo en tu modelo de User.

Uso de la facade de notificación

De manera alternativa, puede enviar notificaciones a través de la facade Notification. Este enfoque es útil cuando se necesita enviar una notificación a múltiples entidades notificables, como una colección de usuarios. Para enviar notificaciones utilizando la facade, pasa todas las entidades notificables y la instancia de notificación al método send:

use Illuminate\Support\Facades\Notification;
 
Notification::send($users, new InvoicePaid($invoice));

También puedes enviar notificaciones inmediatamente utilizando el método sendNow. Este método enviará la notificación inmediatamente incluso si la notificación implementa la interfaz ShouldQueue:

Notification::sendNow($developers, new DeploymentCompleted($deployment));

Especificación de Canales de Entrega

Cada clase de notificación tiene un método via que determina en qué canales se enviará la notificación. Las notificaciones pueden enviarse a través de los canales mail, database, broadcast, vonage y slack.

Nota
Si quieres utilizar otros canales de envío como Telegram o Pusher, consulta el sitio web de la comunidad Laravel Notification Channels.

El método via recibe una instancia $notifiable, que será una instancia de la clase a la que se está enviando la notificación. Puede utilizar $notifiable para determinar en qué canales debe enviarse la notificación:

/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return $notifiable->prefers_sms ? ['vonage'] : ['mail', 'database'];
}

Puesta en cola de notificaciones

Advertencia
Antes de poner notificaciones en cola deberías configurar tu cola e iniciar un worker.

El envío de notificaciones puede llevar tiempo, especialmente si el canal necesita hacer una llamada a una API externa para entregar la notificación. Para acelerar el tiempo de respuesta de tu aplicación, manda tu notificación a la cola añadiendo la interfaz ShouldQueue y el trait Queueable a tu clase. La interfaz y el trait ya están importados para todas las notificaciones generadas mediante el comando make:notification, por lo que puedes añadirlos inmediatamente a tu clase de notificación:

<?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;
 
// ...
}

Una vez que la interfaz ShouldQueue ha sido añadida a tu notificación, puedes enviar la notificación de forma normal. Laravel detectará la interfaz ShouldQueue en la clase y automáticamente pondrá en cola la entrega de la notificación:

$user->notify(new InvoicePaid($invoice));

Al poner en cola las notificaciones, se creará un trabajo en cola para cada combinación de destinatario y canal. Por ejemplo, seis trabajos serán enviados a la cola si tu notificación tiene tres destinatarios y dos canales.

Retrasar notificaciones

Si desea retrasar la entrega de la notificación, puede encadenar el método de delay en su instanciación de notificación:

$delay = now()->addMinutes(10);
 
$user->notify((new InvoicePaid($invoice))->delay($delay));

Retrasar notificaciones por canal

Puede pasar un array al método delay para especificar cuanto desea retrasar la notificación para un canal específico:

$user->notify((new InvoicePaid($invoice))->delay([
'mail' => now()->addMinutes(5),
'sms' => now()->addMinutes(10),
]));

De manera alternativa, puede definir un método withDelay en la propia clase de notificación. El método withDelay debe devolver un array de nombres de canales y valores de retardo:

/**
* Determine the notification's delivery delay.
*
* @param mixed $notifiable
* @return array
*/
public function withDelay($notifiable)
{
return [
'mail' => now()->addMinutes(5),
'sms' => now()->addMinutes(10),
];
}

Personalización de la conexión de la cola de notificaciones

Por defecto, las notificaciones en cola se encolarán utilizando la conexión de cola por defecto de su aplicación. Si desea especificar una conexión diferente para una notificación en particular, puede definir una propiedad $connection en la clase de notificación:

/**
* The name of the queue connection to use when queueing the notification.
*
* @var string
*/
public $connection = 'redis';

O, si desea especificar una conexión de cola específica que se debe utilizar para cada canal de notificación soportado por la notificación, puede definir un método viaConnections en su notificación. Este método debe devolver un array de pares nombre de canal / nombre de conexión de cola:

/**
* Determine which connections should be used for each notification channel.
*
* @return array
*/
public function viaConnections()
{
return [
'mail' => 'redis',
'database' => 'sync',
];
}

Personalización de colas de canales de notificación

Si desea especificar una cola específica que debe utilizarse para cada canal de notificación soportado por la notificación, puede definir un método viaQueues en su notificación. Este método debe devolver un array de pares nombre de canal / nombre de cola:

/**
* Determine which queues should be used for each notification channel.
*
* @return array
*/
public function viaQueues()
{
return [
'mail' => 'mail-queue',
'slack' => 'slack-queue',
];
}

Notificaciones en cola y transacciones de base de datos

Cuando las notificaciones en cola se envían dentro de transacciones de base de datos, pueden ser procesadas por la cola antes de que la transacción de base de datos se haya "commiteado". Cuando esto ocurre, cualquier actualización que haya realizado en los modelos o registros de la base de datos durante la transacción de la base de datos puede no reflejarse todavía en la base de datos. Además, es posible que los modelos o registros de base de datos creados durante la transacción no existan en la base de datos. Si su notificación depende de estos modelos, pueden producirse errores inesperados cuando se procese el trabajo que envía la notificación en cola.

Si la opción de configuración after_commit de su conexión de cola está establecida en false, puede indicar que una notificación en cola concreta debe enviarse después de que todas las transacciones de base de datos abiertas se hayan consignado llamando al método afterCommit al enviar la notificación:

use App\Notifications\InvoicePaid;
 
$user->notify((new InvoicePaid($invoice))->afterCommit());

De manera alternativa, puede llamar al método afterCommit desde el constructor de su notificación:

<?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;
 
/**
* Create a new notification instance.
*
* @return void
*/
public function __construct()
{
$this->afterCommit();
}
}

Nota
Para obtener más información sobre cómo solucionar estos problemas, consulte la documentación relativa a los trabajos en cola y las transacciones de base de datos.

Cómo determinar si se debe enviar una notificación en cola

Después de que una notificación en cola haya sido enviada a la cola para su procesamiento en segundo plano, normalmente será aceptada por un trabajador de la cola y enviada a su destinatario.

Sin embargo, si deseas tomar la decisión final sobre si la notificación en cola debe ser enviada después de ser procesada por un trabajador de la cola, puedes definir un método shouldSend en la clase de notificación. Si este método devuelve false, la notificación no se enviará:

/**
* Determine if the notification should be sent.
*
* @param mixed $notifiable
* @param string $channel
* @return bool
*/
public function shouldSend($notifiable, $channel)
{
return $this->invoice->isPaid();
}

Notificaciones bajo demanda

A veces puedes necesitar enviar una notificación a alguien que no está almacenado como "usuario" de tu aplicación. Utilizando el método route de la facade Notification, puedes especificar información de enrutamiento de notificaciones ad-hoc antes de enviar la notificación:

use Illuminate\Broadcasting\Channel;
 
Notification::route('mail', 'taylor@example.com')
->route('vonage', '5555555555')
->route('slack', 'https://hooks.slack.com/services/...')
->route('broadcast', [new Channel('channel-name')])
->notify(new InvoicePaid($invoice));

Si quieres proporcionar el nombre del destinatario al enviar una notificación bajo demanda a la ruta de mail, puedes proporcionar un array que contenga la dirección de email como clave y el nombre como valor del primer elemento del array:

Notification::route('mail', [
'barrett@example.com' => 'Barrett Blair',
])->notify(new InvoicePaid($invoice));

Notificaciones por correo

Formateo de Mensajes de Correo

Si una notificación admite ser enviada como un email, debe definir un método toMail en la clase de notificación. Este método recibirá una entidad $notifiable y devolverá una instancia Illuminate\Notifications\Messages\MailMessage.

La clase MailMessage contiene algunos métodos sencillos para ayudarle a construir mensajes de email transaccionales. Los mensajes de correo pueden contener líneas de texto, así como una "llamada a la acción". Veamos un ejemplo del método toMail:

/**
* 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!')
->lineIf($this->amount > 0, "Amount paid: {$this->amount}")
->action('View Invoice', $url)
->line('Thank you for using our application!');
}

Nota
Nota estamos usando $this->invoice->id en nuestro método toMail. Puedes pasar cualquier dato que tu notificación necesite para generar su mensaje en el constructor de la notificación.

En este ejemplo, registramos un saludo, una línea de texto, una llamada a la acción, y luego otra línea de texto. Estos métodos proporcionados por el objeto MailMessage hacen que sea sencillo y rápido dar formato a pequeños correos electrónicos transaccionales. A continuación, el canal de correo traducirá los componentes del mensaje en una bonita plantilla de email HTML con una contrapartida de texto sin formato. A continuación se muestra un ejemplo de un email generado por el canal de mail:

Nota
Cuando envíe notificaciones por correo, asegúrese de establecer la opción de configuración name en su archivo de configuración config/app.php. Este valor se utilizará en la cabecera y el pie de página de sus mensajes de notificación por correo.

Mensajes de error

Algunas notificaciones informan a los usuarios de errores, como el pago fallido de una factura. Puede indicar que un mensaje de correo se refiere a un error llamando al método error cuando construya su mensaje. Cuando utilice el método de error en un mensaje de correo, el botón de llamada a la acción será rojo en lugar de negro:

/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->error()
->subject('Invoice Payment Failed')
->line('...');
}

Otras opciones de formato de las notificaciones de correo

En lugar de definir las "líneas" de texto en la clase de notificación, puede utilizar el método view para especificar una plantilla personalizada que debe utilizarse para renderizar el email de notificación:

/**
* 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]
);
}

Puede especificar una vista de texto plano para el mensaje de correo pasando el nombre de la vista como segundo elemento de una array que se proporciona al método view:

/**
* 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]
);
}

Personalización del remitente

Por defecto, la dirección del remitente del email se define en el archivo de configuración config/mail.php. Sin embargo, puede especificar la dirección del remitente para una notificación específica utilizando el método from:

/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->from('barrett@example.com', 'Barrett Blair')
->line('...');
}

Personalización del destinatario

Al enviar notificaciones a través del canal de mail, el sistema de notificación buscará automáticamente una propiedad de email electrónico en su entidad notificable. Puede personalizar qué email se utiliza para enviar la notificación definiendo un método routeNotificationForMail en la entidad notificable:

<?php
 
namespace App\Models;
 
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 email address and name...
return [$this->email_address => $this->name];
}
}

Personalización del asunto

Por defecto, el asunto del email es el nombre de la clase de notificación formateado a "Title Case". Así, si su clase de notificación se llama InvoicePaid, el asunto del email será Invoice Paid. Si desea especificar un asunto diferente para el mensaje, puede llamar al método subject cuando construya su mensaje:

/**
* 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('...');
}

Personalización del remitente

Por defecto, la notificación por email se enviará utilizando el mailer por defecto definido en el archivo de configuración config/mail.php. Sin embargo, puede especificar un mailer diferente en tiempo de ejecución llamando al método mailer cuando construya su mensaje:

/**
* 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('...');
}

s

Personalización de las plantillas

Puede modificar la plantilla HTML y el texto plano utilizado por las notificaciones de correo publicando los recursos del paquete de notificaciones. Tras ejecutar este comando, las plantillas de notificaciones por correo se ubicarán en el directorio resources/views/vendor/notifications:

php artisan vendor:publish --tag=laravel-notifications

Adjuntos

Para añadir archivos adjuntos a una notificación por email, utilice el método attach al crear el mensaje. El método attach acepta la ruta absoluta al archivo como primer argumento:

/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->greeting('Hello!')
->attach('/path/to/file');
}

Nota
El método attach que ofrecen los mensajes de correo de notificación también acepta objetos adjuntables. Para más información, consulta la completa documentación sobre objetos adjuntables.

Al adjuntar archivos a un mensaje, también puede especificar el nombre para mostrar y/o el tipo MIME pasando una array como segundo argumento al método attach:

/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->greeting('Hello!')
->attach('/path/to/file', [
'as' => 'name.pdf',
'mime' => 'application/pdf',
]);
}

A diferencia de lo que ocurre al adjuntar archivos en objetos enviables por correo, no puedes adjuntar un archivo directamente desde un disco de almacenamiento utilizando attachFromStorage. Debe utilizar el método attach con una ruta absoluta al archivo en el disco de almacenamiento. De manera alternativa, puedes devolver un mailable desde el método toMail:

use App\Mail\InvoicePaid as InvoicePaidMailable;
 
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return Mailable
*/
public function toMail($notifiable)
{
return (new InvoicePaidMailable($this->invoice))
->to($notifiable->email)
->attachFromStorage('/path/to/file');
}

Cuando sea necesario, se pueden adjuntar varios archivos a un mensaje utilizando el método attachMany:

/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->greeting('Hello!')
->attachMany([
'/path/to/forge.svg',
'/path/to/vapor.svg' => [
'as' => 'Logo.svg',
'mime' => 'image/svg+xml',
],
]);
}

Archivos adjuntos de datos sin procesar

El método attachData puede utilizarse para adjuntar una cadena de bytes sin procesar. Cuando se llama al método attachData, se debe proporcionar el nombre de archivo que se debe asignar al adjunto:

/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->greeting('Hello!')
->attachData($this->pdf, 'name.pdf', [
'mime' => 'application/pdf',
]);
}

Añadir etiquetas y metadatos

Algunos proveedores de correo de terceros como Mailgun y Postmark soportan "etiquetas" y "metadatos" de mensajes, que pueden ser utilizados para agrupar y rastrear los correos electrónicos enviados por su aplicación. Puede añadir etiquetas y metadatos a un mensaje de email mediante los métodos tag y metadata:

/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->greeting('Comment Upvoted!')
->tag('upvote')
->metadata('comment_id', $this->comment->id);
}

Si su aplicación utiliza el controlador Mailgun, puede consultar la documentación de Mailgun para obtener más información sobre etiquetas y metadatos. Del mismo modo, también puede consultar la documentación de Postmark para obtener más información sobre su compatibilidad con etiquetas y metadatos.

Si su aplicación utiliza Amazon SES para enviar correos electrónicos, debe utilizar el método de metadata para adjuntar "etiquetas" SES al mensaje.

Personalización del mensaje Symfony

El método withSymfonyMessage de la clase MailMessage permite registrar un closure que se invocará con la instancia de Symfony Message antes de enviar el mensaje. Esto te da la oportunidad de personalizar profundamente el mensaje antes de que se entregue:

use Symfony\Component\Mime\Email;
 
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->withSymfonyMessage(function (Email $message) {
$message->getHeaders()->addTextHeader(
'Custom-Header', 'Header Value'
);
});
}

Uso de Mailables

Si es necesario, puede devolver un objeto mailable completo desde el método toMail de su notificación. Si devuelve un Mailable en lugar de un MailMessage, deberá especificar el destinatario del mensaje mediante el método to del objeto mailable:

use App\Mail\InvoicePaid as InvoicePaidMailable;
 
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return Mailable
*/
public function toMail($notifiable)
{
return (new InvoicePaidMailable($this->invoice))
->to($notifiable->email);
}

Mailables y notificaciones bajo demanda

Si está enviando una notificación bajo demanda, la instancia $notifiable dada al método toMail será una instancia de Illuminate\Notifications\AnonymousNotifiable, que ofrece un método routeNotificationFor que puede utilizarse para recuperar la dirección de email a la que debe enviarse la notificación bajo demanda:

use App\Mail\InvoicePaid as InvoicePaidMailable;
use Illuminate\Notifications\AnonymousNotifiable;
 
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return Mailable
*/
public function toMail($notifiable)
{
$address = $notifiable instanceof AnonymousNotifiable
? $notifiable->routeNotificationFor('mail')
: $notifiable->email;
 
return (new InvoicePaidMailable($this->invoice))
->to($address);
}

Vista previa de las notificaciones por correo

Al diseñar una plantilla de notificación de correo, es conveniente previsualizar rápidamente el mensaje de correo renderizado en el navegador como una plantilla típica de Blade. Por esta razón, Laravel permite devolver cualquier mensaje de correo generado por una notificación de correo directamente desde un closure ruta o controlador. Cuando un MailMessage es devuelto, será renderizado y mostrado en el navegador, permitiéndote previsualizar rápidamente su diseño sin necesidad de enviarlo a una dirección de correo real:

use App\Models\Invoice;
use App\Notifications\InvoicePaid;
 
Route::get('/notification', function () {
$invoice = Invoice::find(1);
 
return (new InvoicePaid($invoice))
->toMail($invoice->user);
});

Notificaciones de correo Markdown

Las notificaciones de correo Markdown le permiten aprovechar las plantillas preconstruidas de las notificaciones de correo, a la vez que le dan más libertad para escribir mensajes más largos y personalizados. Dado que los mensajes están escritos en Markdown, Laravel es capaz de renderizar plantillas HTML hermosas y responsivas para los mensajes, al mismo tiempo que genera automáticamente una contraparte en texto plano.

Generación del mensaje

Para generar una notificación con su correspondiente plantilla Markdown, puedes utilizar la opción --markdown del comando make:notification Artisan:

php artisan make:notification InvoicePaid --markdown=mail.invoice.paid

Al igual que el resto de notificaciones de correo, las notificaciones que utilizan plantillas Markdown deben definir un método toMail en su clase de notificación. Sin embargo, en lugar de utilizar los métodos line y action para construir la notificación, utilice el método markdown para especificar el nombre de la plantilla Markdown que debe utilizarse. Como segundo argumento del método puede pasarse un array de datos que desee poner a disposición de la plantilla:

/**
* 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)
->subject('Invoice Paid')
->markdown('mail.invoice.paid', ['url' => $url]);
}

Redacción del mensaje

Las notificaciones de correo Markdown utilizan una combinación de componentes Blade y sintaxis Markdown que le permiten construir fácilmente notificaciones mientras aprovecha los componentes de notificación preelaborados de Laravel:

<x-mail::message>
# Invoice Paid
 
Your invoice has been paid!
 
<x-mail::button :url="$url">
View Invoice
</x-mail::button>
 
Thanks,<br>
{{ config('app.name') }}
</x-mail::message>

Componente de botón

El componente de botón muestra un enlace de botón centrado. El componente acepta dos argumentos, una url y un color opcional. Los colores soportados son primary, green, y red. Puede añadir tantos componentes de botón a una notificación como desee:

<x-mail::button :url="$url" color="green">
View Invoice
</x-mail::button>

Componente de panel

El componente panel muestra el bloque de texto en un panel con un color de fondo ligeramente distinto al del resto de la notificación. Esto le permite llamar la atención sobre un bloque de texto determinado:

<x-mail::panel>
This is the panel content.
</x-mail::panel>

Componente de tabla

El componente tabla permite transformar una tabla Markdown en una tabla HTML. El componente acepta la tabla Markdown como contenido. La alineación de las columnas de la tabla se realiza utilizando la sintaxis predeterminada de alineación de tablas de Markdown:

<x-mail::table>
| Laravel | Table | Example |
| ------------- |:-------------:| --------:|
| Col 2 is | Centered | $10 |
| Col 3 is | Right-Aligned | $20 |
</x-mail::table>

Personalización de los componentes

Puede exportar todos los componentes de notificación Markdown a su propia aplicación para personalizarlos. Para exportar los componentes, utilice el comando vendor:publish Artisan para publicar la etiqueta asset laravel-mail:

php artisan vendor:publish --tag=laravel-mail

Este comando publicará los componentes de correo Markdown en el directorio resources/views/vendor/mail. El directorio mail contendrá un directorio html y un directorio text, cada uno con sus respectivas representaciones de cada componente disponible. Puede personalizar estos componentes como desee.

Personalizar el CSS

Después de exportar los componentes, el directorio resources/views/vendor/mail/html/themes contendrá un archivo default.css. Puede personalizar el CSS de este archivo y sus estilos se incluirán automáticamente en las representaciones HTML de sus notificaciones Markdown.

Si deseas construir un tema completamente nuevo para los componentes Markdown de Laravel, puedes colocar un archivo CSS dentro del directorio html/themes. Después de nombrar y guardar su archivo CSS, actualice la opción de theme del archivo de configuración de mail para que coincida con el nombre de su nuevo tema.

Para personalizar el tema de una notificación individual, puede llamar al método del theme mientras crea el mensaje de correo de la notificación. El método de theme acepta el nombre del tema que debe utilizarse al enviar la notificación:

/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->theme('invoice')
->subject('Invoice Paid')
->markdown('mail.invoice.paid', ['url' => $url]);
}

Notificaciones de base de datos

Requisitos previos

El canal de notificación de database almacena la información de la notificación en una tabla de base de datos. Esta tabla contendrá información como el tipo de notificación, así como una estructura de datos JSON que describe la notificación.

Puede consultar la tabla para mostrar las notificaciones en la interfaz de usuario de su aplicación. Pero, antes de que pueda hacer eso, necesitará crear una tabla de base de datos para contener sus notificaciones. Puede utilizar el comando notifications:table para generar una migración con el esquema de tabla adecuado:

php artisan notifications:table
 
php artisan migrate

Formateo de las Notificaciones de la Base de Datos

Si una notificación soporta ser almacenada en una tabla de base de datos, debes definir un método toDatabase o toArray en la clase de notificación. Este método recibirá una entidad $notifiable y devolverá un array PHP plano. El array devuelto será codificado como JSON y almacenado en la columna de data de tu tabla de notifications. Veamos un ejemplo del método toArray:

/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
* @return array
*/
public function toArray($notifiable)
{
return [
'invoice_id' => $this->invoice->id,
'amount' => $this->invoice->amount,
];
}

toDatabase Vs. toArray

El método toArray también es utilizado por el canal de broadcast para determinar qué datos difundir a su frontend con JavaScript. Si desea tener dos representaciones de array diferentes para los canales database y broadcast, debe definir un método toDatabase en lugar de un método toArray.

Acceso a las notificaciones

Una vez almacenadas las notificaciones en la base de datos, necesitará una forma cómoda de acceder a ellas desde sus entidades notificables. El trait Illuminate\Notifications\Notifiable, que se incluye en el modelo App\Models\User por defecto de Laravel, incluye una relación Eloquent llamada notifications que devuelve las notificaciones de la entidad. Para obtener notificaciones, puedes acceder a este método como a cualquier otra relación Eloquent. Por defecto, las notificaciones se ordenarán por la fecha de creación (created_at) con las notificaciones más recientes al principio de la colección:

$user = App\Models\User::find(1);
 
foreach ($user->notifications as $notification) {
echo $notification->type;
}

Si desea recuperar sólo las notificaciones "no leídas", puede utilizar la relación unreadNotifications. De nuevo, estas notificaciones se ordenarán por la columna created_at, con las notificaciones más recientes al principio de la colección:

$user = App\Models\User::find(1);
 
foreach ($user->unreadNotifications as $notification) {
echo $notification->type;
}

Nota
Para acceder a tus notificaciones desde tu cliente JavaScript, debes definir un controlador de notificaciones para tu aplicación que devuelva las notificaciones para una entidad notificable, como el usuario actual. A continuación, puede realizar una solicitud HTTP a la URL de ese controlador desde su cliente JavaScript.

Marcar Notificaciones como Leídas

Normalmente, querrá marcar una notificación como "leída" cuando un usuario la vea. El trait Illuminate\Notifications\Notifiable proporciona un método markAsRead, que actualiza la columna read_at en el registro de base de datos de la notificación:

$user = App\Models\User::find(1);
 
foreach ($user->unreadNotifications as $notification) {
$notification->markAsRead();
}

Sin embargo, en lugar de recorrer cada notificación, puede utilizar el método markAsRead directamente en una colección de notificaciones:

$user->unreadNotifications->markAsRead();

También puede utilizar una consulta de actualización masiva para marcar todas las notificaciones como leídas sin recuperarlas de la base de datos:

$user = App\Models\User::find(1);
 
$user->unreadNotifications()->update(['read_at' => now()]);

Puede borrar las notificaciones para eliminarlas completamente de la tabla usando el método delete:

$user->notifications()->delete();

Notificaciones Broadcast

Requisitos previos

Antes de difundir las notificaciones, debe configurar y estar familiarizado con los servicios de difusión de eventos (event broadcasting) de Laravel. La difusión de eventos proporciona una manera de reaccionar a los eventos de Laravel del lado del servidor desde su frontend con JavaScript.

Formato de notificaciones Broadcast

El canal de broadcast difunde notificaciones utilizando los servicios de event broadcasting de Laravel, lo que permite a tu frontend con JavaScript recibir notificaciones en tiempo real. Si una notificación soporta broadcasting, puedes definir un método toBroadcast en la clase de notificación. Este método recibirá una entidad $notifiable y devolverá una instancia de BroadcastMessage. Si el método toBroadcast no existe, se utilizará el método toArray para recoger los datos que deben ser difundidos. Los datos devueltos se codificarán como JSON y se transmitirán a su frontend con JavaScript. Veamos un ejemplo del método toBroadcast:

use Illuminate\Notifications\Messages\BroadcastMessage;
 
/**
* Get the broadcastable representation of the notification.
*
* @param mixed $notifiable
* @return BroadcastMessage
*/
public function toBroadcast($notifiable)
{
return new BroadcastMessage([
'invoice_id' => $this->invoice->id,
'amount' => $this->invoice->amount,
]);
}

Configuración de la cola de Broadcast

Todas las notificaciones broadcast se ponen en cola para su difusión. Si desea configurar la conexión de la cola o el nombre de la cola que se utilizará, puede utilizar los métodos onConnection y onQueue de BroadcastMessage:

return (new BroadcastMessage($data))
->onConnection('sqs')
->onQueue('broadcasts');

Personalización del tipo de notificación

Además de los datos que especifique, todas las notificaciones broadcast también tienen un campo de type que contiene el nombre completo de la clase de la notificación. Si desea personalizar el tipo de notificación, puede definir un método broadcastType en la clase de notificación:

use Illuminate\Notifications\Messages\BroadcastMessage;
 
/**
* Get the type of the notification being broadcast.
*
* @return string
*/
public function broadcastType()
{
return 'broadcast.message';
}

Escucha de notificaciones

Las notificaciones se emitirán en un canal privado formateado utilizando la convención {notifiable}.{id}. Por lo tanto, si está enviando una notificación a una instancia de App.Models.User con un ID de 1, la notificación se emitirá en el canal privado App.Models.User.1. Cuando se utiliza Laravel Echo, puede escuchar fácilmente las notificaciones en un canal utilizando el método de notification:

Echo.private('App.Models.User.' + userId)
.notification((notification) => {
console.log(notification.type);
});

Personalización del canal de notificación

Si desea personalizar el canal por el que se emiten las notificaciones de una entidad, puede definir un método receivesBroadcastNotificationsOn en la entidad notificable:

<?php
 
namespace App\Models;
 
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
 
class User extends Authenticatable
{
use Notifiable;
 
/**
* The channels the user receives notification broadcasts on.
*
* @return string
*/
public function receivesBroadcastNotificationsOn()
{
return 'users.'.$this->id;
}
}

Notificaciones SMS

Requisitos previos

El envío de notificaciones SMS en Laravel es impulsado por Vonage (anteriormente conocido como Nexmo). Antes de poder enviar notificaciones a través de Vonage, necesitas instalar los paquetes laravel/vonage-notification-channel y guzzlehttp/guzzle:

composer require laravel/vonage-notification-channel guzzlehttp/guzzle

El paquete incluye un archivo de configuración. Sin embargo, no es necesario que exportes este archivo de configuración a tu propia aplicación. Puedes simplemente utilizar las variables de entorno VONAGE_KEY y VONAGE_SECRET para definir tus claves públicas y secretas de Vonage.

Después de definir sus claves, puede establecer una variable de entorno VONAGE_SMS_FROM que defina el número de teléfono desde el que se enviarán sus mensajes SMS por defecto. Puedes generar este número de teléfono dentro del panel de control de Vonage:

VONAGE_SMS_FROM=15556666666

Formateo de notificaciones SMS

Si una notificación admite el envío como SMS, debes definir un método toVonage en la clase de notificación. Este método recibirá una entidad $notifiable y devolverá una instancia Illuminate\Notifications\Messages\VonageMessage:

/**
* Get the Vonage / SMS representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\VonageMessage
*/
public function toVonage($notifiable)
{
return (new VonageMessage)
->content('Your SMS message content');
}

Contenido Unicode

Si tu mensaje SMS contiene caracteres unicode, deberás llamar al método unicode cuando construyas la instancia de VonageMessage:

/**
* Get the Vonage / SMS representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\VonageMessage
*/
public function toVonage($notifiable)
{
return (new VonageMessage)
->content('Your unicode message')
->unicode();
}

Personalización del número "Desde"

Si deseas enviar algunas notificaciones desde un número de teléfono que es diferente del número de teléfono especificado por tu variable de entorno VONAGE_SMS_FROM, puedes llamar al método from en una instancia de VonageMessage:

/**
* Get the Vonage / SMS representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\VonageMessage
*/
public function toVonage($notifiable)
{
return (new VonageMessage)
->content('Your SMS message content')
->from('15554443333');
}

Cómo agregar una referencia de cliente

Si deseas realizar un seguimiento de los costos por usuario, equipo o cliente, puedes agregar una "referencia de cliente" a la notificación. Vonage te permitirá generar informes usando esta referencia de cliente para que puedas comprender mejor el uso de SMS de un cliente en particular. La referencia del cliente puede ser cualquier cadena de hasta 40 caracteres:

/**
* Get the Vonage / SMS representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\VonageMessage
*/
public function toVonage($notifiable)
{
return (new VonageMessage)
->clientReference((string) $notifiable->id)
->content('Your SMS message content');
}

Enrutamiento de notificaciones SMS

Para dirigir las notificaciones de Vonage al número de teléfono correcto, define un método routeNotificationForVonage en tu entidad notificable:

<?php
 
namespace App\Models;
 
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
 
class User extends Authenticatable
{
use Notifiable;
 
/**
* Route notifications for the Vonage channel.
*
* @param \Illuminate\Notifications\Notification $notification
* @return string
*/
public function routeNotificationForVonage($notification)
{
return $this->phone_number;
}
}

Notificaciones Slack

Requisitos previos

Antes de poder enviar notificaciones a través de Slack, debes instalar el canal de notificaciones de Slack a través de Composer:

composer require laravel/slack-notification-channel

También deberás crear una aplicación Slack para tu equipo. Después de crear la aplicación, debes configurar un "Incoming Webhook" para el área de trabajo. Slack le proporcionará una URL de webhook que podrá utilizar para enviar las notificaciones de Slack.

Formateo de notificaciones Slack

Si una notificación admite ser enviada como un mensaje de Slack, debe definir un método toSlack en la clase de notificación. Este método recibirá una entidad $notifiable y devolverá una instancia Illuminate\Notifications\Messages\SlackMessage. Los mensajes de Slack pueden contener contenido de texto, así como un "adjunto" que formatea texto adicional o una array de campos. Veamos un ejemplo básico de toSlack:

/**
* Get the Slack representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\SlackMessage
*/
public function toSlack($notifiable)
{
return (new SlackMessage)
->content('One of your invoices has been paid!');
}

Adjuntos de Slack

También puede añadir "archivos adjuntos" a los mensajes de Slack. Los archivos adjuntos proporcionan opciones de formato más ricas que los simples mensajes de texto. En este ejemplo, enviaremos una notificación de error sobre una excepción que se ha producido en una aplicación, incluyendo un enlace para ver más detalles sobre la excepción:

/**
* Get the Slack representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\SlackMessage
*/
public function toSlack($notifiable)
{
$url = url('/exceptions/'.$this->exception->id);
 
return (new SlackMessage)
->error()
->content('Whoops! Something went wrong.')
->attachment(function ($attachment) use ($url) {
$attachment->title('Exception: File Not Found', $url)
->content('File [background.jpg] was not found.');
});
}

Los archivos adjuntos también permiten especificar una array de datos que deben presentarse al usuario. Los datos proporcionados se presentarán en un formato tipo tabla para facilitar su lectura:

/**
* Get the Slack representation of the notification.
*
* @param mixed $notifiable
* @return SlackMessage
*/
public function toSlack($notifiable)
{
$url = url('/invoices/'.$this->invoice->id);
 
return (new SlackMessage)
->success()
->content('One of your invoices has been paid!')
->attachment(function ($attachment) use ($url) {
$attachment->title('Invoice 1322', $url)
->fields([
'Title' => 'Server Expenses',
'Amount' => '$1,234',
'Via' => 'American Express',
'Was Overdue' => ':-1:',
]);
});
}

Markdown Attachment Content

Si algunos de sus campos adjuntos contienen Markdown, puede utilizar el método markdown para indicar a Slack que analice y muestre los campos adjuntos dados como texto con formato Markdown. Los valores aceptados por este método son: pretext, text, y/o fields. Para más información sobre el formato de los adjuntos de Slack, consulte la documentación de la API de Slack:

/**
* Get the Slack representation of the notification.
*
* @param mixed $notifiable
* @return SlackMessage
*/
public function toSlack($notifiable)
{
$url = url('/exceptions/'.$this->exception->id);
 
return (new SlackMessage)
->error()
->content('Whoops! Something went wrong.')
->attachment(function ($attachment) use ($url) {
$attachment->title('Exception: File Not Found', $url)
->content('File [background.jpg] was *not found*.')
->markdown(['text']);
});
}

Enrutamiento de notificaciones de Slack

Para dirigir las notificaciones de Slack al equipo y canal de Slack adecuados, defina un método routeNotificationForSlack en su entidad notificable. Esto debería devolver la URL webhook a la que la notificación debe ser entregada. Las URL de webhook pueden generarse añadiendo un servicio "Incoming Webhook" a su equipo de Slack:

<?php
 
namespace App\Models;
 
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
 
class User extends Authenticatable
{
use Notifiable;
 
/**
* Route notifications for the Slack channel.
*
* @param \Illuminate\Notifications\Notification $notification
* @return string
*/
public function routeNotificationForSlack($notification)
{
return 'https://hooks.slack.com/services/...';
}
}

Localización de notificaciones

Laravel permite enviar notificaciones en una configuración regional distinta de la configuración regional actual de la petición HTTP, e incluso recordará esta configuración regional si la notificación se pone en cola.

Para ello, la clase Illuminate\Notifications\Notification ofrece un método locale para establecer el idioma deseado. La aplicación cambiará a esta configuración regional cuando se esté evaluando la notificación y luego volverá a la configuración regional anterior cuando finalice la evaluación:

$user->notify((new InvoicePaid($invoice))->locale('es'));

La localización de múltiples entradas notificables también puede lograrse a través de la facade Notification:

Notification::locale('es')->send(
$users, new InvoicePaid($invoice)
);

Idiomas preferidos por el usuario

A veces, las aplicaciones almacenan la configuración regional preferida de cada usuario. Implementando el contrato HasLocalePreference en tu modelo de notificación, puedes indicar a Laravel que utilice esta configuración regional almacenada cuando envíe una notificación:

use Illuminate\Contracts\Translation\HasLocalePreference;
 
class User extends Model implements HasLocalePreference
{
/**
* Get the user's preferred locale.
*
* @return string
*/
public function preferredLocale()
{
return $this->locale;
}
}

Una vez implementada la interfaz, Laravel utilizará automáticamente la configuración regional preferida al enviar notificaciones y mailables al modelo. Por lo tanto, no hay necesidad de llamar al método locale cuando se utiliza esta interfaz:

$user->notify(new InvoicePaid($invoice));

Eventos de Notificación

Evento de envío de notificaciones

Cuando se envía una notificación, el sistema de notificación envía el evento Illuminate\Notifications\Events\NotificationSending que contiene la entidad "notificable" y la propia instancia de notificación. Puede registrar escuchas para este evento en el EventServiceProvider de su aplicación:

use App\Listeners\CheckNotificationStatus;
use Illuminate\Notifications\Events\NotificationSending;
 
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
NotificationSending::class => [
CheckNotificationStatus::class,
],
];

La notificación no se enviará si un listener de eventos para el evento NotificationSending devuelve false desde su método handle:

use Illuminate\Notifications\Events\NotificationSending;
 
/**
* Handle the event.
*
* @param \Illuminate\Notifications\Events\NotificationSending $event
* @return void
*/
public function handle(NotificationSending $event)
{
return false;
}

Dentro de un receptor de eventos, puedes acceder a las propiedades notifiable, notification y channel del evento para saber más sobre el destinatario de la notificación o sobre la propia notificación:

/**
* Handle the event.
*
* @param \Illuminate\Notifications\Events\NotificationSending $event
* @return void
*/
public function handle(NotificationSending $event)
{
// $event->channel
// $event->notifiable
// $event->notification
}

Evento Notificación Enviada

Cuando se envía una notificación, el sistema de notificación envía el evento Illuminate\Notifications\Events\NotificationSentque contiene la entidad "notificable" y la propia instancia de notificación. Puede registrar oyentes para este evento en su EventServiceProvider:

use App\Listeners\LogNotification;
use Illuminate\Notifications\Events\NotificationSent;
 
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
NotificationSent::class => [
LogNotification::class,
],
];

Nota
Después de registrar escuchadores en tu EventServiceProvider, utiliza el comando event:generate Artisan para generar rápidamente clases de escuchadores.

Dentro de un escuchador de eventos, puedes acceder a las propiedades notifiable, notification, channel y response del evento para saber más sobre el destinatario de la notificación o la notificación en sí:

/**
* Handle the event.
*
* @param \Illuminate\Notifications\Events\NotificationSent $event
* @return void
*/
public function handle(NotificationSent $event)
{
// $event->channel
// $event->notifiable
// $event->notification
// $event->response
}

Canales Personalizados

Laravel viene con un puñado de canales de notificación, pero es posible que desee escribir sus propios controladores para entregar notificaciones a través de otros canales. Laravel lo hace simple. Para empezar, define una clase que contenga un método de send. El método debe recibir dos argumentos: un $notifiable y un $notification.

Dentro del método send, puedes llamar a métodos de la notificación para recuperar un objeto mensaje entendido por tu canal y luego enviar la notificación a la instancia $notifiable como desees:

<?php
 
namespace App\Notifications;
 
use Illuminate\Notifications\Notification;
 
class VoiceChannel
{
/**
* Send the given notification.
*
* @param mixed $notifiable
* @param \Illuminate\Notifications\Notification $notification
* @return void
*/
public function send($notifiable, Notification $notification)
{
$message = $notification->toVoice($notifiable);
 
// Send notification to the $notifiable instance...
}
}

Una vez definida tu clase de canal de notificación, puedes devolver el nombre de la clase desde el método via de cualquiera de tus notificaciones. En este ejemplo, el método toVoice de tu notificación puede devolver cualquier objeto que elijas para representar mensajes de voz. Por ejemplo, podrías definir tu propia clase VoiceMessage para representar estos mensajes:

<?php
 
namespace App\Notifications;
 
use App\Notifications\Messages\VoiceMessage;
use App\Notifications\VoiceChannel;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
 
class InvoicePaid extends Notification
{
use Queueable;
 
/**
* Get the notification channels.
*
* @param mixed $notifiable
* @return array|string
*/
public function via($notifiable)
{
return [VoiceChannel::class];
}
 
/**
* Get the voice representation of the notification.
*
* @param mixed $notifiable
* @return VoiceMessage
*/
public function toVoice($notifiable)
{
// ...
}
}