diff --git a/README.md b/README.md index 6cb105b..194be06 100644 --- a/README.md +++ b/README.md @@ -279,7 +279,7 @@ As a general rule of thumb, `com.atproto` endpoints (such as `com.atproto.sync`) | [app.bsky.feed.getAuthorFeed](https://github.com/bluesky-social/atproto/blob/main/lexicons/app/bsky/feed/getAuthorFeed.json) | ✅ | | [app.bsky.feed.getLikes](https://github.com/bluesky-social/atproto/blob/main/lexicons/app/bsky/feed/getLikes.json) | ✅ | | [app.bsky.feed.getPostThread](https://github.com/bluesky-social/atproto/blob/main/lexicons/app/bsky/feed/getPostThread.json) | ✅ | -| [app.bsky.feed.getActorLikes](https://github.com/bluesky-social/atproto/blob/main/lexicons/app/bsky/feed/getActorLikes.json) | ❌ | +| [app.bsky.feed.getActorLikes](https://github.com/bluesky-social/atproto/blob/main/lexicons/app/bsky/feed/getActorLikes.json) | ✅ | | [app.bsky.feed.getRepostedBy](https://github.com/bluesky-social/atproto/blob/main/lexicons/app/bsky/feed/getRepostedBy.json) | ✅ | | [app.bsky.feed.describeFeedGenerator](https://github.com/bluesky-social/atproto/blob/main/lexicons/app/bsky/feed/describeFeedGenerator.json) | ❌ | | [app.bsky.feed.searchPosts](https://github.com/bluesky-social/atproto/blob/main/lexicons/app/bsky/feed/searchPosts.json) | ❌ | diff --git a/samples/FishyFlipSamplesApp/Program.cs b/samples/FishyFlipSamplesApp/Program.cs index 567daf2..c074516 100644 --- a/samples/FishyFlipSamplesApp/Program.cs +++ b/samples/FishyFlipSamplesApp/Program.cs @@ -51,7 +51,7 @@ string[] authMenuChoices = [ - "Exit", "Get List Blocks for Actor", "Get List Mutes for Actor", "Get Suggestion Follows", + "Exit", "Get Actor Likes", "Get List Blocks for Actor", "Get List Mutes for Actor", "Get Suggestion Follows", "Get Lists Via ATIdentifier", "Get List Via ATUri" ]; @@ -64,6 +64,9 @@ var menuChoice = Prompt.Select("Menu", authMenuChoices); switch (menuChoice) { + case "Get Actor Likes": + await GetActorLikes(atProtocol); + break; case "Get List Blocks for Actor": await GetListBlocksForActor(atProtocol); break; @@ -111,6 +114,28 @@ } } +async Task GetActorLikes(ATProtocol protocol) +{ + var handle = Prompt.Input("Handle", defaultValue: "drasticactions.dev", + validators: new[] { Validators.Required() }); + var profile = (await protocol.Identity.ResolveHandleAsync(ATHandle.Create(handle)!)).HandleResult(); + var likes = (await protocol.Feed.GetActorLikesAsync(profile.Did)).HandleResult(); + if (likes is null) + { + Console.WriteLine("No likes found."); + return; + } + + foreach (var item in likes.Feed) + { + Console.WriteLine(item.Post.Author); + Console.WriteLine(item.Post.IndexedAt); + Console.WriteLine(item.Post.Record?.Text); + Console.WriteLine("-----"); + + } +} + async Task GetListBlocksForActor(ATProtocol protocol) { var blocks = (await protocol.Graph.GetListBlocksAsync()).HandleResult(); diff --git a/src/FishyFlip/BlueskyFeed.cs b/src/FishyFlip/BlueskyFeed.cs index 4e7e2f4..9566a42 100644 --- a/src/FishyFlip/BlueskyFeed.cs +++ b/src/FishyFlip/BlueskyFeed.cs @@ -112,6 +112,21 @@ public async Task> GetAuthorFeedAsync(ATIdentifier handle, int error => error!); } + public async Task> GetActorLikesAsync(ATIdentifier handle, int limit = 50, string? cursor = default, CancellationToken cancellationToken = default) + { + string url = $"{Constants.Urls.Bluesky.Feed.GetActorLikes}?actor={handle.ToString()}&limit={limit}"; + if (cursor is not null) + { + url += $"&cursor={cursor}"; + } + + Multiple result = await this.Client.Get(url, this.Options.JsonSerializerOptions, cancellationToken, this.Options.Logger); + return result + .Match>( + authorFeed => (authorFeed ?? new Timeline(Array.Empty(), null))!, + error => error!); + } + public async Task> GetPostsAsync(IEnumerable query, CancellationToken cancellationToken = default) { var answer = string.Join("&", query.Select(n => $"uris={n}")); diff --git a/src/FishyFlip/Constants.cs b/src/FishyFlip/Constants.cs index 1e9fd84..3a41d31 100644 --- a/src/FishyFlip/Constants.cs +++ b/src/FishyFlip/Constants.cs @@ -100,6 +100,7 @@ public static class Bluesky public static class Feed { public const string GetAuthorFeed = "/xrpc/app.bsky.feed.getAuthorFeed"; + public const string GetActorLikes = "/xrpc/app.bsky.feed.getActorLikes"; public const string GetTimeline = "/xrpc/app.bsky.feed.getTimeline"; public const string GetFeedSkeleton = "/xrpc/app.bsky.feed.getFeedSkeleton"; public const string GetPostThread = "/xrpc/app.bsky.feed.getPostThread";