support embeds for feeds, lists and starter packs

This commit is contained in:
mruac 2025-03-25 21:13:04 +10:30
parent 38bb5115c9
commit d31ef85446

View File

@ -180,7 +180,7 @@ class BlueskyBridge extends BridgeAbstract
if (Debug::isEnabled()) { if (Debug::isEnabled()) {
$url = explode('/', $post['post']['uri']); $url = explode('/', $post['post']['uri']);
error_log('https://bsky.app/profile/' . $url[2] . '/post/' . $url[4]); $this->logger->debug('https://bsky.app/profile/' . $url[2] . '/post/' . $url[4]);
} }
$description = ''; $description = '';
@ -255,10 +255,16 @@ class BlueskyBridge extends BridgeAbstract
$description .= '<a href="' . $uri_reconstructed . '">Quoted post detached.</a>'; $description .= '<a href="' . $uri_reconstructed . '">Quoted post detached.</a>';
} elseif (isset($quotedRecord['blocked']) && $quotedRecord['blocked']) { //blocked by quote author } elseif (isset($quotedRecord['blocked']) && $quotedRecord['blocked']) { //blocked by quote author
$description .= 'Author of quoted post has blocked OP.'; $description .= 'Author of quoted post has blocked OP.';
} elseif (($quotedRecord['$type'] ?? '') === 'app.bsky.feed.defs#generatorView') { } elseif (
$description .= '</p>'; ($quotedRecord['$type'] ?? '') === 'app.bsky.feed.defs#generatorView' ||
$description .= $this->getGeneratorViewDescription($quotedRecord); ($quotedRecord['$type'] ?? '') === 'app.bsky.graph.defs#listView'
$description .= '<p>'; ) {
$description .= $this->getListFeedDescription($quotedRecord);
} elseif (
($quotedRecord['$type'] ?? '') === 'app.bsky.graph.starterpack' ||
($quotedRecord['$type'] ?? '') === 'app.bsky.graph.defs#starterPackViewBasic'
) {
$description .= $this->getStarterPackDescription($post['post']['embed']['record']);
} else { } else {
$quotedAuthorDid = $quotedRecord['author']['did']; $quotedAuthorDid = $quotedRecord['author']['did'];
$quotedDisplayName = $quotedRecord['author']['displayName'] ?? ''; $quotedDisplayName = $quotedRecord['author']['displayName'] ?? '';
@ -403,10 +409,16 @@ class BlueskyBridge extends BridgeAbstract
$description .= '<a href="' . $uri_reconstructed . '">Quoted post detached.</a>'; $description .= '<a href="' . $uri_reconstructed . '">Quoted post detached.</a>';
} elseif (isset($replyQuotedRecord['blocked']) && $replyQuotedRecord['blocked']) { //blocked by quote author } elseif (isset($replyQuotedRecord['blocked']) && $replyQuotedRecord['blocked']) { //blocked by quote author
$description .= 'Author of quoted post has blocked OP.'; $description .= 'Author of quoted post has blocked OP.';
} elseif (($replyQuotedRecord['$type'] ?? '') === 'app.bsky.feed.defs#generatorView') { } elseif (
$description .= '</p>'; ($replyQuotedRecord['$type'] ?? '') === 'app.bsky.feed.defs#generatorView' ||
$description .= $this->getGeneratorViewDescription($replyQuotedRecord); ($replyQuotedRecord['$type'] ?? '') === 'app.bsky.graph.defs#listView'
$description .= '<p>'; ) {
$description .= $this->getListFeedDescription($replyQuotedRecord);
} elseif (
($replyQuotedRecord['$type'] ?? '') === 'app.bsky.graph.starterpack' ||
($replyQuotedRecord['$type'] ?? '') === 'app.bsky.graph.defs#starterPackViewBasic'
) {
$description .= $this->getStarterPackDescription($replyPost['embed']['record']);
} else { } else {
$quotedAuthorDid = $replyQuotedRecord['author']['did']; $quotedAuthorDid = $replyQuotedRecord['author']['did'];
$quotedDisplayName = $replyQuotedRecord['author']['displayName'] ?? ''; $quotedDisplayName = $replyQuotedRecord['author']['displayName'] ?? '';
@ -554,11 +566,19 @@ class BlueskyBridge extends BridgeAbstract
} }
$title .= ', replying to ' . $replyAuthor; $title .= ', replying to ' . $replyAuthor;
} }
if (isset($post['post']['embed']) && isset($post['post']['embed']['record'])) {
if (
isset($post['post']['embed']) &&
isset($post['post']['embed']['record']) &&
//if not starter pack, feed or list
($post['post']['embed']['record']['$type'] ?? '') !== "app.bsky.feed.defs#generatorView" &&
($post['post']['embed']['record']['$type'] ?? '') !== "app.bsky.graph.defs#listView" &&
($post['post']['embed']['record']['$type'] ?? '') !== "app.bsky.graph.defs#starterPackViewBasic"
) {
if (isset($post['post']['embed']['record']['blocked'])) { if (isset($post['post']['embed']['record']['blocked'])) {
$quotedAuthor = 'blocked user'; $quotedAuthor = 'blocked user';
} elseif (isset($post['post']['embed']['record']['notFound'])) { } elseif (isset($post['post']['embed']['record']['notFound'])) {
$quotedAuthor = 'deleted post'; $quotedAuthor = 'deleted psost';
} elseif (isset($post['post']['embed']['record']['detached'])) { } elseif (isset($post['post']['embed']['record']['detached'])) {
$quotedAuthor = 'detached post'; $quotedAuthor = 'detached post';
} else { } else {
@ -587,34 +607,64 @@ class BlueskyBridge extends BridgeAbstract
{ {
$uri = 'https://public.api.bsky.app/xrpc/app.bsky.feed.getAuthorFeed?actor=' . urlencode($did) . '&filter=' . urlencode($filter) . '&limit=30'; $uri = 'https://public.api.bsky.app/xrpc/app.bsky.feed.getAuthorFeed?actor=' . urlencode($did) . '&filter=' . urlencode($filter) . '&limit=30';
if (Debug::isEnabled()) { if (Debug::isEnabled()) {
error_log($uri); $this->logger->debug($uri);
} }
$response = json_decode(getContents($uri), true); $response = json_decode(getContents($uri), true);
return $response; return $response;
} }
private function getGeneratorViewDescription(array $record): string //Embed for generated feeds and lists
private function getListFeedDescription(array $record): string
{ {
$avatar = e($record['avatar']); $feedViewAvatar = isset($record['avatar']) ? "<img src=\"" . preg_replace('/\/img\/avatar\//', '/img/avatar_thumbnail/', $record['avatar']) . "\">" : "";
$displayName = e($record['displayName']); $feedViewName = e($record['displayName'] ?? $record['name']);
$displayHandle = e($record['creator']['handle']); $feedViewDescription = e($record['description'] ?? '');
$likeCount = e($record['likeCount']); $authorDisplayName = e($record['creator']['displayName']);
$authorHandle = e($record['creator']['handle']);
$likeCount = isset($record['likeCount']) ? "<br>Liked by " . e($record['likeCount']) . " users" : '';
preg_match('/\/([^\/]+)$/', $record['uri'], $matches); preg_match('/\/([^\/]+)$/', $record['uri'], $matches);
$uri = e('https://bsky.app/profile/' . $record['creator']['did'] . '/feed/' . $matches[1]); if (($record['purpose'] ?? '') === 'app.bsky.graph.defs#modlist') {
$typeURL = '/lists/';
$typeDesc = 'moderation list';
} elseif (($record['purpose'] ?? '') === 'app.bsky.graph.defs#curatelist') {
$typeURL = '/lists/';
$typeDesc = 'list';
} else {
$typeURL = '/feed/';
$typeDesc = 'feed';
}
$uri = e('https://bsky.app/profile/' . $record['creator']['did'] . $typeURL . $matches[1]);
return <<<END return <<<END
<a href="{$uri}" style="color: inherit;"> <blockquote>
<div style="border: 1px solid #333; padding: 10px;"> <b><a href="{$uri}">{$feedViewName}</a></b><br/>
<div style="display: flex; margin-bottom: 10px;"> Bluesky {$typeDesc} by <b>{$authorDisplayName}</b> <i>@{$authorHandle}</i>
<img src="{$avatar}" height="50" width="50" style="margin-right: 10px;"> <figure>
<div style="display: flex; flex-direction: column; justify-content: center;"> {$feedViewAvatar}
<h3>{$displayName}</h3> <figcaption>{$feedViewDescription}{$likeCount}</figcaption>
<span>Feed by @{$displayHandle}</span> </figure>
</div> </blockquote>
</div> END;
<span>Liked by {$likeCount} users</span> }
</div>
</a> private function getStarterPackDescription(array $record): string
{
if (!isset($record['record'])) {
return 'Failed to get starter pack information.';
}
$starterpackRecord = $record['record'];
$starterpackName = e($starterpackRecord['name']);
$starterpackDescription = e($starterpackRecord['description']);
$creatorDisplayName = e($record['creator']['displayName']);
$creatorHandle = e($record['creator']['handle']);
preg_match('/\/([^\/]+)$/', $starterpackRecord['list'], $matches);
$uri = e('https://bsky.app/starter-pack/' . $record['creator']['did'] . '/' . $matches[1]);
return <<<END
<blockquote>
<b><a href="{$uri}">{$starterpackName}</a></b><br/>
Bluesky starter pack by <b>{$creatorDisplayName}</b> <i>@{$creatorHandle}</i><br/>
{$starterpackDescription}
</blockquote>
END; END;
} }
} }