fedi-feed-router/backend/app/Jobs/SyncChannelPostsJob.php

113 lines
3.5 KiB
PHP
Raw Normal View History

2025-06-30 19:54:43 +02:00
<?php
namespace App\Jobs;
use App\Enums\PlatformEnum;
use App\Exceptions\PlatformAuthException;
2025-07-06 20:52:58 +02:00
use App\Models\PlatformAccount;
2025-07-05 18:26:04 +02:00
use App\Models\PlatformChannel;
2025-06-30 19:54:43 +02:00
use App\Modules\Lemmy\Services\LemmyApiService;
2025-07-05 18:26:04 +02:00
use App\Services\Log\LogSaver;
2025-06-30 19:54:43 +02:00
use Exception;
2025-07-05 18:26:04 +02:00
use Illuminate\Contracts\Queue\ShouldBeUnique;
2025-06-30 19:54:43 +02:00
use Illuminate\Contracts\Queue\ShouldQueue;
2025-07-06 20:52:58 +02:00
use Illuminate\Database\Eloquent\Collection;
2025-06-30 19:54:43 +02:00
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Support\Facades\Cache;
2025-07-05 18:26:04 +02:00
class SyncChannelPostsJob implements ShouldQueue, ShouldBeUnique
2025-06-30 19:54:43 +02:00
{
use Queueable;
public function __construct(
2025-07-05 18:26:04 +02:00
private readonly PlatformChannel $channel
2025-06-30 19:54:43 +02:00
) {
2025-08-03 20:59:09 +02:00
$this->onQueue('sync');
2025-06-30 19:54:43 +02:00
}
2025-07-05 18:26:04 +02:00
public static function dispatchForAllActiveChannels(): void
2025-07-02 21:10:35 +02:00
{
2025-07-05 18:26:04 +02:00
PlatformChannel::with(['platformInstance', 'platformAccounts'])
->whereHas('platformInstance', fn ($query) => $query->where('platform', PlatformEnum::LEMMY))
2025-08-07 21:19:19 +02:00
->whereHas('platformAccounts', fn ($query) => $query->where('platform_accounts.is_active', true))
->where('platform_channels.is_active', true)
2025-07-05 18:26:04 +02:00
->get()
->each(function (PlatformChannel $channel) {
self::dispatch($channel);
LogSaver::info('Dispatched sync job for channel', $channel);
});
2025-07-02 21:10:35 +02:00
}
2025-06-30 19:54:43 +02:00
public function handle(): void
{
2025-07-05 18:26:04 +02:00
LogSaver::info('Starting channel posts sync job', $this->channel);
2025-07-06 20:45:40 +02:00
match ($this->channel->platformInstance->platform) {
PlatformEnum::LEMMY => $this->syncLemmyChannelPosts(),
};
2025-07-05 18:26:04 +02:00
LogSaver::info('Channel posts sync job completed', $this->channel);
2025-06-30 19:54:43 +02:00
}
2025-07-05 18:26:04 +02:00
/**
* @throws PlatformAuthException
*/
2025-06-30 19:54:43 +02:00
private function syncLemmyChannelPosts(): void
{
try {
2025-07-06 20:52:58 +02:00
/** @var Collection<int, PlatformAccount> $accounts */
$accounts = $this->channel->activePlatformAccounts()->get();
$account = $accounts->first();
2025-06-30 19:54:43 +02:00
2025-07-06 20:52:58 +02:00
if (! $account) {
2025-07-05 18:26:04 +02:00
throw new PlatformAuthException(PlatformEnum::LEMMY, 'No active account found for channel');
}
2025-07-03 21:16:22 +02:00
2025-07-05 18:26:04 +02:00
$api = new LemmyApiService($this->channel->platformInstance->url);
$token = $this->getAuthToken($api, $account);
2025-06-30 19:54:43 +02:00
2025-07-06 10:53:37 +02:00
$platformChannelId = $this->channel->channel_id
2025-07-06 20:52:58 +02:00
? $this->channel->channel_id
2025-07-06 10:53:37 +02:00
: $api->getCommunityId($this->channel->name, $token);
2025-07-05 18:26:04 +02:00
2025-07-06 10:53:37 +02:00
$api->syncChannelPosts($token, $platformChannelId, $this->channel->name);
2025-07-05 18:26:04 +02:00
LogSaver::info('Channel posts synced successfully', $this->channel);
2025-06-30 19:54:43 +02:00
} catch (Exception $e) {
2025-07-05 18:26:04 +02:00
LogSaver::error('Failed to sync channel posts', $this->channel, [
2025-06-30 19:54:43 +02:00
'error' => $e->getMessage()
]);
2025-07-05 18:26:04 +02:00
2025-06-30 19:54:43 +02:00
throw $e;
}
}
2025-07-05 18:26:04 +02:00
/**
* @throws PlatformAuthException
*/
2025-07-06 20:52:58 +02:00
private function getAuthToken(LemmyApiService $api, PlatformAccount $account): string
2025-06-30 19:54:43 +02:00
{
2025-07-05 18:26:04 +02:00
$cacheKey = "lemmy_jwt_token_{$account->id}";
$cachedToken = Cache::get($cacheKey);
2025-06-30 21:28:15 +02:00
if ($cachedToken) {
return $cachedToken;
}
2025-06-30 19:54:43 +02:00
2025-07-05 18:26:04 +02:00
if (!$account->username || !$account->password) {
throw new PlatformAuthException(PlatformEnum::LEMMY, 'Missing credentials for account');
2025-06-30 21:28:15 +02:00
}
2025-07-05 18:26:04 +02:00
$token = $api->login($account->username, $account->password);
2025-06-30 21:28:15 +02:00
if (!$token) {
2025-07-05 18:26:04 +02:00
throw new PlatformAuthException(PlatformEnum::LEMMY, 'Login failed for account');
2025-06-30 21:28:15 +02:00
}
2025-06-30 19:54:43 +02:00
2025-07-05 18:26:04 +02:00
Cache::put($cacheKey, $token, 3600);
2025-06-30 21:28:15 +02:00
return $token;
2025-06-30 19:54:43 +02:00
}
}