[when send emails shows these error][1]ReflectionException Method App\Mail\Newsletter::__invoke() does not exist
these is my controlledispatch(new Newsletter($emailSubject,$emailBody,$arrayEmails));
these is my email classpublic function build() { return $this->view('emails.newsletter')->subject($this->emailSubject)->with(['msg'=> $this->emailBody]); }
these is my jobs public function handle() { $email = new Newsletter($this->emailSubject,$this->emailBody,$this->arrayEmails); Mail::to($this->arrayEmails)->send($email); }
As I understand, you create a job that in turn create and send the email object.
However, in the controller, you are not dispatching the job, you are dispatch the email object. And the email object doesn't contain either a handle or __invoke method so you see the error message.
The solution is to dispatch the job instead of the email.
This design is indeed unnecessary. Pls have a look at Mailables, create a queued mailable, and just send it.
Related
In my app with Laravel on back-end users can send messages to each other.
I want to send push notification to app users on new inbox message, but I need to send messages only if user hadn't already read this message.
So I see it that way
On every message sended I need to schedule Laravel notification after 1 minute
if user already received this message I need to cancel this notification
How can dismiss scheduled notification in Laravel? Is this approach fine and actual now?
Class extends Notification
public function via($notifiable)
{
if($this->dontSend($notifiable)) {
return [];
}
return ['mail'];
}
public function dontSend($notifiable)
{
return $this->appointment->status === 'cancelled';
}
Maybe there is more convenient way to handle it? For example, to send push every time but somehow dismiss it showing from app if it's already launched?
One way to do it would be something like this;
Before you trigger your notification create a unique identifier(sha1 could be an option) with the combination of user_id. Let's say it is SgiA7EfBQBFQK3pjRWtaxB1CkSf7gf4lSixvei3jU3ydHJ39ZGjhhdUUCnHRno3C. Send it to the notification. Both notification and message will be send at the same time, but notification will have one minute delay.
$identifier = Str::random(64);
$delay = now()->addMinute();
$user->notify((new MyNotification($identifier))->delay($delay));
// send a request that contains identifier.
You set this to the Redis with TTL of 2 minutes. It will be gone if there is no action.
Redis::set('SgiA7EfBQBFQK3pjRWtaxB1CkSf7gf4lSixvei3jU3ydHJ39ZGjhhdUUCnHRno3C', 1, 120);
While sending a message to the user, attach this identifier to the message. When user read that message, you make a request to your /read endpoint with all the parameters + the identifier.
When you receive the request, delete the key from Redis. (user received the message)
Redis::del('SgiA7EfBQBFQK3pjRWtaxB1CkSf7gf4lSixvei3jU3ydHJ39ZGjhhdUUCnHRno3C');
In your Notification class, implement a small method to check whether the key exists in Redis.
Redis::exists('SgiA7EfBQBFQK3pjRWtaxB1CkSf7gf4lSixvei3jU3ydHJ39ZGjhhdUUCnHRno3C');
class MyNotification extends BaseNotification
{
use Queueable;
private $identifier;
public function __construct($identifier)
{
$this->identifier = $identifier;
}
public function via()
{
return $this->isValid() ? ['mail'] : [];
}
public function isValid()
{
return Redis::exists($this->identifier);
}
public function toMail()
{
// details..
}
}
It doesn't have to be Redis but it is a perfect match for these kind of key/value structure.
How can I send email and SMS together using Laravel 5.5 ?
Should I use mailable and SMS service or Notification with SMS and How ?
You can create an event in laravel's App/Events folder.
put all the code for send mail and sms with there configuration, just call that event wherever you want to hit sms or mail.
You may create one function which will include both notify() method for an email and dispatch() method for message
example
public function Notification(Model $tender)
{
$user = access()->user();
/* Send confirmation email */
$tender->notify(new Email($user));
/* Send confirmation message */
Send::dispatch($user);
}
Then you will just call a single function that is Notification() which will do both sending email and message
I have a unit test with the following:
use \Illuminate\Notifications\DatabaseNotification;
public function testMailSentAndLogged()
{
Notification::fake();
$user = factory(User::class)->create();
$emailAddress = $user->emailAddress;
$emailAddress->notify(new UserCreated);
Notification::assertSentTo(
$emailAddress,
UserCreated::class
);
error_log('DatabaseNotification '.print_r(DatabaseNotification::get()->toArray(), 1));
$this->assertEquals(1, $emailAddress->notifications->count());
}
My Notification has this for the via():
public final function via($notifiable)
{
// complex logic...
error_log('mail, database');
return ['mail', 'database'];
}
The code fails on the $this->assertEquals code. the error_log produces the following:
[03-Jan-2018 01:23:01 UTC] mail, database
[03-Jan-2018 01:23:01 UTC] DatabaseNotification Array
(
)
WHY don't the $emailAddress->notifications pull up anything? Why doesn't DatabaseNotification::get() pull anything?;
In your test, you are calling the method
Notification::fake();
As stated in Laravel's documentation on Mocking,
You may use the Notification facade's fake method to prevent
notifications from being sent.
Actually, this bit of code is the assertion that the Notification would have been sent, under normal circumstances (ie in prod) :
Notification::assertSentTo();
If you remove the call to Notification::fake(), your notification should appear in your testing database.
So you kinda have two solutions. The first one is to remove the call to fake(), thus really sending the notification, which will appear in the database. the second is not to test if the notification was written successfully in the database : it's Laravel's responsibility, not your application's. I recommand the second solution :)
What would be the best approach to send an email notification to a user after my chain of jobs are finished ?
I am using Laravel 5.5 & horizon queues.
My method where user is being validated and a chain of jobs are being fired:
public function activateUser($token)
{
if ($user = $this->activationService->activateUser($token)) {
CheckIfDown::withChain([
(new ScanOne($user))->onQueue('new-user'),
(new ScanTwo($user))->onQueue('new-user'),
(new ScanThree($user))->onQueue('new-user'),
(new FirstScanFinished($user))->onQueue('new-user') // What I've tried - this job should send an email from it's handle() method.
])->dispatch($user)->onQueue('new-user');
return redirect('/login')->with('message', 'You have successfully completed the registration process!');
// return redirect($this->redirectPath());
}
abort(404);
}
These specific chain of jobs are only fired once the user validates his email address. Email should be sent only once.
FirstScanFinished handle method
public function handle()
{
$message = (new FirstScanFinished($this->user));
$email = $this->user->email;
Mail::to($email)
->send($message);
}
All the jobs appears to be successfully fired, but I don't get any email in my mailtrap(just to note all my smtp settings are good and emails in other places are firing of without any problems). I also don't get any error in my logs. How should I approach this ?
I've an application that sends a mail to list of emails after submit the form. For this I'm using queue jobs to send mail to that list in the background. I'm using SMTP for this with mailtrap. I'm new to this queue jobs functionality.
this is my controller code to dispatch queue:
public function sendMail(Request $request)
{
$lists = List::where('list_id',$request->list_id)->pluck('email')->toArray();
$jobs = (new SendEmailToList($lists));
$this->dispatch($jobs);
return 'success';
}
And this is my job functionality in queue :
public function handle()
{
$lists = $this->lists;
Mail::send('email.test', array('email' => 'Sample'), function ($message) use ($lists) {
$message->to($lists);
});
}
I've a program file in the supervisor of my Linux system to queue:listen.
I've done all things but still it's not sending mail to all the list of emails. I've referred many of documentations but still same issue, all the documents given that to implement a QueueManager.
You should probably call Mail::queue or Mail::later instead of Mail::send.
Please refer to Mail documentation in case you've been missing something else.