onQueue('publishing'); } /** * Execute the job. * * @throws PublishException */ public function handle(ArticleFetcher $articleFetcher, ArticlePublishingService $publishingService, NotificationService $notificationService): void { $interval = Setting::getArticlePublishingInterval(); if ($interval > 0) { $lastPublishedAt = ArticlePublication::max('published_at'); if ($lastPublishedAt && now()->diffInMinutes($lastPublishedAt, absolute: true) < $interval) { return; } } // Get the oldest approved route_article that hasn't been published to its channel yet $routeArticle = RouteArticle::where('approval_status', ApprovalStatusEnum::APPROVED) ->whereDoesntHave('article.articlePublications', function ($query) { $query->whereColumn('article_publications.platform_channel_id', 'route_articles.platform_channel_id'); }) ->oldest('route_articles.created_at') ->with(['article', 'platformChannel.platformInstance', 'platformChannel.activePlatformAccounts']) ->first(); if (! $routeArticle) { return; } $article = $routeArticle->article; ActionPerformed::dispatch('Publishing next article from scheduled job', LogLevelEnum::INFO, [ 'article_id' => $article->id, 'title' => $article->title, 'url' => $article->url, 'route' => $routeArticle->feed_id.'-'.$routeArticle->platform_channel_id, ]); $routeArticle->update(['publish_status' => PublishStatusEnum::PUBLISHING]); try { $extractedData = $articleFetcher->fetchArticleData($article); $publication = $publishingService->publishRouteArticle($routeArticle, $extractedData); if ($publication) { $routeArticle->update(['publish_status' => PublishStatusEnum::PUBLISHED]); ActionPerformed::dispatch('Successfully published article', LogLevelEnum::INFO, [ 'article_id' => $article->id, 'title' => $article->title, ]); } else { $routeArticle->update(['publish_status' => PublishStatusEnum::ERROR]); ActionPerformed::dispatch('No publication created for article', LogLevelEnum::WARNING, [ 'article_id' => $article->id, 'title' => $article->title, ]); $notificationService->send( NotificationTypeEnum::PUBLISH_FAILED, NotificationSeverityEnum::WARNING, "Publish failed: {$article->title}", 'No publication was created for this article. Check channel routing configuration.', $article, ); } } catch (PublishException $e) { $routeArticle->update(['publish_status' => PublishStatusEnum::ERROR]); ActionPerformed::dispatch('Failed to publish article', LogLevelEnum::ERROR, [ 'article_id' => $article->id, 'error' => $e->getMessage(), ]); $notificationService->send( NotificationTypeEnum::PUBLISH_FAILED, NotificationSeverityEnum::ERROR, "Publish failed: {$article->title}", $e->getMessage(), $article, ); throw $e; } } }