How can I make the laravel queue retry only failed notification channels instead of retrying the whole notification? - laravel

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.

Related

Laravel Echo with Pusher and Livewire - not receiving notifications client-side

I'm able to broadcast a notification to Pusher, but I'm unable to receive the response back in my livewire component.
Here is my Notification class:
<?php
namespace App\Notifications;
use App\Models\Statement;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class StatementCompletedNotification extends Notification implements ShouldQueue, ShouldBroadcast
{
use Queueable;
public $statement;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct(Statement $statement)
{
$this->statement = $statement;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['database', 'broadcast'];
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return [
'user_id' => $this->statement->uploadedBy->id,
'statement_id' => $this->statement->id,
'file_name' => $this->statement->original_file_name
];
}
/**
* Get the channels the event should broadcast on.
*
* #return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('users.' . $this->statement->uploadedBy->id);
}
}
And here is the getListeners() method on my Livewire component. I've tried several different things here, first off I tried the way it's shown in the docs, just by referencing my StatementCompletedNotification in the listener, like so:
public function getListeners()
{
return [
"echo-private:users.{$this->user->id},StatementCompletedNotification" => 'refreshNotifications'
];
}
I noticed that in pusher, my event type is listed as Illuminate\Notifications\Events\BroadcastNotificationCreated, and I found this post online, so I tried that method like so:
public function getListeners()
{
return [
"echo-private:users.{$this->user->id},.Illuminate\\Notifications\\Events\\BroadcastNotificationCreated" => 'refreshNotifications'
];
}
Neither way has worked for me.
Here's where I'm attempting to just get something back in my javascript on the client-side:
Echo.private('users.1')
.notification((notification) => {
console.log(notification);
});
I don't get any response and I have no idea what the problem is. I've spent an insane amount of time on this and can't seem to figure it out.
Also, it appears that my notification is being picked up multiple times in the queue:
A little more background, the flow that I have set up right now is basically:
StatementCompleted event gets fired (not queued), there's a listener that handles the StatementCompleted event which is queued, and calls my StatementCompletedNotification class like so:
public function handle($event)
{
$event->statement->uploadedBy->notify(new StatementCompletedNotification($event->statement));
}

Laravel 8 Jestream Notifiable Sending email to non existing user does not work

I am using Laravel 8 Jetstream.
Given that I am using an additional and external database, I need to send email notifications to users, whose info is in that external database, where the email column name is different; let's say "electronicmail".
In the official docs it says:
Remember, you may use the Notifiable trait on any of your models. You
are not limited to only including it on your User model.
So I got this external model:
ExternalUser.php
<?php
namespace App\Models\ExternalDatabase;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;
class ExternalUser extends Model
{
use Notifiable;
/**
* External DB connection
*
* #var string
*/
protected $connection='externalissima';
/**
* The table associated with the model.
*
* #var string
*/
protected $table='External-users';
/**
* Indicates whether or not the model should be timestamped.
*
* #var bool
*/
public $timestamps = false;
}
That external External-users table does not have the email column, but as electronicmail.
So, whenever I use:
$ext_user->notify(new \App\Notifications\Test());
The \App\Notifications\Test() notification class is not working, since I guess because there's no exact email column name.
Then how do I customize the email column to make it work?
After hours of searching, I have read also in the same docs that you can make use of on-demand notifications like so:
Route::get('notification', function (){
Auth()->user()->notify(new \App\Notifications\Test()); //THIS IS WORKING
Illuminate\Support\Facades\Notification::route('email',
['tester#mail.com','John Doe']
)->notify(new \App\Notifications\Test()); //THIS, what I need, IS NOT WORKING, why???
});
And my test notification looks like:
Notifications/Test.php
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class Test 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)
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->subject('Test notification')
->line('The introduction to the notification.')
->action('Notification Action', url('/'))
->line('Thank you for using our application!');
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return [
//
];
}
}
In my case, the notifications for the models/User.php are working fine.
However,
Illuminate\Support\Facades\Notification::route('email',
['tester#mail.com','John Doe']
)->notify(new \App\Notifications\Test());
this is not working with on demand notifications with a custom email, why?
How do I fix this? What am I missing?

how to fix the correct url in the button of email laravel notification?

i'm using laravel mail notification and i have problem in the url button i have http://127.0.0.1 instead of http://127.0.0.1:8000 and when i clic at the button in email i redirected in failued url because :8000
is missed.
how i can fix this problem please ?
this my code in notification class
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\BroadcastMessage;
use Illuminate\Notifications\Notification;
class NewProject extends Notification implements ShouldQueue
{
use Queueable;
public $data;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct($data)
{
$this->data=$data;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->line('New Project :' . $this->data['projet'])
->action('New project', url('/detail/'.$this->data['id']))
->line('Thank you for using our application!');
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toDatabase($notifiable)
{
return [
//
];
}
}```
The base app URL is configured inside the .env file on the variable APP_URL. So you must set:
APP_URL=http://127.0.0.1:8000
In your environment file.

Why is the data column empty? Laravel Notifications

I am trying to set up database notification, but the data I am sending for the 'data' column isn't showing up...
My notification class:
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use App\User;
use App\Admin;
class UserAddedToStudio extends Notification implements ShouldQueue
{
use Queueable;
public $user;
public $admin;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct(User $user, Admin $admin)
{
$this->user = $user;
$this->admin = $admin;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['mail', 'database'];
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->subject('Welcome to '.$this->admin->name.'\'s studio')
->line('Hi '.$this->user->name.'. Your request to join '.$this->admin->name.'\'s studio has been accepted! Now you can start registering for lessons.')
// ->action('Notification Action', url('/'))
->line('Thank you for using our application!');
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toDatabase($notifiable)
{
return [
'message' => 'You have been added to the studio'
];
}
}
In my notifications table on MySQL all the columns are filled except for the data column. There I only get an empty array []. but why?? so frustrating.... :(
Here is the screenshot from my phpmyadmin.
Try to use toArray() instead of toDatabase()
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return [
'message' => 'You have been added to the studio'
];
}
as you use Queue you should restart the queue worker.
php artisan queue: work
Remember, queue workers, are long-lived processes and store the booted application state in memory. As a result, they will not notice changes in your code base after they have been started. So, during your deployment process, be sure to restart your queue workers. In addition, remember that any static state created or modified by your application will not be automatically reset between jobs.

Laravel email messed up

I am using the default email template, and there is are cases that the email is gibberish/messed up.
Additional information on the problem:
Occur when viewing in IOs app mail (rarely to a person)
Opening the mail in gmail gives no problem
using SMTP
Question is, what can I do to fix this problem and make sure it does not happen again. Whether changes in SMTP setting etc?
As per the code:
<?php
namespace Framework\Notifications\User;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
class AuthenticationLink extends Notification// implements ShouldQueue
{
use Queueable;
protected $name;
protected $link;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct($name, $link)
{
$this->name = $name;
$this->link = $link;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->subject(__('mail/authentication.System Authentication'))
->greeting(__('mail/default.Hello').' '.$this->name)
->line(__('mail/authentication.Please click the link below to confirm your email and begin using System'))
->action(__('default.Confirm'), $this->link);
}
I have been looking through google search and asking help in Laravel Discord and Laravel FB Group. Still nothing at the moment.
Any help will do. Thank you very much.

Resources