Created
February 18, 2020 00:57
-
-
Save Tmeister/9458c7c3b018f8e9c07b048d4ffb775e to your computer and use it in GitHub Desktop.
Jobs process
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Jobs; | |
use App\Lead; | |
use Cache; | |
use Illuminate\Bus\Queueable; | |
use Illuminate\Queue\SerializesModels; | |
use Illuminate\Queue\InteractsWithQueue; | |
use Illuminate\Contracts\Queue\ShouldQueue; | |
use Illuminate\Foundation\Bus\Dispatchable; | |
use Log; | |
class GenerateLeadsBatches implements ShouldQueue | |
{ | |
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; | |
private $list; | |
/** | |
* Create a new job instance. | |
* | |
* @param $list | |
*/ | |
public function __construct($list) | |
{ | |
// | |
$this->list = $list; | |
} | |
/** | |
* Execute the job. | |
* | |
* @return void | |
*/ | |
public function handle() | |
{ | |
$leads = Lead::select('email')->cursor(); | |
$chunks = $leads->chunk(5000); | |
$count = 0; | |
foreach ($chunks as $chunk) { | |
$job = new ProcessLeadsBatches($chunk, $this->list); | |
dispatch($job)->delay(now()->addMinutes(10 * $count++)); | |
} | |
Cache::put('_list_' . $this->list->id, ['total' => count($chunks), 'processed' => 0], now()->addMinutes(120)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Jobs; | |
use App\Lead; | |
use App\Mail\LeadLists; | |
use App\User; | |
use Cache; | |
use Illuminate\Bus\Queueable; | |
use Illuminate\Queue\SerializesModels; | |
use Illuminate\Queue\InteractsWithQueue; | |
use Illuminate\Contracts\Queue\ShouldQueue; | |
use Illuminate\Foundation\Bus\Dispatchable; | |
use DB; | |
use Log; | |
use Mail; | |
use Storage; | |
use Laracsv\Export; | |
class ProcessLeadsBatches implements ShouldQueue | |
{ | |
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; | |
private $leads; | |
private $list; | |
/** | |
* Create a new job instance. | |
* | |
* @param $leads | |
* @param $list | |
*/ | |
public function __construct($leads, $list) | |
{ | |
$this->leads = $leads; | |
$this->list = $list; | |
} | |
/** | |
* Execute the job. | |
* | |
* @return void | |
* @throws \League\Csv\CannotInsertRecord | |
*/ | |
public function handle() | |
{ | |
$start = microtime(true); | |
$walker = $this->list->type === 'openers' ? 'findNoOpenersLead' : 'findBounceLead'; | |
$matches = []; | |
// HERE REFACTOR | |
foreach ($this->leads as $lead) { | |
if (count($results = $this->{$walker}($lead->email))) { | |
foreach ($results as $result) { | |
$row = Lead::whereLeadId($result->lead_id)->first(); | |
$matches[] = [ | |
'domain' => $row->domain, | |
'email' => $lead->email | |
]; | |
} | |
} | |
} | |
Log::info(count($matches) . ' leads found'); | |
$this->createCSVFile($matches); | |
// Check if is the final Job if not update the processed jobs | |
$status = Cache::get('_list_' . $this->list->id); | |
$status['processed'] = $status['processed'] + 1; | |
Cache::put('_list_' . $this->list->id, $status, now()->addMinutes(10)); | |
if ($status['total'] === $status['processed']) { | |
Mail::to($this->list->user()->first()->email)->send(new LeadLists('filtered/' . $this->list->file)); | |
Log::info('Email Sent to ' . $this->list->user()->first()->email); | |
} | |
$time_elapsed_secs = microtime(true) - $start; | |
Log::info('Finish batch on ' . $time_elapsed_secs); | |
} | |
private function findNoOpenersLead($email) | |
{ | |
return DB::select( | |
DB::raw("select lead_id, email from sent_emails | |
where email='" . $email . "' | |
and sent_date < NOW() - INTERVAL 30 DAY | |
group by email | |
having ( | |
select count(*) from sent_emails | |
where email='" . $email . "' and was_opened != 0) = 0;" | |
) | |
); | |
} | |
private function findBounceLead($email) | |
{ | |
return DB::select( | |
DB::raw("select lead_id, email from sent_emails | |
where email='" . $email . "' | |
and was_opened = -1 | |
and sent_date < NOW() - INTERVAL 30 DAY | |
group by email" | |
) | |
); | |
} | |
private function createCSVFile($matches) | |
{ | |
$csv = new Export(); | |
$csv->build(collect($matches), ['domain', 'email'], ['header' => false]); | |
$rawContent = $csv->getWriter()->getContent(); | |
$rawContent = substr($rawContent, 0, strrpos($rawContent, "\n")); | |
$downloadablePath = 'filtered/' . $this->list->file; | |
Log::info('Generating File ' . $downloadablePath ); | |
Storage::disk('public')->append($downloadablePath, $rawContent); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Mail; | |
use Illuminate\Bus\Queueable; | |
use Illuminate\Mail\Mailable; | |
use Illuminate\Queue\SerializesModels; | |
use Illuminate\Contracts\Queue\ShouldQueue; | |
class LeadLists extends Mailable | |
{ | |
use Queueable, SerializesModels; | |
private $filePath; | |
/** | |
* Create a new message instance. | |
* | |
* @param $filePath | |
*/ | |
public function __construct($filePath) | |
{ | |
// | |
$this->filePath = $filePath; | |
} | |
/** | |
* Build the message. | |
* | |
* @return $this | |
*/ | |
public function build() | |
{ | |
return $this->attachFromStorageDisk('public', $this->filePath) | |
->view('email.lists'); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment