File: /home/xedaptot/ai.naniguide.com/app/Jobs/Ads/RefreshAdPlatformTokens.php
<?php
namespace App\Jobs\Ads;
use App\Model\AdPlatform;
use App\Services\Ads\AdActivityLogger;
use App\Services\Ads\AdPlatformManager;
use Illuminate\Support\Facades\Log;
use Throwable;
/**
* Scheduled job to refresh ad platform tokens proactively.
* Runs every 30 minutes. Refreshes tokens expiring within 24 hours.
*
* Platform-specific refresh timing:
* - Meta: tokens last 60 days, no refresh (re-auth required)
* - Google: refresh anytime via refresh_token
* - TikTok: tokens last 24h, refresh proactively every ~20h
* - LinkedIn: tokens last 60 days, refresh when <7 days remaining
*/
class RefreshAdPlatformTokens extends AbstractAdsJob
{
public function __construct()
{
parent::__construct();
// Override: batch job should not retry — each platform refresh has its
// own error handling via AdPlatformManager::refreshIfExpired().
$this->tries = 1;
$this->timeout = 120;
}
public function handle(AdPlatformManager $manager): void
{
$platforms = AdPlatform::active()
->whereNotNull('token_expires_at')
->where('token_expires_at', '<=', now()->addDay()) // Expiring within 24h
->whereNotNull('refresh_token')
->get();
foreach ($platforms as $platform) {
try {
$manager->refreshIfExpired($platform);
} catch (\Throwable $e) {
// Individual platform errors are already logged by the manager.
// Just log at job level for debugging.
Log::warning('RefreshAdPlatformTokens: failed for platform ' . $platform->uid, [
'platform' => $platform->platform,
'error' => $e->getMessage(),
]);
}
}
// Also check for expiring tokens that need user notification (7-day warning)
$expiringPlatforms = AdPlatform::active()
->whereNotNull('token_expires_at')
->where('token_expires_at', '<=', now()->addDays(7))
->where('token_expires_at', '>', now()->addDay())
->get();
foreach ($expiringPlatforms as $platform) {
// Only log warning once per day (check if we already logged today)
$alreadyWarned = $platform->activityLogs()
->where('action', 'platform.token_expiring')
->where('created_at', '>=', now()->startOfDay())
->exists();
if (!$alreadyWarned) {
$daysLeft = now()->diffInDays($platform->token_expires_at);
AdActivityLogger::log(
entity: $platform,
action: 'platform.token_expiring',
status: 'warning',
title: $platform->platform_label . " token expires in {$daysLeft} days",
description: "Token will expire on " . $platform->token_expires_at->format('Y-m-d H:i') . ". Reconnect to avoid disruption.",
resolutionHint: "Go to Ads > Platforms and click 'Reconnect' on " . $platform->platform_label . " before it expires.",
platform: $platform->platform,
);
}
}
}
public function failed(Throwable $e): void
{
$this->logFailure($e);
}
}