fedi-feed-router/backend/app/Services/Publishing/ArticlePublishingService.php

86 lines
2.9 KiB
PHP
Raw Normal View History

2025-07-05 18:26:04 +02:00
<?php
namespace App\Services\Publishing;
use App\Enums\PlatformEnum;
use App\Exceptions\PublishException;
use App\Models\Article;
use App\Models\ArticlePublication;
2025-07-06 20:37:55 +02:00
use App\Models\PlatformChannel;
2025-07-05 18:26:04 +02:00
use App\Modules\Lemmy\Services\LemmyPublisher;
use App\Services\Log\LogSaver;
use Exception;
2025-07-06 20:52:58 +02:00
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
2025-07-05 18:26:04 +02:00
use Illuminate\Support\Collection;
use RuntimeException;
class ArticlePublishingService
{
/**
2025-07-07 00:51:32 +02:00
* @param array<string, mixed> $extractedData
* @return EloquentCollection<int, ArticlePublication>
2025-07-05 18:26:04 +02:00
* @throws PublishException
*/
2025-07-07 00:51:32 +02:00
public function publishToRoutedChannels(Article $article, array $extractedData): EloquentCollection
2025-07-05 18:26:04 +02:00
{
if (! $article->is_valid) {
throw new PublishException($article, PlatformEnum::LEMMY, new RuntimeException('CANNOT_PUBLISH_INVALID_ARTICLE'));
}
$feed = $article->feed;
2025-07-06 20:52:58 +02:00
/** @var EloquentCollection<int, PlatformChannel> $activeChannels */
2025-07-06 20:37:55 +02:00
$activeChannels = $feed->activeChannels()->with(['platformInstance', 'activePlatformAccounts'])->get();
2025-07-05 18:26:04 +02:00
2025-07-06 20:37:55 +02:00
return $activeChannels->map(function (PlatformChannel $channel) use ($article, $extractedData) {
$account = $channel->activePlatformAccounts()->first();
2025-07-05 18:26:04 +02:00
if (! $account) {
LogSaver::warning('No active account for channel', $channel, [
'article_id' => $article->id
]);
return null;
}
return $this->publishToChannel($article, $extractedData, $channel, $account);
})
->filter();
}
2025-07-07 00:51:32 +02:00
/**
* @param array<string, mixed> $extractedData
*/
private function publishToChannel(Article $article, array $extractedData, PlatformChannel $channel, mixed $account): ?ArticlePublication
2025-07-05 18:26:04 +02:00
{
try {
$publisher = new LemmyPublisher($account);
$postData = $publisher->publishToChannel($article, $extractedData, $channel);
$publication = ArticlePublication::create([
'article_id' => $article->id,
'post_id' => $postData['post_view']['post']['id'],
2025-07-06 01:35:59 +02:00
'platform_channel_id' => $channel->id,
2025-07-05 18:26:04 +02:00
'published_by' => $account->username,
'published_at' => now(),
'platform' => $channel->platformInstance->platform->value,
'publication_data' => $postData,
]);
LogSaver::info('Published to channel via routing', $channel, [
'article_id' => $article->id,
2025-07-07 00:51:32 +02:00
'priority' => $channel->pivot->priority ?? null
2025-07-05 18:26:04 +02:00
]);
return $publication;
} catch (Exception $e) {
LogSaver::warning('Failed to publish to channel', $channel, [
'article_id' => $article->id,
'error' => $e->getMessage()
]);
return null;
}
}
}