NovinkaZverejnili sme 50+ Laravel balíkov ako open source
Custom AI apps, agents and automation — Roundly ConsultingRoundly
Všetky balíky

E-maily idú cez mailové notifikácie Laravelu (TypedMailNotification) v jazyku príjemcu (HasLocalePreference::preferredLocale()).

Deduplikácia v rámci okna

Kľúč deduplikácie má rovnaké časti ako kľúč zlučovania v schránke, takže jedna položka schránky a jedno doručenie vždy patria k sebe:

  • Leading (predvolené, notifications.mail.strategy) — prvá udalosť odošle e-mail hneď (alebo na konci tichých hodín); ďalšie udalosti v okne sa doň zlúčia a nič ďalšie neodošlú. Desať udalostí za päť minút → jeden e-mail.
  • Trailing (mailStrategy(): MailStrategy::Trailing) — doručenie čaká prvú udalosť + okno; každá udalosť sa zlúči a odíde jeden e-mail s konečným počtom a najnovším obsahom.
  • Urgentné druhy posielajú vždy hneď. E-mail, ktorý ešte neodišiel, pohltí ďalšie udalosti (Folded); odoslaný ich len spočíta (Deduplicated). Ak sa pred odoslaním zlúčilo viac udalostí, e-mail uvedie „a N ďalších aktualizácií“.
// Leading (default): the first event mails now; later ones in the window fold into it
Notifications::send('request.awaiting_approval', $request, $approver);   // MailOutcome::Pending
Notifications::send('request.awaiting_approval', $request, $approver);   // MailOutcome::Folded (or Deduplicated once sent)

// Trailing: one mail after the window, with the final count and the latest content
final class CommentPosted extends NotificationType
{
    public function window(): ?string { return 'PT10M'; }
    public function mailStrategy(): MailStrategy { return MailStrategy::Trailing; }
    // …
}

Životný cyklus doručenia

StavVýznam
pending → sending → sentBežná cesta. DeliverMailJob prevezme riadok cez compare-and-set, takže opakovaná úloha ani druhý scheduler nič nepošle.
heldTiché hodiny — sweep ho uvoľní po ich skončení; pri doručení sa znova overí a ak medzitým začali tiché hodiny, znova sa podrží.
digestOdložené do súhrnu používateľa.
cancelledrecipient_gone, unknown_type, subject_gone, no_access, muted (okrem povinných), revoked — overuje sa tesne pred odoslaním.
failedrender (háčik druhu vyhodil výnimku — nahlásené, bez opakovania), transport (po mail.max_attempts s mail.backoff medzi pokusmi), unknown (po mail.lease sa stále odosiela — nikdy sa nepošle znova).
undeliverableno_address — resolver vrátil null alebo príjemca nemá trasu pre e-mail.

Adresa sa určí ešte pred mailovým kanálom Laravelu: nakonfigurovaný resolver adries, inak routeNotificationFor('mail'). Pri vypnutom notifications.queue.enabled beží úloha priamo po commite; inak sa odošle na notifications.queue.connection / queue. Udalosti: NotificationMailSent, NotificationMailFailed, NotificationMailHeld.

Vykreslenie

Predmet = title(); oslovenie (s menom príjemcu, ak ho má); prvý riadok = body() (inak nadpis); „a N ďalších aktualizácií“ pri zlúčení; tlačidlo akcie (url() + actionText(), len absolútne http(s)); pätička — upozornenie na povinnosť pri povinných druhoch, inak odkaz na preferencie, ak je nastavené notifications.mail.preferences_url (URL alebo názov route); nakoniec háčik mail($message, $payload) druhu. Text ide cez markdown šablónu Laravelu, ktorá ho escapuje. V teste aplikácie to overíte takto:

use Illuminate\Support\Facades\Notification;
use RoundlyConsulting\Notifications\Mail\TypedMailNotification;

Notification::assertSentTo($user, TypedMailNotification::class, fn ($n) => $n->type === 'security.alert'
    && $n->message->subject === 'Security alert');

Minimálny e-mail pre citlivé subjekty

Ak sensitive($subject) druhu vráti true a notifications.mail.minimal_for_sensitive je zapnuté (predvolené), e-mail obsahuje len minimalTitle() („New notification from :app“), jeden riadok a tlačidlo — body() ani mail() sa nevolajú. Riadky citlivých položiek v súhrne používajú tiež minimálny text. Schránky sa to netýka: je za vaším prihlásením.

Resolver adries

notifications.mail.address_resolver určuje ResolvesMailAddress, ktorý rozhodne o adrese každého e-mailu balíka — typovaných aj súhrnov; pri súhrne je payload null. Reťazec pošle na danú adresu; null označí doručenie ako undeliverable (súhrn zlyhá ako no_address). S contacts-for-laravel idú e-maily na primárny e-mailový kontakt používateľa:

class User extends Authenticatable
{
    use HasContacts;
    use Notifiable;
    use ReceivesNotifications;
    use RoutesNotificationsViaContacts;   // mail goes to the primary email contact
}

Ak chcete len overené adresy, naviažte resolver — používateľ bez overeného primárneho e-mailu potom dostane undeliverable a ani súhrn:

use Illuminate\Database\Eloquent\Model;
use RoundlyConsulting\Contacts\Enums\ContactType;
use RoundlyConsulting\Notifications\Contracts\ResolvesMailAddress;
use RoundlyConsulting\Notifications\NotificationPayload;

final class VerifiedEmailResolver implements ResolvesMailAddress
{
    public function address(Model $recipient, ?NotificationPayload $payload): ?string   // null payload = a digest
    {
        $contact = $recipient->primaryContact(ContactType::Email);

        return $contact?->verified_at !== null ? $contact->value : null;
    }
}

// config/notifications.php
'mail' => ['address_resolver' => App\Notifications\VerifiedEmailResolver::class],

Prejavte lásku k open source

Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.

Ďalšie spôsoby podpory vrátane kryptomien

Odoslaním daru súhlasíte s našimi podmienkami prijímania darov.

Chcete to zabudovať do svojho produktu?

Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.