rileys-cr's avatar

Send Notifications in a Batch

Explanation

I have a Notification that can have optional attachments. I would like the process to be:

  1. user modifies text of notification and optionally attaches file
  2. if file is uploaded, move it to temporary location on server and create an Attachment model
  3. send all notifications as a batch job with attachments if necessary
  4. listen for NotificationSent::class event and check if all notifications have been sent (using $event->notification->batching())
  5. if the batch is finished sending, delete all attachments uploaded for that notification from server

More Details

I have a Notification class called CustomEmail

class CustomEmail extends Notification implements ShouldQueue 
{
    use Queueable, Batchable;
    /* regular notification methods */
}

In EventServiceProvider.php I'm listening for the NotificationSent::class and I made a custom DeleteEmailAttachments handler:

/** EventServiceProvider.php */
protected $listen = [
    NotificationSent::class => [
        DeleteEmailAttachments::class,
    ],
];
/** DeleteEmailAttachments.php */
public function handle(NotificationSent $event): void
{
    Log::debug('finished sending yet? '.($event->notification->batching() ? 'yes' : 'no'));
}

And finally, this is how I've attempted to dispatch the job:

/** EmailController.php */

// create attachment models (simplified a lot of stuff here but this is the general idea)
$attachments = [];
foreach (request()->file('attachments') as $attachment) {
    $attachments[] = App\Models\Attachment::create([
        // attachment data here
    ]);
    Storage::disk('local')->put('tempAttachments/'.$attachment->getClientOriginalName(), $attachment, 'private');
}

// create Collection of users to email
$recipients = User::whereIn('id', $request->userIds)->get();

// dispatch Notification in a batch
Bus::batch([
    Notification::send($recipients, new CustomEmail($request->body, $request->subject, $attachments)),
])->dispatch();

Problem

If I add the ->dispatch() method (as shown above), it gives me an error

Call to a member function withBatchId() on null

If I remove ->dispatch(), the emails get sent, but the batch never gets created (no new rows in the job_batches table). And $event->notification->batching() always returns false.

0 likes
1 reply
rileys-cr's avatar

Has anyone ever sent notifications in batch? It seems like it should be possible but Notifications and Batches don't seem to play nice together...

Please or to participate in this conversation.