BigJobbies
BigJobbies

Reputation: 4045

Laravel retrieve all records 20 mins from created_at time

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

Answers (3)

Waqas Altaf
Waqas Altaf

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

silver
silver

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

yadu siva das
yadu siva das

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

Related Questions