How can i send mailable into schedule in Laravel - php

i'm trying to send a mailable into schedule, but the mail is ommited when schedule is execute
$schedule->call(function () {
Log::debug("START TEST MAIL"); //this is write in log
$result = Mail::to('myemail#gmail.com')->send(new MailRecover('12345678aZ*'));
Log::debug("END TEST MAIL, RESULT: $result"); //this is write in log
})->everyMinute();
i put the same lines of codes (the logs and the mailable) in a controller and work perfectly, but in the schedule (kernel.php) doesnt work (only write every minute the two logs).

If you want to use closure command, add it to routes/console.php:
Artisan::command('send:email', function ($project) {
Log::debug("START TEST MAIL"); //this is write in log
$result = Mail::to('myemail#gmail.com')->send(new MailRecover('12345678aZ*'));
Log::debug("END TEST MAIL, RESULT: $result"); //this is write in log
});
Then run it in scheduler:
$schedule->call('send:email')->everyMinute();

Related

Laravel run something when create a job

when I create a job and before start it , I need run a function ,
i update the class DatabaseJob
<?php
namespace App\Queue\Jobs;
use App\Models\Tenancy;
use App\Http\DatabaseHelper;
use App\Http\Helper;
class DatabaseJob extends \Illuminate\Queue\Jobs\DatabaseJob
{
public function fire()
{
Helper::createJobLog($this->job->id);
parent::fire();
}
}
but it seems the function createJobLog is fired only when the Job start ,I need it when the job created not started .
In a service provider you can listen for the Illuminate\Queue\Events\JobQueued event. Something similar to:
Event::listen(JobQueued::class, function ($event) {
// Of course, if you need to log only the database jobs then you can check the job type
if (!$event->job instanceOf DatabaseJob) {
return;
}
Helper::createJobLog($event->job->getJobId());
});
You may call the function createJobLog() when the job is dispatched. Jobs can be set with a timestamp to delay its start time, if you don’t want the job started immediately after it is being dispatched.

Laravel 8 Schedule Task not sending Email on Cpanel

I would like to send an email via task scheduler every minute using Laravel 8.
Below is my code on Kernel.php
$schedule->call(function () {
$adminController = new AdminController();
$adminController->test();
})->everyMinute();
On the Admin Controller I have a method called test
public function test()
{
try {
$fp = fopen('cronJobTest.txt', 'a');
fwrite($fp, "Testing Started. ");
fclose($fp);
$email = new \stdClass();
$email->subject = "Cron Job Test";
$email->greetings = "Hi, Tested";
$email->message1 = "This is a cron job tester";
$email->btn_text = 'Test';
$email->message2 = "";
$email->url = "dashboard/test";
\Illuminate\Support\Facades\Notification::route('mail', 'myemailaddressHere#gmail.com')->notify(new EmailNotification($email));
}catch (Exception $exception){
$fp = fopen('cronJobTest.txt', 'a');
fwrite($fp, "Failed with exception ".$exception->getMessage());
fclose($fp);
}
}
On my local machine I then run the command:
php artisan schedule:work
An email is sent to the provided email address as expected.
However, after uploading the source code to shared hosting cpanel and setting up the Cron Job, the scheduler does not send an email.
I am sure the method test() is fired because if you look at the test() method, I am creating a file 'cronJobTest.txt' everytime the method is called and appending the text 'Test Started'.
In my web routes I have created a route to direct to the test() method and if I call the method via the route, an email is sent. ie https://mylaraveldomain.com/test
Route::get("test", [AdminController::class, 'test']);
However the same same method does not send an email if fired from the scheduler.
What might be causing this?
Do you have a cron in your server? If not, then that is the problem. Refer to this page.
Edit: Have you confirmed that the cron is running properly? If not, put an everyMinute job that logs something first. Check first if the log shows up.

Laravel 5 - Setting Kernel to run test script at regular intervals. (Cron job)

In my laravel project, I have this file in my tests directory:
tom_test.php:
<?php
error_log("hello world");
I want to schedule this script to run every 'x' amount of time.
I've seen this question from cyber8200.
Unfortunately, I'm unsure how to make this test script to run.
Do I have to convert the test file to a class instead?
I would appreciate it if somebody would explicitly state what code needs to be added to the app/Console/Kernel.php file.
I suspect it should resemble some of the code in the cyber8200 question
UPDATE
Thanks to Tim Lewis' comment, I've managed to get the cron job running (I think).
Unfortunately, I cannot see the "hello world" message being logged to the console.
Here is what I've done
I added a command as follows:
public function handle()
{
error_log("hello");
// echo base_path();
exit;
include base_path().'/tests/Browser/tom_test.php';
}
and this schedule function to the kernel:
protected function schedule(Schedule $schedule)
{
$schedule->command('tom_test')
->everyMinute();
}
This is the result I get:
The job seems to be quitting after one run, and no message is logged to the console.

Laravel Config::set() does not seem to work with Queued Jobs

I need to modify the mail SMTP parameters such as MAIL_HOST and MAIL_USERNAME dynamically.
For, this I am using Config::set() to set these values dynamically.
# This code works
Config::set('mail.host', 'smtp.gmail.com');
Mail::to('user#example.com')->send(new myMailable());
The above code works if I do not queue the mail.
The moment I queue it, it appears that Config::set() fails to set the values.
Test to confirm Config::set() not working with queued jobs -
I created a simple job and put the below code in the handler.
public function handle()
{
# set the config
Config::set('mail.host', 'smtp.gmail.com');
# confirm config has been set correctly
logger('Setting host to = [' . config('mail.host') . ']');
}
The above code creates the below log entry.
Setting host to = []
Why can I not change the Config on-the-fly for queued jobs? And how to solve this?
This is because the Queue worker doesn't use the current request. It is a stand-alone process, not being interferred by config settings.
To let this work, you need to use a Job. The dispatch function takes your data and sends it through to the job itself. From your controller, call:
JobName::dispatch($user, $settings);
In the job you set the variables accordingly:
public function __construct($user, $settings)
{
$this->user = $user;
$this->settings = $settings;
}
Then in the handle method:
\Notification::sendNow($this->user, new Notification($this->settings));
You can use a normal notification for this.
Do not for get to add implements ShouldQueue to your job!

Sending bulk emails using different credentials

I need to send hundreds of emails using different credentials from laravel.
Each customer of mine has his/hers mail list and needs to provide their own SMTP server. I process that list and send emails on customer's behalf.
This is what I have so far. It is working, but it is very slow and I don't have many emails so far. I see a problem when I get more emails.
Any suggestions on how to improve?
PS- I use cron Console Command and use Kernel to schedule the job.
public function sendMailings($allMailings) {
foreach ($allMailings as $email) {
Config::set('mail.host', $email['smtpServer']);
Config::set('mail.port', $email['smtpPort']);
Config::set('mail.username', $email['smtpUser']);
Config::set('mail.password', $email['smtpPassword']);
Config::set('mail.encryption', $email['smtpProtocol']);
Config::set('mail.frommmail', trim($email['fromEmail']));
Config::set('mail.fromuser', trim($email['fromUser']));
Config::set('mail.subject', trim($email['subject']));
Config::set('mail.toEmail', trim($email['toEmail']));
Config::set('mail.toName', trim($email['toName']));
Config::set('mail.pretend', false);
$email_body = $email['emailBody'];
Mail::send('emails.availability, compact('email_body')
, function($message) {
$message->from(config('mail.username'), config('mail.fromUser'));
$message->replyTo(config('mail.frommmail'), config('mail.fromUser'));
$message->to(config('mail.toEmail'), config('mail.toName'))->subject(config('mail.subject'));
});
Log::info('Mail was sent');
}
}
You can not change email provider configs on-the-fly, so you must make new instance of mailer in service container. I did it before, i wrote a method in my own class to get new mailer instance:
/**
* #return Mailer
*/
protected function getMailer()
{
// Changing mailer configuration
config(['mail.driver' => static::getName()]);
// Register new instance of mailer on-the-fly
(new MailServiceProvider($this->container))->register();
// Get mailer instance from service container
return $this->container->make('mailer');
}
Sending e-mail messages directly in web app can drastically slow down the responsiveness of your application. You should always queue your messages.
Instead of Mail::send You can use Mail::queue
and then from cron or manually call
php artisan queue:work
That will process the next item on the queue. This command will do nothing if the queue is empty. But if there’s an item on the queue it will fetch the item and attempt to execute it.

Categories