> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Notificaciones

> Aprende a enviar notificaciones a varios canales (correo, base de datos, Slack, etc.) simultáneamente con el sistema de notificaciones de Laravel.

## 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`.

```shell theme={null}
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()`.

```php theme={null}
use App\Notifications\InvoicePaid;

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

<Info>
  Puedes añadir `Notifiable` a cualquier modelo, no solo a `User`.
</Info>

### Con el facade Notification

Para enviar a varios usuarios a la vez, utiliza el facade `Notification`.

```php theme={null}
use Illuminate\Support\Facades\Notification;

Notification::send($users, new InvoicePaid($invoice));
```

Para enviar inmediatamente sin pasar por la cola, usa `sendNow()`.

```php theme={null}
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.

```mermaid theme={null}
flowchart TD
    A["$user->notify(new InvoicePaid())"] --> B["via() elige<br>los canales"]
    B --> C{"Canal seleccionado"}
    C --> D["mail<br>toMail()"]
    C --> E["database<br>toArray()"]
    C --> F["broadcast<br>toBroadcast()"]
    C --> G["vonage<br>toVonage()"]
    C --> H["slack<br>toSlack()"]
```

```php theme={null}
public function via(object $notifiable): array
{
    return ['mail', 'database'];
}
```

También puedes elegir canal según la preferencia del usuario.

```php theme={null}
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`.

```php theme={null}
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.

```php theme={null}
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`.

```shell theme={null}
php artisan make:notification InvoicePaid --markdown=mail.invoice.paid
```

Usa `toMarkdownMail()` en lugar de `toMail()`.

```php theme={null}
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`.

```shell theme={null}
php artisan make:notifications-table

php artisan migrate
```

### Definir toArray

Devuelve los datos a guardar como array desde `toArray()`.

```php theme={null}
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.

```php theme={null}
$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`.

```php theme={null}
foreach ($user->unreadNotifications as $notification) {
    echo $notification->data['message'];
}
```

### Marcar como leídas

Con `markAsRead()` marcas la notificación como leída.

```php theme={null}
// 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 theme={null}
<?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.

```php theme={null}
$user->notify(new InvoicePaid($invoice));
```

Puedes retrasar el envío.

```php theme={null}
$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 theme={null}
<?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()`.

```php theme={null}
use Illuminate\Support\Facades\Notification;

Notification::route('mail', 'guest@example.com')
    ->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()`                   |


## Related topics

- [BlueskyManager y HasShortHand](/es/packages/laravel-bluesky/bluesky-manager.md)
- [Canal de notificaciones - LINE SDK for Laravel](/es/packages/laravel-line-sdk/notification.md)
- [Canal de notificaciones - Laravel Bluesky](/es/packages/laravel-bluesky/notification.md)
- [Laravel Notification for Discord(Webhook)](/es/packages/laravel-notification-discord-webhook.md)
- [Laravel Horizon](/es/horizon.md)
