I have a command which needs to send an email to a user 20 mins after their record was created.
The command runs every minute through the Kernel.php
$allUsers = User::where('created_at' = now()->addMinutes(20))
The above doesnt seem to return any records.
Any help would be greatly appreciated.
CodePudding user response:
The best approach on this is to create a Job queue for sending an email then use delayed-dispatching
You can dispatch the job upon record creation or through event listener by adding something like below after record creation
ProcessEmail::dispatch($user)->delay(now()->addMinutes(20));
Here's the full steps
first run jobs migration php artisan queue:table
then run artisan command to create a job php artisan make:job ProcessEmail
then on your App/Jobs/ProcessEmail.php
should have something like this
namespace App\Jobs;
///..uses here
class ProcessEmail implements ShouldQueue {
//additional uses blablaba
protected $user;
public $tries = 3;
public function __construct( $user ) {
//assign the user as job property to access on handle
$this->user = $user;
}
public function handle() {
// Email proccess
try {
//However you run the email
\Log::info('I run for user '. $this->user->email);
} catch (\Throwable $exception) {
// re-attempt on failure
if ($this->attempts() > 2) {
// manually set the job as failed on 3rd attempt and throw some error
throw $exception;
}
// release after 5 seconds to retry the job.
$this->release(5);
return;
}
}
public function failed(\Throwable $e) {
// Do something on failure
\Log::info( $e->getMessage() );
}
}
then whereever you create the record, call that jobs
use App\Jobs\ProcessEmail;
then on your record creation, dispatch it after user is created like below
$user = User::create(['.......']);
ProcessEmail::dispatch($user)->delay(now()->addMinutes(20));
CodePudding user response:
hope this helps
$startDate = Carbon::now()->subMinutes(21);
$endDate = Carbon::now()->subMinutes(19);
$allUsers = User::->whereBetween('created_at', [$startDate, $endDate])->get();
CodePudding user response:
In you query = sign only get record which exactly match with created_at. For example you create a record on date 25-06-2022 time 04:15:33.
As your command execute every minute so it will execute on 04:15:00 & 04:16:00, these will get only records that match with time and your created record is between these as seconds are not matching therefore it will return Null/empty. To access records you must use greater-than or equal sign >= in your query to get any record which is created before 20 minutes.
$allUsers = User::where('created_at' >= now()->addMinutes(20))
Use some flag to keep record of users already sent email otherwise your code will send email to all users created before 20 minutes either email already sent or not.