From aba38845d24a42b20434b6dbbc90cb09dfe716ec Mon Sep 17 00:00:00 2001 From: shaun Date: Mon, 4 Aug 2025 07:30:48 -0500 Subject: [PATCH] =?UTF-8?q?[YoutubeCommunityTabsBridge]=20Rename=20Communi?= =?UTF-8?q?ty=E2=86=92Posts=20to=20fix=20broken=20bridge=20(#4606)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * youtube community posts are just called "Posts" now * finish renaming Community -> Posts * add feedName fallbacks (thanks @Mar-Koeh) * rename YouTubePostsTabBridge back to YouTubeCommunityTabBridge * fix linter error by breaking up long expression * fix optional-chaining regression by using ‘?? null’ --- README.md | 2 +- bridges/YouTubeCommunityTabBridge.php | 44 +++++++++++++++------------ 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index dadf7094..66d9b46e 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ Requires minimum PHP 7.4. * `TwitchBridge`: [Fetches videos from channel](https://rss-bridge.org/bridge01/#bridge-TwitchBridge) * `XPathBridge`: [Scrape out a feed using XPath expressions](https://rss-bridge.org/bridge01/#bridge-XPathBridge) * `YoutubeBridge`: [Fetches videos by username/channel/playlist/search](https://rss-bridge.org/bridge01/#bridge-YoutubeBridge) -* `YouTubeCommunityTabBridge`: [Fetches posts from a channel's community tab](https://rss-bridge.org/bridge01/#bridge-YouTubeCommunityTabBridge) +* `YouTubeCommunityTabBridge`: [Fetches posts from a channel's Posts tab](https://rss-bridge.org/bridge01/#bridge-YouTubeCommunityTabBridge) ## Tutorial diff --git a/bridges/YouTubeCommunityTabBridge.php b/bridges/YouTubeCommunityTabBridge.php index 284b81f9..d6a70bd6 100644 --- a/bridges/YouTubeCommunityTabBridge.php +++ b/bridges/YouTubeCommunityTabBridge.php @@ -2,9 +2,9 @@ class YouTubeCommunityTabBridge extends BridgeAbstract { - const NAME = 'YouTube Community Tab Bridge'; + const NAME = 'YouTube Posts Tab Bridge'; const URI = 'https://www.youtube.com'; - const DESCRIPTION = 'Returns posts from a channel\'s community tab'; + const DESCRIPTION = 'Returns posts from a channel\'s posts tab'; const MAINTAINER = 'VerifiedJoseph'; const PARAMETERS = [ 'By channel ID' => [ @@ -31,7 +31,7 @@ class YouTubeCommunityTabBridge extends BridgeAbstract private $feedName = ''; private $itemTitle = ''; - private $urlRegex = '/youtube\.com\/(channel|user|c)\/([\w]+)\/community/'; + private $urlRegex = '/youtube\.com\/(channel|user|c)\/([\w]+)\/posts/'; private $jsonRegex = '/var ytInitialData = ([^<]*);<\/script>/'; public function detectParameters($url) @@ -59,26 +59,30 @@ class YouTubeCommunityTabBridge extends BridgeAbstract { if (is_null($this->getInput('username')) === false) { try { - $this->feedUrl = $this->buildCommunityUri($this->getInput('username'), 'c'); + $this->feedUrl = $this->buildPostsUri($this->getInput('username'), 'c'); $html = getSimpleHTMLDOM($this->feedUrl); } catch (Exception $e) { - $this->feedUrl = $this->buildCommunityUri($this->getInput('username'), 'user'); + $this->feedUrl = $this->buildPostsUri($this->getInput('username'), 'user'); $html = getSimpleHTMLDOM($this->feedUrl); } } else { - $this->feedUrl = $this->buildCommunityUri($this->getInput('channel'), 'channel'); + $this->feedUrl = $this->buildPostsUri($this->getInput('channel'), 'channel'); $html = getSimpleHTMLDOM($this->feedUrl); } $json = $this->extractJson($html->find('html', 0)->innertext); - $this->feedName = $json->header->c4TabbedHeaderRenderer->title; + $this->feedName = $json->header->c4TabbedHeaderRenderer->title ?? null; + $this->feedName ??= $json->header->pageHeaderRenderer->pageTitle ?? null; + $this->feedName ??= $json->metadata->channelMetadataRenderer->title ?? null; + $this->feedName ??= $json->microformat->microformatDataRenderer->title ?? null; + $this->feedName ??= ''; - if ($this->hasCommunityTab($json) === false) { - returnServerError('Channel does not have a community tab'); + if ($this->hasPostsTab($json) === false) { + returnServerError('Channel does not have a posts tab'); } - $posts = $this->getCommunityPosts($json); + $posts = $this->getPosts($json); foreach ($posts as $key => $post) { $this->itemTitle = ''; @@ -132,18 +136,18 @@ class YouTubeCommunityTabBridge extends BridgeAbstract public function getName() { if (!empty($this->feedName)) { - return $this->feedName . ' - YouTube Community Tab'; + return $this->feedName . ' - YouTube Posts Tab'; } return parent::getName(); } /** - * Build Community URI + * Build Posts URI */ - private function buildCommunityUri($value, $type) + private function buildPostsUri($value, $type) { - return self::URI . '/' . $type . '/' . $value . '/community'; + return self::URI . '/' . $type . '/' . $value . '/posts'; } /** @@ -165,14 +169,14 @@ class YouTubeCommunityTabBridge extends BridgeAbstract } /** - * Check if channel has a community tab + * Check if channel has a posts tab */ - private function hasCommunityTab($json) + private function hasPostsTab($json) { foreach ($json->contents->twoColumnBrowseResultsRenderer->tabs as $tab) { if ( isset($tab->tabRenderer) - && str_ends_with($tab->tabRenderer->endpoint->commandMetadata->webCommandMetadata->url, 'community') + && str_ends_with($tab->tabRenderer->endpoint->commandMetadata->webCommandMetadata->url, 'posts') ) { return true; } @@ -182,14 +186,14 @@ class YouTubeCommunityTabBridge extends BridgeAbstract } /** - * Get community tab posts + * Get posts from posts tab */ - private function getCommunityPosts($json) + private function getPosts($json) { foreach ($json->contents->twoColumnBrowseResultsRenderer->tabs as $tab) { if ( isset($tab->tabRenderer) - && str_ends_with($tab->tabRenderer->endpoint->commandMetadata->webCommandMetadata->url, 'community') + && str_ends_with($tab->tabRenderer->endpoint->commandMetadata->webCommandMetadata->url, 'posts') ) { return $tab->tabRenderer->content->sectionListRenderer->contents[0]->itemSectionRenderer->contents; }