Viewing file: ScheduleController.php (8.48 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
namespace App\Http\Controllers;
use App\EmailProvider\SendMailProcess; use App\Events\SendEMail; use App\Models\Contact; use App\Models\Domain; use App\Models\EmailQueue; use App\Models\Message; use App\Models\SendingServer; use App\Models\Unsubscribe; use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\Log;
class ScheduleController extends Controller { public function process() { $sendFailed = []; $allNumbers = []; $messages = EmailQueue::where(['schedule_completed' => 'no']) ->whereNotNull('schedule_datetime') ->whereNull('delivered_at') ->where('schedule_datetime', '<', now()) ->where('status', 'running') ->get() ->mapToGroups(function ($item, $key) { return ["" . $item->from => $item]; })->map(function ($q) { return $q->take(15); }); $mergedMessages = []; $queueIds = []; foreach ($messages as $items) { foreach ($items as $item) { $queueIds[] = $item->id; $mergedMessages[] = $item; } } if (empty($queueIds)) { if (config('app.debug')) { Log::info("Queue is empty"); } exit; }
$messages = $mergedMessages; $messageBody = []; //getting limit crossed list $totalNewQueueCount = count($messages); // dd($totalNewQueueCount); $sendingServers = SendingServer::where('status', 'active')->where('sending_type','production')->get()->all();
#region Monthly Limit Check $monthlyEmailQueue = EmailQueue::selectRaw("count(*) as total,sending_server_id") ->where('schedule_completed', 'yes') ->whereBetween('schedule_datetime', [now()->subMonth(), now()]) ->groupBy('sending_server_id') ->pluck('total', 'sending_server_id') ->all(); $availableMonthlySendingServerIds = []; foreach ($sendingServers as $sendingServer) { if (isset($monthlyEmailQueue[$sendingServer->id])) { $totalUsed = $monthlyEmailQueue[$sendingServer->id] + $totalNewQueueCount; // count new queue ; if ($sendingServer->monthly_limit > $totalUsed) { $availableMonthlySendingServerIds[] = $sendingServer->id; } } else { $availableMonthlySendingServerIds[] = $sendingServer->id; } } #endregion
#region Daily Limit Check $dailyEmailQueue = EmailQueue::selectRaw("count(*) as total,sending_server_id") ->where('schedule_completed', 'yes') ->whereIn('sending_server_id', $availableMonthlySendingServerIds) ->whereBetween('schedule_datetime', [now()->subDay(), now()]) ->groupBy('sending_server_id') ->pluck('total', 'sending_server_id') ->all(); $availableDailySendingServerIds = []; foreach ($sendingServers as $sendingServer) { if (isset($dailyEmailQueue[$sendingServer->id])) { $totalUsed = $dailyEmailQueue[$sendingServer->id] + $totalNewQueueCount; // count new queue ; if ($sendingServer->daily_limit > $totalUsed) { $availableDailySendingServerIds[] = $sendingServer->id; } } else { $availableDailySendingServerIds[] = $sendingServer->id; } } #endregion
#region Hourly Limit Check $hourlyEmailQueue = EmailQueue::selectRaw("count(*) as total,sending_server_id") ->where('schedule_completed', 'yes') ->whereBetween('schedule_datetime', [now()->subHour(), now()]) ->whereIn('sending_server_id', $availableDailySendingServerIds) ->groupBy('sending_server_id') ->pluck('total', 'sending_server_id') ->all();
$availableHourlySendingServer = collect([]); foreach ($sendingServers as $sendingServer) { if (isset($hourlyEmailQueue[$sendingServer->id])) { $totalUsed = $hourlyEmailQueue[$sendingServer->id] + $totalNewQueueCount; // count new queue ; if ($sendingServer->hourly_limit > $totalUsed) { $availableHourlySendingServer->push($sendingServer); } } else { $availableHourlySendingServer->push($sendingServer); } } #endregion
if ($availableHourlySendingServer->isEmpty()) { if (config('app.debug')) { Log::info("server is empty"); } exit; }
EmailQueue::whereIn('id', $queueIds)->update(['schedule_completed' => 'yes']); foreach ($messages as $message) { try { $allNumbers[] = $message->to; $messageBody[$message->to][] = $message->body; $current_plan = $message->user->plan;
if (!$current_plan) { Log::error("plan not found for message " . $message->id); return response()->json(['message' => 'Plan not found']); }
$pre_available_email = $current_plan->available_emails;
$new_available_email = $pre_available_email - 1;
//if not enough email then return if ($new_available_email < 0) { Log::error("Don\'t have enough email. Email id:" . $message->id); return response()->json(['message' => 'Don\'t have enough email']); } $domain = Domain::where(['id' => $message->domain_id, 'dkim_key_verified' => 'yes', 'spf_key_verified' => 'yes', 'text_verified' => 'yes', 'dmarc_key_verified' => 'yes', ])->first();
$server_config_value = [];
foreach ($availableHourlySendingServer as $server) { $server->send_dkim_private_key = false; if ($domain && isset($domain->dkim_private_key) && $domain->dkim_private_key && $server->value) { $dns_key = explode('.', $domain->dnskey); // pmail._domainkey.example.com $value = (object)json_decode($server->value); $value->dkim_private_key = $domain->dkim_private_key; $value->dkim_domain = $domain->name; $value->dkim_selector = $dns_key[0] ?? 'pmail'; $value->from = $message->from; $server->value = json_encode($value); $server->send_dkim_private_key = true; } $server_config_value[$server->from] = $server; // TODO::convert model to collect } $availableServerFirst = $availableHourlySendingServer->sortBy('priority')->first(); $provider = $availableServerFirst->from;
//if domain verified then send using sendmail if ($domain && isset($domain->dkim_private_key) && $domain->dkim_private_key) { $availableServerSendmail = $availableHourlySendingServer->where('from', 'sendmail')->first(); if ($availableServerSendmail) { $provider = 'sendmail'; } } if (isset($availableServerSendmail) && $availableServerSendmail) { $availableServerFirst = $availableServerSendmail; } $message->update(['sending_server_id' => $availableServerFirst->id]); $sendEmail = new SendMailProcess(); $sendEmail = $sendEmail->setProvider($provider) ->serverConfig($server_config_value) ->setMessage($message) ->process(); if ($sendEmail->hasErrors()) { $errors = $sendEmail->getErrors(); // dd($errors); } } catch (\Exception $ex) { Log::error($ex->getMessage()); $message->status = 'failed'; $message->save(); } }
}
public function check(){ Log::info("checking schedule"); $this->process(); }
public function processEmail() { Artisan::call("queue:work", ['--stop-when-empty' => true]); } }
|