My laravel notification has to send messages to 2 channels. But when one channel failed, both channel was been resending message by queue. Is there anyway to solve this without creating a deferent notification?
I try to read from docs but I didn't find any answer. The expected result is to only retry failed channel messages when notification being resent by queue.
As Asked by @matiaslauriti the code in notification are the followings: (Laravel 9, php8.1)
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use App\Mail\MyMail;
class LineLoginNotification extends Notification implements
ShouldQueue
{
use Queueable;
/**
* Create a new notification instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
// Attempt to send the notification via email and MyChannel
return ['mail' , MyChannel::class ];
}
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return Mailable
*/
public function toMail($notifiable)
{
return (new MyMail($notifiable))->to($notifiable->email);
}
/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
* @return array
*/
public function toArray($notifiable)
{
return [
//
];
}
/**
*
*/
public function toMyChannelMethod($notifiable){
$msg = "myMsg";
return $msg;
}
}
The code of the channel is
<?php
namespace App\Notifications;
use App\Services\MyMessageService;
class MyChannel
{
/**
* Send line notification
* @param $notifiable
* @param $notification that implements toMyChannelMethod() method
* @return void
*/
public function send($notifiable, $notification)
{
$line_id = $notifiable->line_id;
$msg = $notification->toMyChannelMethod($notifiable);
$messageService = new MyMessageService();
$messageService->sendSimpleMsg($msg, $line_id);
}
}
As far as I know Laravel creates separate queued jobs for each channel implemented in queued notifications. When executed by horizon or the default laravel worker each of these jobs instantiates \App\Notifications\LineLoginNotification separately for each channel, 'mail' and MyChannel in your case. So, you should not bother that failing in sending by one notification channel might cause fail in other channels. They don't interfere as long as your notification implements ShouldQueue interface.
Update: by the way, maybe you are already aware of but just FYI, you should add an attribute
public $tries = 3; // number of retries
to your notification class \App\Notifications\LineLoginNotification or indicate 'tries' attribute in your horizon configuration (config/horizon.php) in order a failed notification to be retried by queue worker.