Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions app/Http/Controllers/Auth/ThreadsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ class ThreadsController extends SocialController
protected array $scopes = [
'threads_basic',
'threads_content_publish',
'threads_manage_replies',
'threads_read_replies',
];

public function connect(Request $request): Response|RedirectResponse
Expand Down
2 changes: 1 addition & 1 deletion app/Jobs/PublishToSocialPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public function handle(): void

$this->postPlatform->markAsFailed($e->getMessage());
$this->postPlatform->socialAccount->markAsDisconnected($e->getMessage());
} catch (\Exception $e) {
} catch (\Throwable $e) {
Log::error('Failed to publish to social platform', [
'post_platform_id' => $this->postPlatform->id,
'platform' => $this->postPlatform->platform->value,
Expand Down
14 changes: 9 additions & 5 deletions app/Services/Social/FacebookPublisher.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,14 @@ public function publish(PostPlatform $postPlatform): array
};
}

private function publishPost(string $pageId, string $accessToken, string $content, $media): array
private function publishPost(string $pageId, string $accessToken, ?string $content, $media): array
{
// Text only post
if ($media->isEmpty()) {
if (empty($content)) {
throw new \Exception('Facebook text posts require content. Please add text to your post.');
}

return $this->publishTextPost($pageId, $accessToken, $content);
}

Expand Down Expand Up @@ -101,7 +105,7 @@ private function publishTextPost(string $pageId, string $accessToken, string $co
];
}

private function publishSingleImagePost(string $pageId, string $accessToken, string $content, $media): array
private function publishSingleImagePost(string $pageId, string $accessToken, ?string $content, $media): array
{
Log::info('Facebook publishing single image post', ['page_id' => $pageId]);

Expand All @@ -128,7 +132,7 @@ private function publishSingleImagePost(string $pageId, string $accessToken, str
];
}

private function publishMultiImagePost(string $pageId, string $accessToken, string $content, $mediaCollection): array
private function publishMultiImagePost(string $pageId, string $accessToken, ?string $content, $mediaCollection): array
{
Log::info('Facebook publishing multi-image post', [
'page_id' => $pageId,
Expand Down Expand Up @@ -194,7 +198,7 @@ private function publishMultiImagePost(string $pageId, string $accessToken, stri
];
}

private function publishVideoPost(string $pageId, string $accessToken, string $content, $media): array
private function publishVideoPost(string $pageId, string $accessToken, ?string $content, $media): array
{
Log::info('Facebook publishing video post', ['page_id' => $pageId]);

Expand Down Expand Up @@ -222,7 +226,7 @@ private function publishVideoPost(string $pageId, string $accessToken, string $c
];
}

private function publishReel(string $pageId, string $accessToken, string $content, $media): array
private function publishReel(string $pageId, string $accessToken, ?string $content, $media): array
{
Log::info('Facebook publishing reel', ['page_id' => $pageId]);

Expand Down
6 changes: 3 additions & 3 deletions app/Services/Social/InstagramPublisher.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public function publish(PostPlatform $postPlatform): array
};
}

private function publishSingleImage(string $instagramId, string $accessToken, string $content, $media): array
private function publishSingleImage(string $instagramId, string $accessToken, ?string $content, $media): array
{
Log::info('Instagram publishing single image', ['instagram_id' => $instagramId, 'image_url' => $media->url]);

Expand Down Expand Up @@ -93,7 +93,7 @@ private function publishSingleImage(string $instagramId, string $accessToken, st
return $this->publishContainer($instagramId, $accessToken, $containerId);
}

private function publishReel(string $instagramId, string $accessToken, string $content, $media): array
private function publishReel(string $instagramId, string $accessToken, ?string $content, $media): array
{
Log::info('Instagram publishing reel', ['instagram_id' => $instagramId]);

Expand Down Expand Up @@ -167,7 +167,7 @@ private function publishStory(string $instagramId, string $accessToken, $media):
return $this->publishContainer($instagramId, $accessToken, $containerId);
}

private function publishCarousel(string $instagramId, string $accessToken, string $content, $mediaCollection): array
private function publishCarousel(string $instagramId, string $accessToken, ?string $content, $mediaCollection): array
{
Log::info('Instagram publishing carousel', [
'instagram_id' => $instagramId,
Expand Down
8 changes: 4 additions & 4 deletions app/Services/Social/LinkedInPagePublisher.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,11 @@ private function retryWithRefresh(PostPlatform $postPlatform, TokenExpiredExcept
}
}

private function publishPost(string $organizationUrn, string $content, $media, $account): array
private function publishPost(string $organizationUrn, ?string $content, $media, $account): array
{
$payload = [
'author' => $organizationUrn,
'commentary' => $content,
'commentary' => $content ?? '',
'visibility' => 'PUBLIC',
'distribution' => [
'feedDistribution' => 'MAIN_FEED',
Expand Down Expand Up @@ -155,7 +155,7 @@ private function publishPost(string $organizationUrn, string $content, $media, $
];
}

private function publishCarousel(string $organizationUrn, string $content, $mediaCollection, $account): array
private function publishCarousel(string $organizationUrn, ?string $content, $mediaCollection, $account): array
{
Log::info('LinkedIn Page publishing carousel', [
'owner' => $organizationUrn,
Expand Down Expand Up @@ -186,7 +186,7 @@ private function publishCarousel(string $organizationUrn, string $content, $medi

$payload = [
'author' => $organizationUrn,
'commentary' => $content,
'commentary' => $content ?? '',
'visibility' => 'PUBLIC',
'distribution' => [
'feedDistribution' => 'MAIN_FEED',
Expand Down
8 changes: 4 additions & 4 deletions app/Services/Social/LinkedInPublisher.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,11 @@ private function retryWithRefresh(PostPlatform $postPlatform, TokenExpiredExcept
}
}

private function publishPost(string $personUrn, string $content, $media): array
private function publishPost(string $personUrn, ?string $content, $media): array
{
$payload = [
'author' => $personUrn,
'commentary' => $content,
'commentary' => $content ?? '',
'visibility' => 'PUBLIC',
'distribution' => [
'feedDistribution' => 'MAIN_FEED',
Expand Down Expand Up @@ -142,7 +142,7 @@ private function publishPost(string $personUrn, string $content, $media): array
];
}

private function publishCarousel(string $personUrn, string $content, $mediaCollection): array
private function publishCarousel(string $personUrn, ?string $content, $mediaCollection): array
{
Log::info('LinkedIn publishing carousel', [
'owner' => $personUrn,
Expand Down Expand Up @@ -173,7 +173,7 @@ private function publishCarousel(string $personUrn, string $content, $mediaColle

$payload = [
'author' => $personUrn,
'commentary' => $content,
'commentary' => $content ?? '',
'visibility' => 'PUBLIC',
'distribution' => [
'feedDistribution' => 'MAIN_FEED',
Expand Down
10 changes: 7 additions & 3 deletions app/Services/Social/ThreadsPublisher.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ public function publish(PostPlatform $postPlatform): array

// Text only post
if ($media->isEmpty()) {
if (empty($postPlatform->content)) {
throw new \Exception('Threads text posts require content. Please add text to your post.');
}

return $this->publishTextPost($userId, $accessToken, $postPlatform->content);
}

Expand Down Expand Up @@ -91,7 +95,7 @@ private function publishTextPost(string $userId, string $accessToken, string $co
return $this->publishContainer($userId, $accessToken, $containerId);
}

private function publishImagePost(string $userId, string $accessToken, string $content, $media): array
private function publishImagePost(string $userId, string $accessToken, ?string $content, $media): array
{
Log::info('Threads publishing image post', ['user_id' => $userId, 'image_url' => $media->url]);

Expand Down Expand Up @@ -122,7 +126,7 @@ private function publishImagePost(string $userId, string $accessToken, string $c
return $this->publishContainer($userId, $accessToken, $containerId);
}

private function publishVideoPost(string $userId, string $accessToken, string $content, $media): array
private function publishVideoPost(string $userId, string $accessToken, ?string $content, $media): array
{
Log::info('Threads publishing video post', ['user_id' => $userId]);

Expand Down Expand Up @@ -151,7 +155,7 @@ private function publishVideoPost(string $userId, string $accessToken, string $c
return $this->publishContainer($userId, $accessToken, $containerId);
}

private function publishCarousel(string $userId, string $accessToken, string $content, $mediaCollection): array
private function publishCarousel(string $userId, string $accessToken, ?string $content, $mediaCollection): array
{
Log::info('Threads publishing carousel', [
'user_id' => $userId,
Expand Down
4 changes: 2 additions & 2 deletions app/Services/Social/TikTokPublisher.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ private function publishVideo(PostPlatform $postPlatform, $media): array
$response = $this->getHttpClient()
->post("{$this->baseUrl}/post/publish/video/init/", [
'post_info' => [
'title' => $postPlatform->content,
'title' => $postPlatform->content ?? '',
'privacy_level' => 'SELF_ONLY',
'disable_duet' => false,
'disable_comment' => false,
Expand Down Expand Up @@ -145,7 +145,7 @@ private function publishPhotos(PostPlatform $postPlatform, $mediaCollection): ar
$response = $this->getHttpClient()
->post("{$this->baseUrl}/post/publish/content/init/", [
'post_info' => [
'title' => $postPlatform->content,
'title' => $postPlatform->content ?? '',
'privacy_level' => 'SELF_ONLY',
'disable_comment' => false,
],
Expand Down
12 changes: 9 additions & 3 deletions app/Services/Social/XPublisher.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@ public function publish(PostPlatform $postPlatform): array

$this->accessToken = $account->access_token;

$data = [
'text' => $postPlatform->content,
];
$data = [];

if (! empty($postPlatform->content)) {
$data['text'] = $postPlatform->content;
}

$mediaIds = [];
$media = $postPlatform->media;
Expand Down Expand Up @@ -69,6 +71,10 @@ public function publish(PostPlatform $postPlatform): array
];
}

if (empty($data['text']) && empty($mediaIds)) {
throw new \Exception('X posts require either text or media. Please add content to your post.');
}

Log::info('Posting tweet', ['data' => $data]);

$response = $this->getHttpClient()
Expand Down
4 changes: 4 additions & 0 deletions app/Services/Social/YouTubePublisher.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ private function getHttpClient(): PendingRequest

private function publishShort(PostPlatform $postPlatform, $media): array
{
if (empty($postPlatform->content)) {
throw new \Exception('YouTube Shorts require a title. Please add text to your post.');
}

$title = $this->buildTitle($postPlatform->content);
$description = $postPlatform->content;

Expand Down
32 changes: 32 additions & 0 deletions tests/Unit/Services/Social/FacebookPublisherTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -327,3 +327,35 @@
expect(fn () => $this->publisher->publish($this->postPlatform))
->toThrow(Exception::class, 'Unsupported media type for Facebook');
});

test('facebook publisher throws exception for text post with null content', function () {
$this->postPlatform->update(['content' => null]);

expect(fn () => $this->publisher->publish($this->postPlatform))
->toThrow(\Exception::class, 'Facebook text posts require content');
});

test('facebook publisher can publish single image with null content', function () {
$this->postPlatform->update(['content' => null]);

$this->postPlatform->media()->create([
'collection' => 'default',
'type' => 'image',
'path' => 'media/2026-01/test-image.jpg',
'original_filename' => 'test.jpg',
'mime_type' => 'image/jpeg',
'size' => 12345,
'order' => 0,
]);

Http::fake([
'https://graph.facebook.com/v24.0/page_123/photos' => Http::response([
'id' => 'photo-123',
'post_id' => 'post-123',
], 200),
]);

$result = $this->publisher->publish($this->postPlatform);

expect($result['id'])->toBe('post-123');
});
Loading
Loading