47 lines
2.5 KiB
PHP
47 lines
2.5 KiB
PHP
<?php
|
|
|
|
namespace App\Services\MailFlow;
|
|
|
|
use App\Jobs\SendMailMessageJob;
|
|
use App\Models\MailMessage;
|
|
use App\Models\User;
|
|
|
|
class ExpiredSubscriptionNotifier
|
|
{
|
|
public function queueDue(): int
|
|
{
|
|
$state = AutomaticMailPolicy::state();
|
|
if (!$state || $state['level'] !== 2 || !$state['since'] || !admin_setting('remind_mail_enable', false)) { return 0; }
|
|
$queued = 0;
|
|
User::where('remind_expire', true)->where('banned', false)->whereNotNull('plan_id')
|
|
->where('expired_at', '>', $state['since'])->where('expired_at', '<=', now()->timestamp)
|
|
->chunkById(500, function ($users) use (&$queued) {
|
|
foreach ($users as $user) {
|
|
if (!filter_var($user->email, FILTER_VALIDATE_EMAIL)) { continue; }
|
|
$key = 'subscription-expired:' . $user->id . ':' . $user->expired_at;
|
|
$params = ['message_key' => $key, 'email' => $user->email, 'user_id' => $user->id,
|
|
'purpose' => 'service_expired', 'subscription_expired_at' => (int) $user->expired_at,
|
|
'template_name' => 'serviceExpired', 'subject' => admin_setting('app_name', 'XBoard') . ' - 套餐已到期',
|
|
'template_value' => ['name' => admin_setting('app_name', 'XBoard'), 'url' => admin_setting('app_url')]];
|
|
if (AutomaticMailPolicy::decision('service_expired', $params)) { continue; }
|
|
// Persist before dispatch. The same user can renew and receive a later distinct expiry event.
|
|
$message = MailMessage::firstOrCreate(['message_key' => $key], [
|
|
'purpose' => 'service_expired', 'user_id' => $user->id, 'email' => $user->email,
|
|
'subject' => $params['subject'], 'template_name' => 'serviceExpired',
|
|
'expires_at' => now()->addDay(), 'payload' => ['email_params' => $params],
|
|
]);
|
|
if (!$message->wasRecentlyCreated && ($message->status !== 'pending' || !$message->payload
|
|
|| $message->updated_at->gt(now()->subMinutes(2)))) { continue; }
|
|
if ($message->attempts >= 6) {
|
|
$message->update(['status' => 'failed', 'error_code' => 'mail_retry_exhausted', 'payload' => null]);
|
|
continue;
|
|
}
|
|
$message->touch();
|
|
SendMailMessageJob::dispatch($message->id);
|
|
$queued++;
|
|
}
|
|
});
|
|
return $queued;
|
|
}
|
|
}
|