# Invia email con Laravel

> Invia le email di Laravel tramite Emailit con il transport e la facade di emailit/emailit-laravel, o con il semplice SMTP, e verifica i webhook di Emailit.

Questa guida mostra due modi per inviare le email di Laravel tramite Emailit: il pacchetto `emailit/emailit-laravel`, che aggiunge un transport di posta `emailit` e una facade `Emailit`, e il semplice SMTP con il mailer integrato di Laravel. Si conclude con una route webhook che verifica le firme.

## Prerequisiti

- PHP 8.1 o versioni successive e Laravel 10, 11 o 12.
- Un [dominio di invio verificato](/it/docs/domains/add-a-domain/), ad esempio `acme.com`.
- Una [chiave API](/it/docs/developers/api-keys/). Basta una chiave di solo invio limitata al tuo dominio.
- Finché il workspace non ha l’[accesso alla produzione](/it/docs/workspaces/production-access/), puoi inviare solo agli indirizzi email degli account dei membri del workspace.

## Opzione 1: il pacchetto Laravel di Emailit

Il pacchetto invia i Mailable esistenti, i Markdown mailable, le notifiche e le email in coda tramite l’API di Emailit, senza modifiche al codice di posta.

### Installa il pacchetto

```bash
composer require emailit/emailit-laravel
```

Il service provider viene rilevato automaticamente.

### Configura il transport

In `.env`, aggiungi la chiave e imposta Emailit come mailer predefinito:

```bash title=".env"
EMAILIT_API_KEY=secret_••••••••••••••••••••••••••••••••
MAIL_MAILER=emailit
MAIL_FROM_ADDRESS=hello@acme.com
MAIL_FROM_NAME="Acme"
```

Registra il mailer in `config/mail.php`:

```php title="config/mail.php"
'mailers' => [
    // ...

    'emailit' => [
        'transport' => 'emailit',
    ],
],
```

`MAIL_FROM_ADDRESS` deve appartenere a un dominio di invio verificato. Per cambiare l’URL di base dell’API, pubblica il file di configurazione con `php artisan vendor:publish --tag=emailit-config`; per l’uso normale non è necessario.

### Invia un Mailable

Crea un Mailable come al solito:

```bash
php artisan make:mail WelcomeEmail
```

```php title="app/Mail/WelcomeEmail.php"
namespace App\Mail;

use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;

class WelcomeEmail extends Mailable
{
    use Queueable, SerializesModels;

    public function __construct(public User $user) {}

    public function envelope(): Envelope
    {
        return new Envelope(subject: 'Welcome to Acme');
    }

    public function content(): Content
    {
        return new Content(view: 'emails.welcome');
    }
}
```

Invialo, oppure mettilo in coda così la richiesta non attende l’API:

```php
use App\Mail\WelcomeEmail;
use Illuminate\Support\Facades\Mail;

Mail::to($user)->send(new WelcomeEmail($user));

Mail::to($user)->queue(new WelcomeEmail($user));
```

### Usa la facade per le funzioni dell’API

La facade `Emailit` espone l’intero [SDK PHP](/it/docs/frameworks/php/), per le funzioni che il mailer di Laravel non prevede, come i template salvati e gli invii programmati:

```php
use Emailit\Laravel\Facades\Emailit;

$email = Emailit::emails()->send([
    'from'         => 'Acme <hello@acme.com>',
    'to'           => $user->email,
    'template'     => 'welcome',
    'variables'    => ['first_name' => $user->first_name],
    'scheduled_at' => 'tomorrow at 9am',
]);

$email->id; // em_…
```

La facade copre anche domini, contatti, liste, soppressioni, webhook e le altre risorse. Se preferisci la dependency injection, indica il tipo `Emailit\EmailitClient` in un controller o in un job e Laravel lo risolve con la chiave configurata.

Intercetta le eccezioni tipizzate per gestire gli errori:

```php
use Emailit\Exceptions\ApiErrorException;
use Emailit\Exceptions\RateLimitException;

try {
    Emailit::emails()->send($payload);
} catch (RateLimitException $e) {
    // 429: release the job back to the queue and try again later
} catch (ApiErrorException $e) {
    report($e); // $e->getHttpStatus() has the status code
}
```

## Opzione 2: semplice SMTP

Se preferisci non aggiungere un pacchetto, indirizza il mailer SMTP di Laravel al relay di Emailit:

```bash title=".env"
MAIL_MAILER=smtp
MAIL_HOST=smtp.emailit.com
MAIL_PORT=587
MAIL_USERNAME=emailit
MAIL_PASSWORD=secret_••••••••••••••••••••••••••••••••
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=hello@acme.com
MAIL_FROM_NAME="Acme"
```

Sulla porta 587 il mailer di Laravel aggiorna la connessione con STARTTLS. I file `config/mail.php` meno recenti leggono `MAIL_ENCRYPTION` e quelli più recenti lo ignorano, quindi puoi tenerlo senza problemi. Per il TLS implicito, usa la porta `465`; se il tuo host blocca la 587, usa la `2525` o la `2587`. Mailable, notifiche e code funzionano esattamente come con il pacchetto. Vedi [Impostazioni SMTP](/it/docs/smtp/settings/).

Via SMTP non puoi usare i template salvati né `scheduled_at`; per queste funzioni usa la facade o l’API.

## Ricevi i webhook

[Crea un webhook](/it/docs/webhooks/set-up/) che punta a `https://your-app.com/webhooks/emailit`, poi salva il suo secret di firma:

```bash title=".env"
EMAILIT_WEBHOOK_SECRET=whsec_••••••••
```

```php title="config/services.php"
'emailit' => [
    'webhook_secret' => env('EMAILIT_WEBHOOK_SECRET'),
],
```

Aggiungi un controller che controlla la firma sul corpo grezzo:

```php title="app/Http/Controllers/EmailitWebhookController.php"
namespace App\Http\Controllers;

use Illuminate\Http\Request;

class EmailitWebhookController extends Controller
{
    public function __invoke(Request $request)
    {
        $payload = $request->getContent();
        $signature = (string) $request->header('X-Emailit-Signature');
        $timestamp = (string) $request->header('X-Emailit-Timestamp');

        $expected = hash_hmac('sha256', $timestamp.'.'.$payload, config('services.emailit.webhook_secret'));

        if (abs(time() - (int) $timestamp) > 300 || ! hash_equals($expected, $signature)) {
            abort(401, 'Invalid signature');
        }

        // The body is a JSON array of up to 100 events.
        foreach (json_decode($payload, true) as $event) {
            match ($event['type']) {
                'email.bounced', 'email.complained' => $this->stopEmailing($event['data']['object']['to']),
                default => null,
            };
        }

        return response()->noContent();
    }

    private function stopEmailing(string $address): void
    {
        // Mark the address as undeliverable in your database.
    }
}
```

Registra la route ed escludila dalla protezione CSRF, perché Emailit non può inviare un token CSRF:

```php title="routes/web.php"
use App\Http\Controllers\EmailitWebhookController;

Route::post('/webhooks/emailit', EmailitWebhookController::class);
```

```php title="bootstrap/app.php (Laravel 11 e 12)"
->withMiddleware(function (Middleware $middleware) {
    $middleware->validateCsrfTokens(except: ['webhooks/emailit']);
})
```

Con Laravel 10, aggiungi invece `'webhooks/emailit'` all’array `$except` in `app/Http/Middleware/VerifyCsrfToken.php`. Restituisci un `2xx` entro 30 secondi e sposta il lavoro lento in una coda. Vedi [Firma delle richieste](/it/docs/webhooks/request-signature/).

## Consigli per la produzione

- **Metti in coda le email.** Usa `queue()` o `ShouldQueue` così le richieste web non attendono le email, e limita la velocità dei job massivi (ad esempio con `Redis::throttle`) per restare entro i [limiti di invio](/it/docs/limits/). Per impostazione predefinita, i nuovi workspace possono inviare 2 email al secondo.
- **Metti in cache la configurazione in modo sicuro.** Dopo `php artisan config:cache`, `env()` funziona solo all’interno dei file di configurazione. Leggi la chiave tramite la configurazione, come fa il pacchetto.
- **Usa una chiave dedicata.** Dai a ogni app e a ogni ambiente la propria chiave di solo invio, così puoi ruotarne una senza toccare le altre. Vedi [Chiavi API](/it/docs/developers/api-keys/).
- **Elimina i webhook duplicati.** Salva ogni `event_id` che elabori e salta le ripetizioni, perché le consegne non riuscite vengono ritentate.

## Passaggi successivi

  - [Guida all’SDK PHP](/it/docs/frameworks/php/): Il client dietro la facade.
  - [Template](/it/docs/templates/): Progetta le email in Emailit e inviale per alias.
  - [Tipi di evento dei webhook](/it/docs/webhooks/event-types/): Ogni evento e il suo payload.
  - [Risoluzione dei problemi SMTP](/it/docs/smtp/troubleshooting/): Correggi gli errori di autenticazione e di connessione.

---
Fonte: https://emailit.com/it/docs/frameworks/laravel/
