Cómo enviar notificaciones en Laravel ⚡

Laravel nos permite enviar notificaciones a través de distintos canales.

Por ejemplo vía:

  • Email,
  • SMS,
  • Slack,
  • Entre otros canales creados por la comunidad!

Las notificaciones también pueden guardarse en una base de datos, para ser mostrados en tu interfaz web.

¿Cuándo usar notificaciones?

Las notificaciones son mensajes informativos, que notifican a los usuarios de algo que ha ocurrido en tu aplicación.

Las notificaciones deben ser puntuales, y es conveniente usarlas para que tus usuarios estén al tanto de eventos que son relevantes para ellos.

Por ejemplo:

  • Si tu aplicación es un foro, debes informar a un usuario cada vez que recibe una respuesta.
  • Si tu aplicación es una tienda online, puedes notificar a un usuario cuando su pedido ha sido confirmado.

Generando notificaciones

En Laravel, cada notificación se representa por una clase. Éstas clases estarán ubicadas generalmente en la carpeta app/Notifications de tu proyecto.

Si no tienes la carpeta creada, no te preocupes, porque se creará al ejecutar el comando Artisan make:notification.

Por ejemplo, para el foro de mi página me interesa:

  • Enviar una notificación al administrador cada vez que se publica una pregunta nueva,
  • y así mismo notificar al autor de la pregunta por cada vez que reciba una respuesta.

Entonces crearé 2 notificaciones:

php artisan make:notification QuestionCreated
php artisan make:notification AnswerCreated

Cada clase "notification" contiene:

  • un método via,
  • y métodos que convierten la notificación en un mensaje soportado por cada canal en particular, tales como toMail y toDatabase.

Enviando notificaciones

Las notifiaciones se pueden enviar de 2 formas: usando el método notify que está presente en el trait Notifiable, o usando la clase fachada Notification.

Usando el trait Notifiable

El trait Notifiable viene incluido por defecto en el modelo App\Models\User de tu proyecto:

use Illuminate\Notifications\Notifiable;
 
class User extends Authenticatable
{
    use Notifiable;
}

Por lo tanto, puedes llamar al método notify desde un objeto User para notificar a dicho usuario:

use App\Notifications\QuestionCreated;
 
$user->notify(new QuestionCreated($question));

Ten en cuenta que puedes agregar el trait a otros modelos si lo consideras necesario.

Usando la facade Notification

De manera alternativa, también puedes enviar notificaciones usando la clase Notification.

Esto es lo más recomendable si necesitas enviar una notificación a múltiples usuarios (o entidades que son notificables).

Para usar esta clase fachada, solo debes pasar las entidades notifiable como primer argumento, seguido de la notificación que deseas enviar:

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

Ten en cuenta que las notificaciones se pueden enviar a través de colas, implementando la interfaz ShouldQueue.

Sin embargo, hay ocasiones en las que querrás enviar notificaciones inmediatamente. Para ello existe el método sendNow.

Este método envía la notificación inmediatamente, incluso si ésta implementa la interfaz ShouldQueue:

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

Canales de entrega

Como ya comentamos, a través del método via puedes indicar a través de qué canales quieres enviar tu notificación.

Las notificaciones pueden enviarse a través de estos canales: mail, database, broadcast, vonage, y slack. Además de otros custom notification drivers mantenidos por la comunidad.

Por ejemplo, si sólo quieres enviar tu notificación a través de correos, puedes usar:

public function via($notifiable)
{
    return ['mail'];
}

Pero ten en cuenta que este método recibe como parámetro una instancia $notifiable, representando a la entidad que va a ser notificada.

Eso significa que puedes usar atributos de este objeto para determinar qué canales usar, según sus propias preferencias. Sólo recuerda devolver siempre un arreglo.

Encolando notificaciones

Antes de encolar notificaciones, ten en cuenta que primero debes configurar en config/queue.php el funcionamiento de las colas para tu proyecto, y así mismo iniciar un worker.

¿Por qué es importante usar colas?

Supongamos que tenemos un tema de conversación muy interesante en nuestro foro, y muchos usuarios están interesados en enterarse de nuevas respuestas.

Si de pronto alguien agrega una respuesta:

  • No queremos que esta persona tenga que esperar a que todos los interesados sean notificados (notificación síncrona sin colas).
  • Queremos que esta persona tenga una buena experiencia al usar nuestra aplicación web.

Dependiendo de cada proyecto, las notificaciones pueden tomar cierto tiempo en ser entregadas, sobretodo si se tienen que hacer peticiones a APIs externas.

Para mejorar el tiempo de respuesta de nuestra aplicación, podemos encolar nuestras notificaciones.

Para encolar una notificación debemos hacer que nuestra clase implemente la interfaz ShouldQueue, y así mismo que contenga al trait Queueable.

Cuando usamos el comando make:notification (mencionado más arriba), tanto la interfaz como el trait ya se encuentran importados en la clase generada.

Por lo tanto, podemos usarlos fácilmente:

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
 
class AnswerCreated extends Notification implements ShouldQueue
{
    use Queueable;
 
    // ...
}

Basta con implementar la interfaz ShouldQueue y Laravel automáticamente se encargará de usar colas de procesamiento para nuestras notificaciones, sin cambios en nuestro código.

Es decir, para notificar, seguimos usando el mismo código.

Por ejemplo, para notificar que se ha agregado una nueva respuesta:

$user->notify(new AnswerCreated($answer));

Cuando encolamos notificaciones, Laravel genera un queued job por cada combinación de recipiente y canal que hayamos declarado.

Por ejemplo, si vamos a notificar a 3 usuarios a través de 2 canales, se agregarán 6 jobs a la cola.

Determinar si una notificación encolada debe ser enviada

Luego de que una notificación ha sido agregada a la cola, para que se procese en segundo plano, normalmente se aceptará por el queue worker y se enviará al destinatario correspondiente.

Sin embargo, si quieres tener control sobre qué notificaciones deben ser entregadas, cuando les llega su turno de ser procesadas por el queue worker, puedes definir un método shouldSend en tu notificación.

Si el método devuelve false, la notificación no será enviada:

public function shouldSend($notifiable, $channel)
{
    return $this->user->isUnsubscribed()) {
        return false;
    }
}

Notificaciones vía Mail

Si una notificación soporta el envío a través del canal mail, debe también definir un método toMail.

Este método recibe una entidad $notifiable y debe devolver una instancia Illuminate\Notifications\Messages\MailMessage.

La clase MailMessage contiene métodos que nos ayudarán a construir los correos que vamos a enviar.

Por ejemplo, pueden contener líneas de texto, y acciones.

Veamos un ejemplo del método toMail:

/**
 * Mail que representa a la notificación.
 */
public function toMail($notifiable)
{
    $url = url('/preguntas/'.$this->question->id);
 
    return (new MailMessage)
        ->greeting('Hola!')
        ->line('Has recibido una nueva respuesta en la pregunta que publicaste en el foro.')
        ->action('Ver conversación', $url)
        ->line('Gracias por ser parte de Programación y más 🙂');
}

Importante:

  • Seguro has notado que usamos $this->question->id en nuestro método toMail.
  • Puedes pasar cualquier data que tu notificación necesite al constructor de tu clase Notification.

En este ejemplo hemos agregado un saludo, una línea, un llamado a la acción, y luego una línea más:

  • Estos métodos son accesibles desde nuestra instancia de MailMessage, y nos permiten construir nuestros correos de manera fácil y rápida.
  • El canal mail generará un mensaje responsive por nosotros, y se verá bien.

Generar Mail usando Markdown

Con las notificaciones basadas en Markdown podemos aprovechar mejor los templates que Laravel prové, ya que tenemos mayor libertad para escribir mensajes personalizados.

Escribimos los mensajes en Markdown, y Laravel se encargará de renderizarlos de modo que sean responsive.

De igual manera, debemos definir un método toMail en nuestra clase Notification. Sin embargo, en vez de usar métodos como line y action, debemos usar el método markdown para indicar el nombre del Markdown template que queremos usar.

Podemos pasar un arreglo con los datos que queremos usar en el template, como segundo argumento:

public function toMail($notifiable)
{
    $url = url('/preguntas/'.$this->question->id);
 
    return (new MailMessage)
        ->subject('Nueva respuesta en el foro')
        ->markdown('emails.forum.new_answer', compact('url'));
}

¿Cómo escribimos nuestro correo usando Markdown?

Luego de indicar la ubicación de tu archivo a través del método markdown, puedes crear un archivo new_answer.blade.php en la carpeta emails/forum con el siguiente contenido:

@component('mail::message')
# Nueva respuesta

Hola!

Has recibido una nueva respuesta, en una pregunta que publicaste o en la cual has participado.

@component('mail::button', ['url' => $url])
Ver conversación
@endcomponent

Gracias por ser parte de la comunidad 🙂,

{{ config('app.name') }}
@endcomponent

Y el resultado final es el siguiente:

Notificación Laravel por Mail, generada usando Markdown

# laravel # mail # notifications # markdown

Logo de Programación y más

Comparte este post si te fue de ayuda 🙂.

Regístrate

Accede a todos los cursos, y resuelve todas tus dudas.

Cursos Recomendados

Imagen para el curso Aprende Laravel

Aprende Laravel

Aprende Laravel desde cero y desarrolla aplicaciones web reales, en tiempo récord, de la mano de Laravel.

Iniciar curso
Imagen para el curso Laravel Upgrade

Laravel Upgrade

Actualiza tus proyectos desde cualquier versión hasta la última versión estable de Laravel.

Iniciar curso
Imagen para el curso Laravel y Vue

Laravel y Vue

Desarrollemos un Messenger! Aprende sobre Channels, Queues, Vuex, JWT, Sesiones, BootstrapVue y mucho más.

Iniciar curso

Espera un momento ...

¿Te gustaría llevar mi curso de Laravel, gratis?

Sólo debes ingresar tus datos: