Reputation: 4045
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.
Upvotes: 0
Views: 951
Reputation: 392
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.
Upvotes: 0
Reputation: 5311
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));
Upvotes: 2
Reputation: 628
hope this helps
$startDate = Carbon::now()->subMinutes(21);
$endDate = Carbon::now()->subMinutes(19);
$allUsers = User::->whereBetween('created_at', [$startDate, $endDate])->get();
Upvotes: 0