4

I have an app where I am sending a push notification which is fine if the user is logged into the application - however, if they're not / if they have not read the notification within X minutes I'd like to send them an email.

The way I am going about this is to use Laravel Notifications to create a mail, broadcast & database notification. On the toMail() method I'm returning a mailable with a delay -

public function toMail($notifiable)
{
    return (new \App\Mail\Order\NewOrder($this->order))
        ->delay(now()->addMinutes(10));
}

After the minutes are up, the email will send but, before the send goes ahead I'd like to perform a check to see if the push/database notification has already been marked as read and if it has cancel the email send. The only way I can think to do this is to bind to the MessageSending event that is baked into Laravel -

// listen for emails being sent
'Illuminate\Mail\Events\MessageSending' => [
    'App\Listeners\Notification\SendingEmail'
],

The only problem is this listener receives a Swift mail event and not the original mailable I was dispatching so I don't know how to cancel it. Any ideas and thanks in advance?

Chris
  • 1,939
  • 1
  • 19
  • 38
  • take a look at "Queues" https://laravel.com/docs/5.7/queues – N69S Sep 24 '18 at 16:47
  • Possible duplicate of [How to cancel queued job in Laravel or Redis](https://stackoverflow.com/questions/48255735/how-to-cancel-queued-job-in-laravel-or-redis) – Devon Bessemer Sep 24 '18 at 16:50
  • Sounds like you should not be dispatching the mailable but dispatching a job that handles the mailable. – Devon Bessemer Sep 24 '18 at 16:52
  • @Devon - perhaps you are right - just feels like a very complex way of sending out an email. I'll take a look! – Chris Sep 24 '18 at 16:53
  • 1
    take look at https://medium.com/@hotmeteor/handling-delayed-notifications-in-laravel-b6699ec30649 – ilyar Dec 13 '18 at 16:44
  • @ilyar that was exactly what I'm looking for! Put it down as an answer and I'll mark as accepted :) – Chris Dec 14 '18 at 12:45

1 Answers1

4

Class extends Notification

public function via($notifiable)
{
    if($this->dontSend($notifiable)) {
        return [];
    }
    return ['mail'];
}

public function dontSend($notifiable)
{
    return $this->appointment->status === 'cancelled';
}

Class EventServiceProvider

protected $listen = [
    NotificationSending::class => [
        NotificationSendingListener::class,
    ],
];

Class NotificationSendingListener

public function handle(NotificationSending $event)
{
    if (method_exists($event->notification, 'dontSend')) {
        return !$event->notification->dontSend($event->notifiable);
    }
    return true;
}

For more details look article Handling delayed notifications in Laravel

ilyar
  • 1,331
  • 12
  • 21