109 lines
3.4 KiB
PHP
109 lines
3.4 KiB
PHP
<?php
|
|
|
|
namespace App\Jobs;
|
|
|
|
use App\Enums\PlatformEnum;
|
|
use App\Exceptions\PlatformAuthException;
|
|
use App\Models\PlatformChannel;
|
|
use App\Modules\Lemmy\Services\LemmyApiService;
|
|
use App\Services\Log\LogSaver;
|
|
use Exception;
|
|
use Illuminate\Contracts\Queue\ShouldBeUnique;
|
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
use Illuminate\Foundation\Queue\Queueable;
|
|
use Illuminate\Support\Facades\Cache;
|
|
|
|
class SyncChannelPostsJob implements ShouldQueue, ShouldBeUnique
|
|
{
|
|
use Queueable;
|
|
|
|
public function __construct(
|
|
private readonly PlatformChannel $channel
|
|
) {
|
|
$this->onQueue('lemmy-posts');
|
|
}
|
|
|
|
public static function dispatchForAllActiveChannels(): void
|
|
{
|
|
PlatformChannel::with(['platformInstance', 'platformAccounts'])
|
|
->whereHas('platformInstance', fn ($query) => $query->where('platform', PlatformEnum::LEMMY))
|
|
->whereHas('platformAccounts', fn ($query) => $query->where('is_active', true))
|
|
->where('is_active', true)
|
|
->get()
|
|
->each(function (PlatformChannel $channel) {
|
|
self::dispatch($channel);
|
|
LogSaver::info('Dispatched sync job for channel', $channel);
|
|
});
|
|
}
|
|
|
|
public function handle(): void
|
|
{
|
|
LogSaver::info('Starting channel posts sync job', $this->channel);
|
|
|
|
if ($this->channel->platformInstance->platform === PlatformEnum::LEMMY) {
|
|
$this->syncLemmyChannelPosts();
|
|
}
|
|
|
|
LogSaver::info('Channel posts sync job completed', $this->channel);
|
|
}
|
|
|
|
/**
|
|
* @throws PlatformAuthException
|
|
*/
|
|
private function syncLemmyChannelPosts(): void
|
|
{
|
|
try {
|
|
$account = $this->channel->platformAccounts()->where('is_active', true)->first();
|
|
|
|
if (!$account) {
|
|
throw new PlatformAuthException(PlatformEnum::LEMMY, 'No active account found for channel');
|
|
}
|
|
|
|
$api = new LemmyApiService($this->channel->platformInstance->url);
|
|
$token = $this->getAuthToken($api, $account);
|
|
|
|
// Get community ID from channel_id or resolve from name
|
|
$platformChannelId = $this->channel->channel_id
|
|
? (int) $this->channel->channel_id
|
|
: $api->getCommunityId($this->channel->name, $token);
|
|
|
|
$api->syncChannelPosts($token, $platformChannelId, $this->channel->name);
|
|
|
|
LogSaver::info('Channel posts synced successfully', $this->channel);
|
|
|
|
} catch (Exception $e) {
|
|
LogSaver::error('Failed to sync channel posts', $this->channel, [
|
|
'error' => $e->getMessage()
|
|
]);
|
|
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @throws PlatformAuthException
|
|
*/
|
|
private function getAuthToken(LemmyApiService $api, \App\Models\PlatformAccount $account): string
|
|
{
|
|
$cacheKey = "lemmy_jwt_token_{$account->id}";
|
|
$cachedToken = Cache::get($cacheKey);
|
|
|
|
if ($cachedToken) {
|
|
return $cachedToken;
|
|
}
|
|
|
|
if (!$account->username || !$account->password) {
|
|
throw new PlatformAuthException(PlatformEnum::LEMMY, 'Missing credentials for account');
|
|
}
|
|
|
|
$token = $api->login($account->username, $account->password);
|
|
|
|
if (!$token) {
|
|
throw new PlatformAuthException(PlatformEnum::LEMMY, 'Login failed for account');
|
|
}
|
|
|
|
Cache::put($cacheKey, $token, 3600);
|
|
|
|
return $token;
|
|
}
|
|
}
|