From 5bd767b862bec2e1a26304be6fa8f6dd8c25ec7f Mon Sep 17 00:00:00 2001
From: Apollo Nargang
Date: Thu, 8 May 2025 23:10:04 -0400
Subject: [PATCH] [TikTokBridge] Use oEmbed for video metadata (#4514)
* [TikTokBridge] Use oEmbed for video metadata
Fetches oEmbed-formatted metadata for videos through the TikTok API to
provide post titles, thumbnails, and authors. This hasn't yet been
tested, so it's possible it doesn't work.
* [TikTokBridge] Add back view count parsing
oops
* [TikTokBridge] Prepend www to the oEmbed API endpoint URL
The non-www URL resulted in a 301 redirect to the www URL, so this just
skips that redirect, improving performance a bit and hopefully helping
with the 400 errors.
* [TikTokBridge] Retry failed OEmbed requests
If an OEmbed request fails, retry a few times, waiting a bit in between
each retry. This should fix the problem for the most part, since I think
the problem was related to some sort of rate limit (it isn't mentioned
in the docs, but it seems to only happen when sending large quantities
of sequential requests).
---
bridges/TikTokBridge.php | 25 ++++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/bridges/TikTokBridge.php b/bridges/TikTokBridge.php
index 43a9cb31..ff3bfbc2 100644
--- a/bridges/TikTokBridge.php
+++ b/bridges/TikTokBridge.php
@@ -21,6 +21,8 @@ class TikTokBridge extends BridgeAbstract
'context' => 'By user', 'username' => '@tiktok'
]
];
+ const OEMBED_RETRY_COUNT = 20;
+ const OEMBED_RETRY_DELAY = 0.1;
const CACHE_TIMEOUT = 900; // 15 minutes
@@ -42,16 +44,33 @@ class TikTokBridge extends BridgeAbstract
$parsedUrl = parse_url($href);
$url = $parsedUrl['scheme'] . '://' . $parsedUrl['host'] . '/' . ltrim($parsedUrl['path'], '/');
- $image = $video->find('video', 0)->poster;
+ // Sometimes the API fails to return data for a second, so try a few times
+ $attempts = 0;
+ do {
+ try {
+ // Fetch the video embed data from the OEmbed API
+ $videoEmbedResponse = getContents('https://www.tiktok.com/oembed?url=' . $url);
+ } catch (Exception $e) {
+ $attempts++;
+ sleep($OEMBED_RETRY_DELAY);
+ continue;
+ }
+ break;
+ } while($attempts < $OEMBED_RETRY_COUNT);
+ $videoEmbedData = json_decode($videoEmbedResponse);
+
+ $title = $videoEmbedData->title;
+ $image = $videoEmbedData->thumbnail_url;
$views = $video->find('div[data-e2e=common-Video-Count]', 0)->plaintext;
$enclosures = [$image, $authorProfilePicture];
$item['uri'] = $url;
- $item['title'] = 'Video';
- $item['author'] = '@' . $author;
+ $item['title'] = $title;
+ $item['author'] = '@' . $videoEmbedData->author_unique_id;
$item['enclosures'] = $enclosures;
$item['content'] = <<$title
{$views} views
EOD;