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

Druhy notifikácií

Druh je jeden typ notifikácie so stabilným kľúčom (request.awaiting_approval): kategória, kanály, priorita, či je povinný alebo patrí do súhrnu, okno zlučovania, subjekt, ktorého sa týka, a spôsob vykreslenia. Napíšte ho ako malú final triedu, ktorá rozširuje NotificationType, a uveďte ju v konfigurácii — povinné sú len key() a title():

// config/notifications.php
'types' => [
    App\Notifications\Types\RequestAwaitingApproval::class,
    App\Notifications\Types\ContractExpiring::class,
    App\Notifications\Types\SecurityAlert::class,
],

Povinný, urgentný a citlivý druh — nikto ho nestlmí, tiché hodiny ho nepodržia a jeho e-mail neobsahuje žiadne podrobnosti:

use Illuminate\Database\Eloquent\Model;
use RoundlyConsulting\Notifications\Enums\Priority;
use RoundlyConsulting\Notifications\NotificationPayload;
use RoundlyConsulting\Notifications\NotificationType;

final class SecurityAlert extends NotificationType
{
    public function key(): string { return 'security.alert'; }
    public function category(): string { return 'security'; }
    public function mandatory(): bool { return true; }                 // nobody can mute it
    public function priority(): Priority { return Priority::Urgent; }  // never held by quiet hours
    public function sensitive(?Model $subject): bool { return true; }  // a title + link mail only

    public function title(NotificationPayload $p): string
    {
        return __('app.security_alert', ['what' => $p->data['what'] ?? 'activity']);
    }

    public function url(NotificationPayload $p): ?string { return route('account.security'); }
}

Háčiky a predvolené hodnoty

MetódaPredvolenéVýznam
key(): stringabstract^[a-z0-9_]+(\.[a-z0-9_]+)*$, najviac 100 znakov — nikdy nevyzerá ako názov triedy.
title(NotificationPayload): stringabstractNadpis v schránke a predmet e-mailu.
category(): stringgeneralRovnaký vzor; zoskupuje maticu preferencií a filtre schránky.
label(): stringváš riadok notifications.types.<key>.label, inak kľúč s veľkými začiatočnými písmenamiPrekladá sa pri čítaní.
description(): ?stringváš riadok notifications.types.<key>.description, inak null—
channels(): list<Channel>[Channel::Inbox, Channel::Mail]Aspoň jeden.
enabledByDefault(Channel): booltruefalse urobí kanál voliteľným (opt-in).
mandatory(): boolfalseIgnoruje každé stlmenie; zápis, ktorý by ho stlmil, vyhodí MandatoryNotificationException.
priority(): PriorityNormalLow / Normal / Urgent. Urgent obíde tiché hodiny, súhrny aj odosielanie na konci okna.
digestible(): boolfalseSúhrn vyžaduje Low a digestible; digestible druh bez Low sa pri registrácii odmietne.
window(): CarbonInterval|string|nullnullISO-8601 alebo relatívne ('10 minutes'), najviac jeden deň. null: žiadne zlučovanie ani deduplikácia.
mailStrategy(): MailStrategymail.strategyTrailing čaká na koniec okna; urgentné druhy idú vždy hneď.
subject(): ?stringnullTrieda modelu subjektu. Odoslanie s inou triedou vyhodí InvalidNotificationSubjectException; druh bez subjektu subjekt odmietne.
subjectFrom(Notification): ?ModelnullLen pre interop — subjekt notifikácie iného balíka.
canAccess(Model $recipient, ?Model $subject): boolGate notifications.access.abilityPozrite Príjemcovia a prístup.
allowsTrashedSubject(): boolfalseSoft-deleted subjekt sa pri každom kroku považuje za neexistujúci, ak to nie je true.
minimalTitle(): stringnotifications::mail.minimal_subjectPredmet minimálneho e-mailu.
context(?Model $subject)nullContext, model alebo reťazec — predvolený kontext, keď ho odosielateľ neuvedie.
notifyActor(): boolfalseAktér sa vyradí z príjemcov, ak to nie je true.
sensitive(?Model $subject): boolfalseMinimálny e-mail: len nadpis a odkaz.
body(NotificationPayload): ?stringnullPrvý riadok e-mailu (inak nadpis).
url(NotificationPayload): ?stringnullLen absolútne http(s) — nič iné sa nikdy nevykreslí.
actionText(NotificationPayload): stringnotifications::mail.viewText tlačidla.
digestLine(NotificationPayload): stringtitle()Riadok v súhrne.
mail(MailMessage, NotificationPayload): MailMessagebez zmenyPosledný háčik na úpravu e-mailu (pri minimálnom e-maile sa nevolá).
publicData(array $data): array$dataČo InboxItemResource zverejní ako data.
reminders(): list<ReminderRule>[]Pozrite Pripomienky a eskalácie.

Payload

Každý háčik na vykreslenie dostane final readonly NotificationPayload. Všetko, čo musí prežiť zmazanie subjektu, čítajte zo subjectKey a data:

public function title(NotificationPayload $p): string
{
    $p->type;         // 'request.awaiting_approval'
    $p->recipient;    // the recipient model
    $p->subject;      // the fresh subject — null when it is gone
    $p->subjectKey;   // survives the subject's deletion
    $p->actor;        // the latest actor
    $p->context;      // ?ContextReference: key, label, type, id
    $p->data;         // the latest event's data
    $p->count;        // events collapsed into this item or mail
    $p->firstAt;      // CarbonImmutable, UTC
    $p->lastAt;
    $p->channel;      // Channel::Inbox or Channel::Mail
    $p->escalated;    // true on an escalation send
    $p->reminder;     // ?ReminderReference: id, rule, offset ('-P30D'), dueAt, level

    return trans_choice('app.awaiting', $p->count, ['ref' => $p->data['reference'], 'count' => $p->count]);
}

Nadpisy, texty a URL v schránke sa vykresľujú pri čítaní v jazyku čitateľa zo živého druhu. Každý zápis do schránky si navyše uloží snímku nadpisu a URL v jazyku príjemcu; resource ju použije, keď druh už nie je zaregistrovaný alebo jeho vykreslenie vyhodí výnimku.

Fluentné druhy

Druh bez triedy, zaregistrovaný v boot() service providera:

use RoundlyConsulting\Notifications\Enums\Priority;
use RoundlyConsulting\Notifications\Facades\Notifications;
use RoundlyConsulting\Notifications\NotificationPayload;

// AppServiceProvider::boot()
Notifications::define('comment.posted')
    ->category('comments')
    ->priority(Priority::Low)
    ->digestible()
    ->window('PT10M')
    ->subject(Post::class)
    ->title(fn (NotificationPayload $p): string => trans_choice('app.comment', $p->count, ['count' => $p->count]))
    ->url(fn (NotificationPayload $p): ?string => route('posts.show', $p->subjectKey))
    ->register();

Každý háčik triedy má v TypeBuilder svoj náprotivok:

use RoundlyConsulting\Notifications\Enums\Channel;
use RoundlyConsulting\Notifications\Enums\MailStrategy;

Notifications::define('report.ready')
    ->label('Report ready', 'When an export you requested has finished.')
    ->channels(Channel::Inbox, Channel::Mail)
    ->optIn(Channel::Mail)                                   // mail off until the user switches it on
    ->mailStrategy(MailStrategy::Trailing)
    ->window('PT15M')
    ->subject(Report::class, allowsTrashed: true)
    ->access(fn (User $recipient, ?Report $report): bool => $report?->owner_id === $recipient->id)
    ->context(fn (?Report $report) => $report?->workspace)
    ->sensitive(fn (?Report $report): bool => $report?->confidential === true)
    ->body(fn (NotificationPayload $p): ?string => __('app.report_ready_body'))
    ->mail(fn (MailMessage $message, NotificationPayload $p): MailMessage => $message->line(__('app.report_expiry')))
    ->register();
MetódaVýznam
category($category)Kategória.
label($label, $description = null)Pevný popis a opis (trieda ich číta z vašich prekladov).
channels(Channel ...$channels) / optIn(Channel $channel)Kanály; optIn() jeden predvolene vypne.
mandatory() / priority(Priority) / digestible()Príznaky zodpovedajúce háčikom triedy.
window($window) / mailStrategy(MailStrategy)Okno zlučovania a stratégia e-mailov.
subject($class, allowsTrashed: false)Trieda subjektu (a či sa ráta aj soft-deleted).
notifyActor()Ponechá aktéra medzi príjemcami.
title(fn) / body(fn) / url(fn)Closures na vykreslenie, dostanú NotificationPayload. Bez title() je nadpisom popis.
access(fn ($recipient, $subject): bool)Vlastná kontrola prístupu namiesto Gate.
context(fn ($subject)) / sensitive(fn ($subject): bool)Predvolený kontext; minimálny e-mail.
mail(fn ($message, $payload)) / subjectFrom(fn ($notification))Úprava e-mailu; subjekt pre interop.
reminders(ReminderRule ...$rules)Pravidlá pripomienok.
make(): DefinedType / register(): voidZostaví druh, alebo ho zostaví a zaregistruje.

Registrácia

Notifications::register(RequestAwaitingApproval::class, SecurityAlert::class);   // class-strings
Notifications::registerType(app(RequestAwaitingApproval::class));                  // an instance

$type = Notifications::define('digest.preview')->title(fn () => 'Preview')->make(); // a DefinedType, not registered
Notifications::registerType($type);

// Anywhere a type key is accepted, a type class-string works too
Notifications::type(RequestAwaitingApproval::class)->about($request)->to($approvers)->send();
  • Druhy v config('notifications.types') sa načítajú lenivo pri prvom použití a vytvárajú sa cez kontajner, takže môžu mať závislosti v konštruktore.
  • Validácia beží pri registrácii bez I/O, takže package:discover funguje aj pred migráciou.
  • Register platí pre jeden proces; úlohy vo fronte si druhy znovu nájdu podľa kľúča a neznámy kľúč pri doručení riadok zruší (unknown_type).
  • Všade, kde sa prijíma kľúč druhu, funguje aj class-string druhu.
PríčinaVýnimka
Kľúč či kategória mimo vzoru; digestible druh, ktorý nie je Low; okno, ktoré nie je kladná doba najviac jeden deň; žiadny kanál; subjekt, ktorý nie je modelInvalidNotificationTypeException
Druhá registrácia toho istého kľúča — s oboma zdrojmi podľa názvu triedy alebo define()DuplicateNotificationTypeException
Pravidlá pripomienok na druhu bez subjektu, prázdny atribút, 0 alebo viac než 25 posunov, duplicitný kľúč pravidla, at() v pravidle druhuInvalidReminderRuleException
Kľúč, ktorý nikto nezaregistroval (pri odoslaní, find(), zápise preferencie)UnknownNotificationTypeException

Zoznam pre obrazovku nastavení

Notifications::types()->all();          // list<TypeDefinition>: key, category, label, description, channels,
                                        //   defaultChannels, mandatory, priority, digestible
Notifications::types()->categories();   // list<CategoryDefinition>: key + label
Notifications::types()->find($key);     // TypeDefinition
Notifications::types()->has($key);      // bool
Notifications::types()->get($key);      // the NotificationType itself

Popisy kategórií pochádzajú z vášho riadku notifications.categories.<key>, inak zo záložného prekladu balíka pre general, inak z kľúča s veľkými začiatočnými písmenami. Register vypíše príkaz:

php artisan notifications:types   # Key, Category, Channels, Priority, Flags, Window, Reminder rules

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.