From 5658ea8c8c4e3ca55b26ba5156aa133e52c447b8 Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Sun, 3 May 2026 22:16:19 -0300 Subject: [PATCH] feat: update Bluesky to use public AppView and remove Mastodon access token from public status requests --- app/Services/Social/BlueskyAnalytics.php | 9 ++++++--- app/Services/Social/MastodonAnalytics.php | 4 +++- config/trypost.php | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/Services/Social/BlueskyAnalytics.php b/app/Services/Social/BlueskyAnalytics.php index cdb309ff..70eb2960 100644 --- a/app/Services/Social/BlueskyAnalytics.php +++ b/app/Services/Social/BlueskyAnalytics.php @@ -20,13 +20,16 @@ public function fetchPostMetrics(PostPlatform $postPlatform): array return ['unsupported' => true, 'reason' => 'missing_post_id']; } - $service = data_get($account->meta, 'service', 'https://bsky.social'); $did = $account->platform_user_id; $atUri = "at://{$did}/app.bsky.feed.post/{$postPlatform->platform_post_id}"; - // Public AppView API: no auth required for reading post counts. + // Read counts (likes, reposts, replies, quotes) live on the AT + // Protocol AppView, not the PDS. The user's PDS requires Bearer auth + // for this endpoint; the public AppView does not. + $appView = (string) config('trypost.platforms.bluesky.public_appview'); + $response = $this->socialHttp() - ->get("{$service}/xrpc/app.bsky.feed.getPosts", [ + ->get("{$appView}/xrpc/app.bsky.feed.getPosts", [ 'uris' => [$atUri], ]); diff --git a/app/Services/Social/MastodonAnalytics.php b/app/Services/Social/MastodonAnalytics.php index 3b176913..a7348f1c 100644 --- a/app/Services/Social/MastodonAnalytics.php +++ b/app/Services/Social/MastodonAnalytics.php @@ -22,8 +22,10 @@ public function fetchPostMetrics(PostPlatform $postPlatform): array $instance = data_get($account->meta, 'instance', 'https://mastodon.social'); + // Public posts: no auth needed. Our token only requests write scopes + // (read:accounts + write:statuses + write:media), so attaching the + // Bearer would 403 with "outside the authorized scopes". $response = $this->socialHttp() - ->withToken($account->access_token) ->get("{$instance}/api/v1/statuses/{$postPlatform->platform_post_id}"); if ($response->failed()) { diff --git a/config/trypost.php b/config/trypost.php index df4ff9e2..c0606acd 100644 --- a/config/trypost.php +++ b/config/trypost.php @@ -87,6 +87,7 @@ ], 'bluesky' => [ 'enabled' => env('BLUESKY_ENABLED', true), + 'public_appview' => env('BLUESKY_PUBLIC_APPVIEW', 'https://public.api.bsky.app'), ], 'mastodon' => [ 'enabled' => env('MASTODON_ENABLED', true),