Back | Home
الـ Path الحالي: /home/picotech/domains/instantly.picotech.app/public_html/public/uploads/../../app/Http/Controllers
الملفات الموجودة في هذا الـ Path:
.
..
Admin
AssetController.php
Auth
Controller.php
Customer
FrontController.php
InboundController.php
RouteController.php
ScheduleController.php
UpgradeController.php
مشاهدة ملف: ScheduleController.php
<?php
namespace App\Http\Controllers;
use App\EmailProvider\SendMailProcess;
use App\Events\SendEMail;
use App\Models\Contact;
use App\Models\Domain;
use App\Models\EmailAccount;
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')
->limit(100)
->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])->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]);
// dd($server_config_value,$message);
$sendEmail = new SendMailProcess();
$sendEmail = $sendEmail->setProvider($provider?$provider:'google_gmail_smtp')
->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]);
}
}