presseportale/app/Mail/MagicLoginLink.php
Kevin Adametz 8bf40ee37e mail: zentrale Bounce-Suppression mit Versand-Gate und Circuit Breaker (Roadmap 1b.6, Schritte 1–2)
email_suppressions/email_bounces als Zustand und Ereignis-Log; ein
MessageSending-Listener streicht gesperrte Empfänger aus JEDER ausgehenden
Mail und setzt den Return-Path. Zweiter Aufnahmepfad: SMTP-Ablehnungen im
Worker — 5.1.x sperrt den Empfänger, Relay-Ablehnungen zählen für den
Circuit Breaker, der den Versand anhält statt gesunde Adressen zu sperren.
X-Pk-Ref-Header auf den Mails, API-Meldungen fallen auf die Firmen-E-Mail
zurück, der Bounce-Import schreibt in die zentrale Liste.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-15 13:48:56 +00:00

51 lines
1.2 KiB
PHP

<?php
namespace App\Mail;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Mail\Mailables\Headers;
use Illuminate\Queue\SerializesModels;
class MagicLoginLink extends Mailable implements ShouldQueue
{
use Queueable, SerializesModels;
public function __construct(
public User $user,
public string $loginUrl,
public string $expiresAt
) {}
/**
* Eigener Header je Mail: Ein DSN bringt die Original-Header zurück, so
* ordnet der Bounce-Parser den Rückläufer dem Datensatz zu (Roadmap 1b.6).
*/
public function headers(): Headers
{
return new Headers(text: [(string) config('bounces.reference_header', 'X-Pk-Ref') => 'user:'.$this->user->id]);
}
public function envelope(): Envelope
{
return new Envelope(
subject: 'Ihr Anmeldelink für Ihr pressekonto'
);
}
public function content(): Content
{
return new Content(
view: 'emails.auth.magic-login-link'
);
}
public function attachments(): array
{
return [];
}
}