diff --git a/src/main/java/swiss/fihlon/apus/plugin/social/bluesky/BlueSkyPlugin.java b/src/main/java/swiss/fihlon/apus/plugin/social/bluesky/BlueSkyPlugin.java index 99b7a46..41f5b3b 100644 --- a/src/main/java/swiss/fihlon/apus/plugin/social/bluesky/BlueSkyPlugin.java +++ b/src/main/java/swiss/fihlon/apus/plugin/social/bluesky/BlueSkyPlugin.java @@ -72,7 +72,9 @@ public Stream getPosts() { for (var i = 0; i < jsonPosts.length(); i++) { final var post = jsonPosts.getJSONObject(i); - posts.add(createPost(post)); + if (hasTag(post, hashtag)) { + posts.add(createPost(post)); + } } } @@ -83,6 +85,28 @@ public Stream getPosts() { } } + private boolean hasTag(final @NotNull JSONObject post, @NotNull final String hashtag) { + final var postRecord = post.getJSONObject("record"); + if (postRecord.has("facets")) { + final var facets = postRecord.getJSONArray("facets"); + for (var i = 0; i < facets.length(); i++) { + final var facet = facets.getJSONObject(i); + final var features = facet.getJSONArray("features"); + for (var j = 0; j < features.length(); j++) { + final var feature = features.getJSONObject(j); + final var type = feature.getString("$type"); + if (type.equals("app.bsky.richtext.facet#tag")) { + final var tag = feature.getString("tag"); + if (tag.equals(hashtag)) { + return true; + } + } + } + } + } + return false; + } + @NotNull private Post createPost(final @NotNull JSONObject post) { final var id = post.getString("uri"); diff --git a/src/test/java/swiss/fihlon/apus/plugin/social/bluesky/BlueSkyPluginTest.java b/src/test/java/swiss/fihlon/apus/plugin/social/bluesky/BlueSkyPluginTest.java index ca672fa..4196649 100644 --- a/src/test/java/swiss/fihlon/apus/plugin/social/bluesky/BlueSkyPluginTest.java +++ b/src/test/java/swiss/fihlon/apus/plugin/social/bluesky/BlueSkyPluginTest.java @@ -209,30 +209,30 @@ private static final class TestBlueSkyLoader implements BlueSkyLoader { @NotNull public JSONArray getPosts(@NotNull String instance, @NotNull String hashtag, @NotNull String postAPI) throws BlueSkyException { return switch (hashtag) { case "foobar" -> new JSONArray(List.of( - createPost(1), - createPost(2), - createPost(3), - createPost(4), - createPost(5) + createPost(1, hashtag), + createPost(2, hashtag), + createPost(3, hashtag), + createPost(4, hashtag), + createPost(5, hashtag) )); case "foo" -> new JSONArray(List.of( - createPost(6), - createPost(7) + createPost(6, hashtag), + createPost(7, hashtag) )); case "bar" -> new JSONArray(List.of( - createPost(8), - createPost(9), - createPost(10) + createPost(8, hashtag), + createPost(9, hashtag), + createPost(10, hashtag) )); case "broken" -> throw new BlueSkyException("This is an expected exception.", new RuntimeException("This is a faked cause.")); default -> new JSONArray(List.of()); }; } - private JSONObject createPost(final int i) { + private JSONObject createPost(final int i, @NotNull final String hashtag) { final var createdAt = ZonedDateTime.of(LocalDateTime.now().minusMinutes(i), ZoneId.systemDefault()); final var fakeReply = """ - "reply": { + "reply": { "parent": { "uri": "ID 1" }, @@ -253,7 +253,17 @@ private JSONObject createPost(final int i) { "record": { "createdAt": "${createdAt}", ${reply} - "text": "Content for post #${i}" + "text": "Content for post #${i}", + "facets": [ + { + "features": [ + { + "$type": "app.bsky.richtext.facet#tag", + "tag": "${tag}" + } + ] + }, + ] }, "embed": { "$type": "app.bsky.embed.images#view", @@ -269,6 +279,7 @@ private JSONObject createPost(final int i) { } """ .replaceAll(Pattern.quote("${i}"), Integer.toString(i)) + .replaceAll(Pattern.quote("${tag}"), hashtag) .replaceAll(Pattern.quote("${createdAt}"), createdAt.format(DATE_TIME_FORMATTER)) .replaceAll(Pattern.quote("${reply}"), i == 5 ? fakeReply : "");