Skip to content

Instantly share code, notes, and snippets.

@Tmeister
Created February 18, 2020 00:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Tmeister/9458c7c3b018f8e9c07b048d4ffb775e to your computer and use it in GitHub Desktop.
Save Tmeister/9458c7c3b018f8e9c07b048d4ffb775e to your computer and use it in GitHub Desktop.
Jobs process
<?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));
}
}
<?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);
}
}
<?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