rileys
rileys

Reputation: 91

Laravel: 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.

Upvotes: 1

Views: 385

Answers (1)

Avishek Dangol
Avishek Dangol

Reputation: 1

My solution is to first create a job that sends the notification and dispatch the job.

Suppose you created a job SendEmailJob, then you can do the following:

Bus::batch([
    new SendEmailJob($parameters)
])->dispatch();

Upvotes: 0

Related Questions