Zum Inhalt springen
Doku

Tutorial

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.

Aktualisiert am 1. Okt. 2026

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, zum Beispiel acme.com.
  • Ein API-Schlüssel. Ein reiner Sende-Schlüssel, der auf Ihre Domain beschränkt ist, genügt.
  • Solange Ihr Workspace keinen Produktionszugang 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

Terminal
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:

.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:

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:

Terminal
php artisan make:mail WelcomeEmail
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 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:

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

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, der auf https://your-app.com/webhooks/emailit zeigt, und speichern Sie dann sein Signatur-Secret:

.env
EMAILIT_WEBHOOK_SECRET=whsec_••••••••
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:

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:

routes/web.php
use App\Http\Controllers\EmailitWebhookController;

Route::post('/webhooks/emailit', EmailitWebhookController::class);
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.

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 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.
  • Webhooks deduplizieren. Speichern Sie jede verarbeitete event_id und überspringen Sie Wiederholungen, da fehlgeschlagene Zustellungen erneut versucht werden.

Nächste Schritte

Der Client hinter der Facade.
Gestalten Sie E-Mails in Emailit und senden Sie sie per Alias.
Alle Events und ihre Payloads.
Authentifizierungs- und Verbindungsfehler beheben.

War diese Seite hilfreich?

Danke für Ihr Feedback.

Danke, wir lesen jede Nachricht.