E-Mail-Praeferenzen: Opt-out je Mail-Typ + One-Click-Unsubscribe ohne Login
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
06d80b255b
commit
51da374173
21 changed files with 746 additions and 9 deletions
42
app/Mail/Concerns/Unsubscribable.php
Normal file
42
app/Mail/Concerns/Unsubscribable.php
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mail\Concerns;
|
||||
|
||||
use App\Enums\EmailNotificationType;
|
||||
use App\Models\User;
|
||||
use Illuminate\Mail\Mailables\Headers;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
|
||||
/**
|
||||
* Macht eine Benachrichtigungs-Mail abbestellbar: signierter Abmelde-Link
|
||||
* für den Mail-Footer (ohne Login nutzbar, ohne Ablauf — der Link aus alten
|
||||
* Mails bleibt gültig) plus die List-Unsubscribe-Header nach RFC 8058, mit
|
||||
* denen Mail-Clients (Gmail, Apple Mail …) einen nativen
|
||||
* „Abbestellen"-Button anbieten.
|
||||
*
|
||||
* Der Link wird im Konstruktor der Mailable erzeugt (configureUnsubscribe),
|
||||
* damit er beim Queuen mit serialisiert wird.
|
||||
*/
|
||||
trait Unsubscribable
|
||||
{
|
||||
public string $unsubscribeUrl;
|
||||
|
||||
public EmailNotificationType $notificationType;
|
||||
|
||||
protected function configureUnsubscribe(User $user, EmailNotificationType $type): void
|
||||
{
|
||||
$this->notificationType = $type;
|
||||
$this->unsubscribeUrl = URL::signedRoute('email-preferences.unsubscribe', [
|
||||
'user' => $user->id,
|
||||
'type' => $type->value,
|
||||
]);
|
||||
}
|
||||
|
||||
public function headers(): Headers
|
||||
{
|
||||
return new Headers(text: [
|
||||
'List-Unsubscribe' => '<'.$this->unsubscribeUrl.'>',
|
||||
'List-Unsubscribe-Post' => 'List-Unsubscribe=One-Click',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace App\Mail;
|
||||
|
||||
use App\Enums\EmailNotificationType;
|
||||
use App\Mail\Concerns\Unsubscribable;
|
||||
use App\Models\PressRelease;
|
||||
use App\Models\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
|
|
@ -17,7 +19,7 @@ use Illuminate\Queue\SerializesModels;
|
|||
*/
|
||||
class PressReleaseDepublished extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
use Queueable, SerializesModels, Unsubscribable;
|
||||
|
||||
public string $showUrl;
|
||||
|
||||
|
|
@ -28,6 +30,8 @@ class PressReleaseDepublished extends Mailable
|
|||
$this->showUrl = $user->canAccessAdmin()
|
||||
? route('admin.press-releases.show', $pressRelease->id)
|
||||
: route('me.press-releases.show', $pressRelease->id);
|
||||
|
||||
$this->configureUnsubscribe($user, EmailNotificationType::PressReleaseDepublished);
|
||||
}
|
||||
|
||||
public function envelope(): Envelope
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace App\Mail;
|
||||
|
||||
use App\Enums\EmailNotificationType;
|
||||
use App\Mail\Concerns\Unsubscribable;
|
||||
use App\Models\PressRelease;
|
||||
use App\Models\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
|
|
@ -12,7 +14,7 @@ use Illuminate\Queue\SerializesModels;
|
|||
|
||||
class PressReleasePublished extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
use Queueable, SerializesModels, Unsubscribable;
|
||||
|
||||
public string $showUrl;
|
||||
|
||||
|
|
@ -33,6 +35,8 @@ class PressReleasePublished extends Mailable
|
|||
: route('me.press-releases.show', $pressRelease->id);
|
||||
|
||||
$this->portalLinks = $pressRelease->publicPortalLinks();
|
||||
|
||||
$this->configureUnsubscribe($user, EmailNotificationType::PressReleasePublished);
|
||||
}
|
||||
|
||||
public function envelope(): Envelope
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace App\Mail;
|
||||
|
||||
use App\Enums\EmailNotificationType;
|
||||
use App\Mail\Concerns\Unsubscribable;
|
||||
use App\Models\PressRelease;
|
||||
use App\Models\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
|
|
@ -12,7 +14,7 @@ use Illuminate\Queue\SerializesModels;
|
|||
|
||||
class PressReleaseRejected extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
use Queueable, SerializesModels, Unsubscribable;
|
||||
|
||||
public string $editUrl;
|
||||
|
||||
|
|
@ -24,6 +26,8 @@ class PressReleaseRejected extends Mailable
|
|||
$this->editUrl = $user->canAccessAdmin()
|
||||
? route('admin.press-releases.edit', $pressRelease->id)
|
||||
: route('me.press-releases.edit', $pressRelease->id);
|
||||
|
||||
$this->configureUnsubscribe($user, EmailNotificationType::PressReleaseRejected);
|
||||
}
|
||||
|
||||
public function envelope(): Envelope
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue