Skip to content

Commit

Permalink
fix(tiktok): correctly handle Tiktok URLs shared from the app
Browse files Browse the repository at this point in the history
  • Loading branch information
rgueldenpfennig committed Jan 18, 2025
1 parent cf1c990 commit d99c576
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 9 deletions.
1 change: 1 addition & 0 deletions src/Squidlr.Web/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ public static int Main(string[] args)
builder.AddFrameAncestors().None();
builder.AddImgSrc().Self().From("https://*.tiktokcdn.com")
.From("https://*.tiktokcdn-us.com")
.From("https://*.tiktokcdn-eu.com")
.From("https://media.licdn.com")
.From("https://*.fbcdn.net")
.From("https://pbs.twimg.com");
Expand Down
5 changes: 2 additions & 3 deletions src/Squidlr/Tiktok/TiktokContentProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ public async ValueTask<Result<Content, RequestContentResult>> GetContentAsync(st
var videoDetail = root.GetPropertyOrNull("__DEFAULT_SCOPE__")?.GetPropertyOrNull("webapp.video-detail");
if (videoDetail == null)
{
_logger.LogError("Could not find 'webapp.video-detail' in JSON payload.");
return new(RequestContentResult.Error);
_logger.LogWarning("Could not find 'webapp.video-detail' in JSON payload.");
return new(RequestContentResult.NoVideo);
}

var statusCode = videoDetail.Value.GetPropertyOrNull("statusCode")?.GetInt32();
Expand All @@ -80,7 +80,6 @@ public async ValueTask<Result<Content, RequestContentResult>> GetContentAsync(st
if (id == null || !id.Equals(identifier.Id, StringComparison.OrdinalIgnoreCase))
{
_logger.LogWarning("ID does not match requested Tiktok identifier.");
return new(RequestContentResult.NotFound);
}

if (itemStruct.GetPropertyOrNull("isContentClassified")?.GetBoolean() == true)
Expand Down
2 changes: 1 addition & 1 deletion src/Squidlr/Tiktok/TiktokIdentifier.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
namespace Squidlr.Tiktok;

public record struct TiktokIdentifier(string Id, string Url);
public record struct TiktokIdentifier(string Id, string Url, bool IsShareUrl = false);
2 changes: 1 addition & 1 deletion src/Squidlr/Tiktok/TiktokServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public static IServiceCollection AddTiktok(this IServiceCollection services)
{
var handler = new SocketsHttpHandler
{
AllowAutoRedirect = false,
AllowAutoRedirect = true,
UseCookies = true
};

Expand Down
13 changes: 11 additions & 2 deletions src/Squidlr/Tiktok/Utilities/UrlUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,25 @@ public static partial class UrlUtilities
[GeneratedRegex(@"https?:\/\/(www\.)?tiktok\.com\/(\S+)\/video\/(?<id>\d+).*?", RegexOptions.IgnoreCase)]
private static partial Regex TiktokUrlRegex();

[GeneratedRegex(@"https?:\/\/vm.tiktok\.com\/(?<id>[\s\S][^\/\?]+).*?", RegexOptions.IgnoreCase)]
private static partial Regex TiktokShareUrlRegex();

public static bool TryGetTiktokIdentifier(string url, [NotNullWhen(true)] out TiktokIdentifier? identifier)
{
ArgumentException.ThrowIfNullOrEmpty(url);
identifier = null;

var isShareUrl = false;
var match = TiktokUrlRegex().Match(url);
if (!match.Success)
return false;
{
match = TiktokShareUrlRegex().Match(url);
if (!match.Success)
return false;
isShareUrl = true;
}

identifier = new(match.Groups["id"].Value, match.Groups[0].Value);
identifier = new(match.Groups["id"].Value, match.Groups[0].Value, isShareUrl);
return true;
}

Expand Down
6 changes: 4 additions & 2 deletions test/Squidlr.Tests/Tiktok/Utilities/UrlUtilitiesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public class UrlUtilitiesTests
[InlineData("https://www.tiktok.com/@_le_cannibale_/video/7139980461132074283", true)]
[InlineData("https://www.tiktok.com/@moxypatch/video/7206382937372134662", true)]
[InlineData("http://tiktok.com/@moxypatch/video/7206382937372134662", true)]
[InlineData("https://vm.tiktok.com/ZNeKLnGKw", true)]
[InlineData("https://www.tiktok.com/@moxypatch/image/7206382937372134662", false)]
[InlineData("https://example.com/foo/1152128691131318273/", false)]
[InlineData("https://google.com", false)]
Expand All @@ -30,13 +31,14 @@ public void IsValidTiktokUrl(string url, bool expectedResult)
[InlineData("https://www.tiktok.com/@leenabhushan/video/6748451240264420610?foo=bar#abc", "6748451240264420610", "https://www.tiktok.com/@leenabhushan/video/6748451240264420610")]
[InlineData("https://www.tiktok.com/@patroxofficial/video/6742501081818877190?langCountry=en", "6742501081818877190", "https://www.tiktok.com/@patroxofficial/video/6742501081818877190")]
[InlineData("http://tiktok.com/@moxypatch/video/7206382937372134662", "7206382937372134662", "http://tiktok.com/@moxypatch/video/7206382937372134662")]
[InlineData("https://vm.tiktok.com/ZNeKLnGKw?foo=bar", "ZNeKLnGKw", "https://vm.tiktok.com/ZNeKLnGKw")]
public void GetTiktokIdentifier(string url, string expectedId, string expectedUrl)
{
// Act
Assert.True(UrlUtilities.TryGetTiktokIdentifier(url, out var identifier));

// Assert
Assert.Equal(expectedId, identifier?.Id);
Assert.Equal(expectedUrl, identifier?.Url);
Assert.Equal(expectedId, identifier.Value.Id);
Assert.Equal(expectedUrl, identifier.Value.Url);
}
}

0 comments on commit d99c576

Please sign in to comment.