Unverified Commit 7229ab29 authored by Hong Minhee's avatar Hong Minhee
Browse files

examples/blog: Better interop w/ Misskey

parent 4dffb89a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@
    "halfyear",
    "httpsig",
    "logtape",
    "Misskey",
    "nodeinfo",
    "preact",
    "unfollow",
+7 −10
Original line number Diff line number Diff line
@@ -192,7 +192,11 @@ federation.setInboxListeners("/users/{handle}/inbox", "/inbox")
    await ctx.sendActivity(
      { handle: blog.handle },
      recipient,
      new Accept({ actor: follow.objectId, object: follow }),
      new Accept({
        id: new URL(`#accept/${handle}`, ctx.getActorUri(blog.handle)),
        actor: follow.objectId,
        object: follow,
      }),
    );
  })
  // The `Create` activity is handled by adding a comment to the post:
@@ -238,21 +242,14 @@ federation.setInboxListeners("/users/{handle}/inbox", "/inbox")
  .on(Undo, async (ctx, undo) => {
    const activity = await undo.getObject(ctx); // An `Activity` to undo
    if (activity instanceof Follow) {
      if (activity.id == null) return;
      await removeFollower(activity.id.href);
      if (activity.id == null || activity.actorId == null) return;
      await removeFollower(activity.id.href, activity.actorId.href);
    } else {
      logger.getChild("inbox").warn(
        "Unsupported object type ({type}) for Undo activity: {object}",
        { type: activity?.constructor.name, object: activity },
      );
    }
  })
  .onError((_ctx, error) => {
    logger.getChild("inbox").error(
      "An error occurred while processing an activity in the inbox handler:\n" +
        "{error}",
      { error },
    );
  });

// Since the blog does not follow anyone, the following dispatcher is
+20 −2
Original line number Diff line number Diff line
@@ -23,14 +23,32 @@ export async function addFollower(follower: Follower): Promise<Follower> {
  return follower;
}

export async function removeFollower(activityId: string): Promise<void> {
export async function removeFollower(
  activityId: string,
  actorId: string,
): Promise<void> {
  const kv = await openKv();
  const follower = await kv.get<Follower>(["follower", activityId]);
  const followers = await kv.get<bigint>(["followers"]);
  if (
    follower == null || follower.value == null || followers == null ||
    followers.value == null
  ) return;
  ) {
    // Sometimes Follow.id and Undo<Follow>.object.id do not match...
    // (e.g., Misskey)
    for await (const entry of kv.list<Follower>({ prefix: ["follower"] })) {
      if (entry.value.id === actorId) {
        const followers = await kv.get<bigint>(["followers"]);
        if (followers == null || followers.value == null) continue;
        await kv.atomic()
          .check(follower)
          .check(followers)
          .delete(entry.key)
          .set(["followers"], followers.value - 1n)
          .commit();
      }
    }
  }
  await kv.atomic()
    .check(follower)
    .check(followers)