# E-Mails mit Laravel senden

> Senden Sie Laravel-E-Mails über Emailit mit dem Mail-Transport und der Facade von emailit/emailit-laravel oder per SMTP und verifizieren Sie Emailit-Webhooks.

Diese Anleitung zeigt zwei Wege, Laravel-E-Mails über Emailit zu senden: das Paket `emailit/emailit-laravel`, das einen Mail-Transport `emailit` und eine Facade `Emailit` hinzufügt, und einfaches SMTP mit dem integrierten Mailer von Laravel. Zum Schluss folgt eine Webhook-Route, die Signaturen verifiziert.

## Voraussetzungen

- PHP 8.1 oder neuer und Laravel 10, 11 oder 12.
- Eine [verifizierte Versanddomain](/de/docs/domains/add-a-domain/), zum Beispiel `acme.com`.
- Ein [API-Schlüssel](/de/docs/developers/api-keys/). Ein reiner Sende-Schlüssel, der auf Ihre Domain beschränkt ist, genügt.
- Solange Ihr Workspace keinen [Produktionszugang](/de/docs/workspaces/production-access/) hat, können Sie nur an die Konto-E-Mail-Adressen von Workspace-Mitgliedern senden.

## Option 1: das Laravel-Paket von Emailit

Das Paket sendet Ihre vorhandenen Mailables, Markdown-Mailables, Benachrichtigungen und E-Mails aus der Warteschlange über die Emailit-API, ohne Änderungen an Ihrem Mail-Code.

### Paket installieren

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

Der Service Provider wird automatisch erkannt.

### Transport konfigurieren

Fügen Sie in `.env` Ihren Schlüssel hinzu und machen Sie Emailit zum Standard-Mailer:

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

Registrieren Sie den Mailer in `config/mail.php`:

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

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

`MAIL_FROM_ADDRESS` muss zu einer verifizierten Versanddomain gehören. Um die Basis-URL der API zu ändern, veröffentlichen Sie die Konfigurationsdatei mit `php artisan vendor:publish --tag=emailit-config`; für die normale Nutzung ist das nicht nötig.

### Mailable senden

Erstellen Sie wie gewohnt ein Mailable:

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

Senden Sie es oder stellen Sie es in die Warteschlange, damit die Anfrage nicht auf die API wartet:

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

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

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

### Facade für API-Funktionen verwenden

Die Facade `Emailit` stellt das vollständige [PHP-SDK](/de/docs/frameworks/php/) bereit, für Funktionen, die der Mailer von Laravel nicht abbildet, etwa gespeicherte Vorlagen und geplante Versände:

```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_…
```

Die Facade deckt außerdem Domains, Kontakte, Kontaktlisten, Sperrungen, Webhooks und die übrigen Ressourcen ab. Wenn Sie Dependency Injection bevorzugen, geben Sie `Emailit\EmailitClient` als Typ in einem Controller oder Job an, und Laravel löst den Client mit Ihrem konfigurierten Schlüssel auf.

Fangen Sie typisierte Exceptions ab, um Fehler zu behandeln:

```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: einfaches SMTP

Wenn Sie lieber kein Paket hinzufügen möchten, richten Sie den SMTP-Mailer von Laravel auf das Emailit-Relay aus:

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

Auf Port 587 stuft der Mailer von Laravel die Verbindung per STARTTLS hoch. Ältere `config/mail.php`-Dateien lesen `MAIL_ENCRYPTION`, neuere ignorieren es; Sie können die Variable also gefahrlos behalten. Für implizites TLS verwenden Sie Port `465`; wenn Ihr Hoster 587 blockiert, verwenden Sie `2525` oder `2587`. Mailables, Benachrichtigungen und Warteschlangen funktionieren genauso wie mit dem Paket. Siehe [SMTP-Einstellungen](/de/docs/smtp/settings/).

Per SMTP können Sie keine gespeicherten Vorlagen und kein `scheduled_at` verwenden; nutzen Sie dafür die Facade oder die API.

## Webhooks empfangen

[Erstellen Sie einen Webhook](/de/docs/webhooks/set-up/), der auf `https://your-app.com/webhooks/emailit` zeigt, und speichern Sie dann sein Signatur-Secret:

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

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

Fügen Sie einen Controller hinzu, der die Signatur anhand des unveränderten Bodys prüft:

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

Registrieren Sie die Route und nehmen Sie sie vom CSRF-Schutz aus, da Emailit kein CSRF-Token senden kann:

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

Unter Laravel 10 fügen Sie `'webhooks/emailit'` stattdessen dem Array `$except` in `app/Http/Middleware/VerifyCsrfToken.php` hinzu. Geben Sie innerhalb von 30 Sekunden einen `2xx`-Status zurück und verlagern Sie langsame Arbeit in eine Warteschlange. Siehe [Anfragesignatur](/de/docs/webhooks/request-signature/).

## Tipps für den Produktivbetrieb

- **E-Mails in die Warteschlange stellen.** Verwenden Sie `queue()` oder `ShouldQueue`, damit Webanfragen nicht auf E-Mails warten, und drosseln Sie Massen-Jobs (zum Beispiel mit `Redis::throttle`), um unter Ihren [Versandlimits](/de/docs/limits/) zu bleiben. Neue Workspaces können standardmäßig 2 E-Mails pro Sekunde senden.
- **Konfiguration sicher cachen.** Nach `php artisan config:cache` funktioniert `env()` nur noch in Konfigurationsdateien. Lesen Sie den Schlüssel über die Konfiguration, so wie es das Paket tut.
- **Eigenen Schlüssel verwenden.** Geben Sie jeder App und Umgebung einen eigenen reinen Sende-Schlüssel, damit Sie einen rotieren können, ohne die anderen anzutasten. Siehe [API-Schlüssel](/de/docs/developers/api-keys/).
- **Webhooks deduplizieren.** Speichern Sie jede verarbeitete `event_id` und überspringen Sie Wiederholungen, da fehlgeschlagene Zustellungen erneut versucht werden.

## Nächste Schritte

  - [Anleitung zum PHP-SDK](/de/docs/frameworks/php/): Der Client hinter der Facade.
  - [Vorlagen](/de/docs/templates/): Gestalten Sie E-Mails in Emailit und senden Sie sie per Alias.
  - [Webhook-Event-Typen](/de/docs/webhooks/event-types/): Alle Events und ihre Payloads.
  - [SMTP-Fehlerbehebung](/de/docs/smtp/troubleshooting/): Authentifizierungs- und Verbindungsfehler beheben.

---
Quelle: https://emailit.com/de/docs/frameworks/laravel/
