# Envoyer des e-mails avec Laravel

> Envoyez les e-mails de Laravel via Emailit avec le transport mail et la façade emailit/emailit-laravel, ou en SMTP simple, et vérifiez les webhooks Emailit.

Ce guide présente deux façons d’envoyer les e-mails de Laravel via Emailit : le paquet `emailit/emailit-laravel`, qui ajoute un transport mail `emailit` et une façade `Emailit`, et le SMTP simple avec le mailer intégré de Laravel. Il se termine par une route de webhook qui vérifie les signatures.

## Prérequis

- PHP 8.1 ou version ultérieure et Laravel 10, 11 ou 12.
- Un [domaine d’envoi vérifié](/fr/docs/domains/add-a-domain/), par exemple `acme.com`.
- Une [clé API](/fr/docs/developers/api-keys/). Une clé Sending Only limitée à votre domaine suffit.
- Tant que votre espace de travail n’a pas l’[accès production](/fr/docs/workspaces/production-access/), vous ne pouvez envoyer qu’aux adresses e-mail des comptes des membres de l’espace de travail.

## Option 1 : le paquet Laravel d’Emailit

Le paquet envoie vos Mailables existants, vos Mailables Markdown, vos notifications et vos e-mails en file d’attente via l’API Emailit, sans modifier votre code d’envoi.

### Installer le paquet

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

Le service provider est découvert automatiquement.

### Configurer le transport

Ajoutez votre clé et faites d’Emailit le mailer par défaut dans `.env` :

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

Déclarez le mailer dans `config/mail.php` :

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

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

`MAIL_FROM_ADDRESS` doit appartenir à un domaine d’envoi vérifié. Pour modifier l’URL de base de l’API, publiez le fichier de configuration avec `php artisan vendor:publish --tag=emailit-config` ; ce n’est pas nécessaire pour un usage normal.

### Envoyer un Mailable

Créez un Mailable comme d’habitude :

```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');
    }
}
```

Envoyez-le, ou mettez-le en file d’attente pour que la requête n’attende pas 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));
```

### Utiliser la façade pour les fonctionnalités de l’API

La façade `Emailit` expose l’intégralité du [SDK PHP](/fr/docs/frameworks/php/), pour les fonctionnalités que le mailer de Laravel ne prend pas en charge, comme les modèles enregistrés et les envois programmés :

```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 façade couvre aussi les domaines, les contacts, les listes de contacts, les adresses bloquées, les webhooks et les autres ressources. Si vous préférez l’injection de dépendances, typez `Emailit\EmailitClient` dans un contrôleur ou un job : Laravel le résout avec la clé configurée.

Interceptez les exceptions typées pour gérer les échecs :

```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
}
```

## Option 2 : SMTP simple

Si vous préférez ne pas ajouter de paquet, faites pointer le mailer SMTP de Laravel vers le relais 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"
```

Sur le port 587, le mailer de Laravel passe la connexion en STARTTLS. Les anciens fichiers `config/mail.php` lisent `MAIL_ENCRYPTION` et les plus récents l’ignorent : vous pouvez donc le conserver sans risque. Pour le TLS implicite, utilisez le port `465` ; si votre hébergeur bloque le port 587, utilisez `2525` ou `2587`. Les Mailables, les notifications et les files d’attente fonctionnent exactement comme avec le paquet. Consultez [Paramètres SMTP](/fr/docs/smtp/settings/).

Via SMTP, vous ne pouvez pas utiliser les modèles enregistrés ni `scheduled_at` ; utilisez pour cela la façade ou l’API.

## Recevoir des webhooks

[Créez un webhook](/fr/docs/webhooks/set-up/) qui pointe vers `https://your-app.com/webhooks/emailit`, puis enregistrez son secret de signature :

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

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

Ajoutez un contrôleur qui vérifie la signature à partir du corps brut :

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

Déclarez la route et excluez-la de la protection CSRF, car Emailit ne peut pas envoyer de jeton CSRF :

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

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

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

Sous Laravel 10, ajoutez plutôt `'webhooks/emailit'` au tableau `$except` de `app/Http/Middleware/VerifyCsrfToken.php`. Renvoyez un `2xx` dans les 30 secondes et déléguez les traitements lents à une file d’attente. Consultez [Signature des requêtes](/fr/docs/webhooks/request-signature/).

## Conseils pour la production

- **Mettez vos e-mails en file d’attente.** Utilisez `queue()` ou `ShouldQueue` pour que les requêtes web n’attendent pas l’envoi, et limitez le débit des jobs d’envoi en masse (par exemple avec `Redis::throttle`) pour rester sous vos [limites d’envoi](/fr/docs/limits/). Par défaut, les nouveaux espaces de travail peuvent envoyer 2 e-mails par seconde.
- **Mettez la configuration en cache sans risque.** Après `php artisan config:cache`, `env()` ne fonctionne que dans les fichiers de configuration. Lisez la clé via la configuration, comme le fait le paquet.
- **Utilisez une clé dédiée.** Donnez à chaque application et à chaque environnement sa propre clé Sending Only, pour pouvoir effectuer la rotation de l’une sans toucher aux autres. Consultez [Clés API](/fr/docs/developers/api-keys/).
- **Dédoublonnez les webhooks.** Enregistrez chaque `event_id` traité et ignorez les doublons, car Emailit réessaie les livraisons en échec.

## Étapes suivantes

  - [Guide du SDK PHP](/fr/docs/frameworks/php/): Le client derrière la façade.
  - [Modèles](/fr/docs/templates/): Concevez vos e-mails dans Emailit et envoyez-les par alias.
  - [Types d’événements webhook](/fr/docs/webhooks/event-types/): Tous les événements et leur payload.
  - [Dépannage SMTP](/fr/docs/smtp/troubleshooting/): Corrigez les erreurs d’authentification et de connexion.

---
Source: https://emailit.com/fr/docs/frameworks/laravel/
