Overview
Opscale\NotificationCenter\Jobs\ExecuteNotificationStrategy is the central orchestration job for multi-channel notification delivery. When dispatched, it iterates over every audience attached to a notification, resolves the profiles in that audience, and — per profile — either dispatches the first-channel delivery or escalates to the next channel in the configured strategy.
Class signature
Constructor
The
Notification model whose delivery strategy should be executed. The job reads the notification’s type to look up the correct strategy block in config('notification-center.strategies') and places itself on the appropriate queue.How it works
Load strategy config
handle() reads the full strategy array for the notification type:channels is empty the job returns immediately without creating any deliveries.Iterate audiences and profiles
The job loops over every
Audience relationship on the notification. For each audience it calls getProfiles() and eager-loads only the deliveries belonging to this notification, ordered by creation time:Process each profile
processProfile() decides what to do for a single profile:- No prior deliveries — creates a
Deliveryrecord with statusPENDINGon the first channel and callssendDelivery(). - Latest delivery is
OPENEDorVERIFIED— skips the profile; no further action needed. - Latest delivery is any other status — calls
resolveNextChannel()to determine whether enough time has elapsed to escalate.
Resolve channel escalation
resolveNextChannel() returns the next channel string, or null if escalation should not happen yet:- The current channel is not found in the strategy’s
channelsarray. - There is no next channel (the current channel is already last).
- The elapsed available hours since the latest delivery was created is less than
timeout_per_channel.
Calculate available hours
calculateAvailability() counts only the hours that fall within the strategy’s allowed days and hours window:Dispatch the delivery
sendDelivery() looks up the notification class for the channel from config('notification-center.messages'), instantiates it, resolves the recipient subscription, and calls notify():Strategy configuration reference
The job reads its settings from thenotification-center.strategies.<type> config block. All keys are optional and fall back to defaults shown below.
| Key | Type | Default | Description |
|---|---|---|---|
queue | string | 'notifications' | Laravel queue name for this strategy |
channels | string[] | [] | Ordered list of channels to attempt |
timeout_per_channel | int | 24 | Hours of available time before escalating to the next channel |
days | int[] | [0,1,2,3,4,5,6] | Allowed days of the week (0 = Sunday) |
hours | string[2] | ['00:00','23:59'] | Allowed time window in 24 h format [from, to] |
max_attempts | int | — | Maximum delivery attempts per channel (used by SendDelivery) |
retry_interval | int[] | — | Seconds between retries (escalating array supported) |
Scheduler
The job is invoked by the hourly scheduler for every published, non-expired notification. This means channel escalation is checked at most once per hour per notification — thetimeout_per_channel value should be set in whole-hour increments for predictable behavior.
The scheduler only dispatches
ExecuteNotificationStrategy for notifications whose status is Published. Drafts and notifications past their expiry date are skipped.Queue configuration
Each strategy maps to a dedicated queue. The built-in strategies use the following queues:| Strategy | Queue |
|---|---|
marketing | notifications-marketing |
transactional | notifications-transactional |
system | notifications-system |
alert | notifications-alert |
reminder | notifications-reminder |