Odosielanie
Jedno volanie upozorní každého príjemcu na jednu udalosť:
Notifications::send(
string $type, // a key or a type class-string
?Model $subject,
RecipientSpec|Model|Closure|iterable $recipients,
array $data = [], // plain JSON, ≤ notifications.inbox.max_data_bytes
?Model $actor = null,
Context|Model|string|null $context = null, // overrides the type's context()
?string $idempotencyKey = null,
): SendResult;Fluentný builder
type() spúšťa rovnaký postup s pomenovanými krokmi:
Notifications::type(RequestAwaitingApproval::class)
->about($request)
->to(Recipients::role($request->company, 'approver'))
->by($request->author)
->with(['reference' => $request->reference])
->in($request->company)
->once("request-submitted:{$request->id}") // a replay sends nothing to anyone it reached
->escalate(after: 'P2D', to: Recipients::role($request->company, 'director'))
->send(); // SendResult
$pending = Notifications::type('request.awaiting_approval')->about($request)->to($approvers);
$pending->data(); // the SendNotificationData it would sendO jednom subjekte
Notifications::for($request)->send('request.awaiting_approval', $approvers, ['reference' => 'PR-9']);
Notifications::for($request)->type('request.awaiting_approval')->to($approvers)->send();
Notifications::for($request)->subject(); // the modelPostup spracovania
Pri každom volaní: nájde druh → overí triedu subjektu, dáta (čistý JSON pod limitom) a typy kľúčov → vyhodnotí kontext → vyhodnotí príjemcov (null hodnoty a duplicity vypadnú, aktér sa odstráni, ak nie je notifyActor()) → nad notifications.fan_out.queue_above (50) príjemcov pošle prácu do frontu po dávkach fan_out.chunk (100). Potom pre každého príjemcu v jednej transakcii:
- Idempotencia — potvrdenka pre kľúč a príjemcu; ak už existuje → Duplicate.
- Kontrola prístupu → NoAccess a udalosť RecipientSkipped.
- Výsledné kanály podľa preferencií používateľa.
- Krok schránky (pozrite Schránka), ak je schránka zapnutá.
- Krok e-mailu (pozrite E-mail), ak je e-mail zapnutý.
Udalosti aj úlohy sa odošlú až po commite: odoslanie v transakcii aplikácie, ktorá sa vráti, nezanechá nič.
Kontexty
Kontext hovorí, kam položka patrí pri filtrovaní — firma, tím, oblasť fakturácie. Prepíše háčik context() druhu:
use RoundlyConsulting\Notifications\Context;
Notifications::send($type, $subject, $users, context: $company); // a model
Notifications::send($type, $subject, $users, context: Context::of($company, 'Acme')); // a model + label
Notifications::send($type, $subject, $users, context: Context::key('billing', 'Billing'));
Notifications::send($type, $subject, $users, context: 'billing'); // key = labelKľúč kontextu z modelu je {alias}:{id} — alias z morph mapy, ak je trieda namapovaná, inak názov triedy v snake_case (company:3) — nikdy názov triedy s menným priestorom, pretože kľúč ide cez sieť. Dve nenamapované triedy s rovnakým názvom zdieľajú priestor kľúčov, preto ich namapujte cez Relation::morphMap. Reťazcový kontext má najviac 191 znakov a nesmie obsahovať spätnú lomku. Popis sa ukladá ako snímka. Kontext nikdy nie je hranicou tenanta.
Idempotencia
->once($key) (alebo send(..., idempotencyKey: $key)) uloží potvrdenku pre každého príjemcu; zopakovanie s rovnakým kľúčom dá týmto príjemcom Duplicate a nič nezapíše. Pripomienky a eskalácie sa odosielajú s vlastnými kľúčmi, takže opakované odoslanie po páde nič nepošle dvakrát. Potvrdenky sa mažú po notifications.idempotency.ttl (P30D).
Eskalácia pri odoslaní
„Ak to do X nikto nepotvrdí, upozorni Y.“ Eskalácie potrebujú subjekt — potvrdenie sa viaže na subjekt:
Notifications::type('request.awaiting_approval')->about($request)->to($approvers)
->once('request:'.$request->id)
->escalate(after: 'P2D', to: Recipients::role($request->company, 'director'))
->escalate(after: 'P5D', to: Recipients::role($request->company, 'board'), type: 'request.overdue')
->send();Každé odoslanie spustí vlastnú reťaz. Opakované odoslanie o jednom subjekte bez kľúča idempotencie spustí reťaz pri každom odoslaní, preto mu dajte once() alebo okno, ak sa môže opakovať. Nečitateľné alebo nekladné oneskorenie vyhodí InvalidReminderRuleException už pri volaní escalate(). Potvrdenie opisuje sekcia Pripomienky a eskalácie.
Dáta
data musí byť čistý JSON — skaláry, null a polia — pod notifications.inbox.max_data_bytes (16 KB). Model, objekt alebo nekonečné desatinné číslo vyhodí InvalidNotificationDataException s cestou k hodnote. data sa ukladá nešifrovane: dávajte doň odkazy, nie tajomstvá.
SendResult
$result = Notifications::send('request.awaiting_approval', $request, $approvers);
$result->type; // the key
$result->outcomes; // list<RecipientOutcome>: recipientKey, recipientType (basename),
// inbox (InboxOutcome), mail (MailOutcome), inboxItemId, deliveryId
$result->queued; // recipients handed to fan-out jobs (their outcomes are not known yet)
$result->inbox(InboxOutcome::Created); // filter by outcome
$result->mail(MailOutcome::Held);
$result->recipients(); // keys reached (not skipped)
$result->skipped(); // no access or a replayed idempotency key| Enum | Hodnoty |
|---|---|
InboxOutcome | Created, Collapsed, Muted, NotInChannels, NoAccess, Duplicate, Queued |
MailOutcome | Pending, Held, Digest, Folded, Deduplicated, Muted, NotInChannels, NoAccess, Duplicate, Queued |
Transakcie a deadlocky
Transakcia každého príjemcu zopakuje deadlock trikrát — ale len vtedy, keď balík vlastní najvonkajšiu transakciu. Vo vnútri transakcie aplikácie Laravel vnorenú transakciu zopakovať nevie: vyhodí výnimku a transakcia aplikácie je stratená. Kde sa dá, posielajte mimo dlhých transakcií, alebo transakciu aplikácie zopakujte sami. Prvé vloženie otvoreného riadku beží pod savepointom, takže prehratý súbeh nikdy nezruší transakciu v PostgreSQL; krok riadok znova načíta a zlúči.
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 kryptomienOdoslaní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.