Unverified Commit 79ef2c57 authored by Hong Minhee's avatar Hong Minhee
Browse files

Merge tag '1.2.2'

Fedify 1.2.2
parents 5c1eaa6b 9e253200
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -9,6 +9,20 @@ Version 1.3.0
To be released.


Version 1.2.2
-------------

Released on November 1, 2024.

 -  Handle connection errors (rather than HTTP errors) in
    the `Context.sendActivity()` method.

 -  Support the `fedify` command on Windows on ARM64 via x64 emulation.
    [[#160]]

[#160]: https://github.com/dahlia/fedify/issues/160


Version 1.2.1
-------------

+2 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@ import {
} from "node:fs/promises";
import { tmpdir } from "node:os";
import { dirname, join } from "node:path";
import process from "node:process";
import { Readable } from "node:stream";
import { fileURLToPath } from "node:url";

@@ -25,6 +26,7 @@ const platforms = {
    x64: "linux-x86_64.tar.xz",
  },
  win32: {
    arm64: "windows-x86_64.zip",
    x64: "windows-x86_64.zip",
  },
};
+100 −0
Original line number Diff line number Diff line
@@ -76,6 +76,106 @@ multiple inbox listeners for different activity types.
[shared inbox]: https://www.w3.org/TR/activitypub/#shared-inbox-delivery


Determining the recipient of an activity
----------------------------------------

### Looking at the `to`, `cc`, `bto`, and `bcc` fields

When you receive an activity, you may want to determine the recipient of the
activity.  The recipient is usually the actor who is mentioned in
the `to`, `cc`, `bto`, or `bcc` field of the activity.  The following shows
how to determine the recipient of a `Create` activity:

~~~~ typescript twoslash
import { Create, type InboxListenerSetters } from "@fedify/fedify";
(0 as unknown as InboxListenerSetters<void>)
// ---cut-before---
.on(Create, async (ctx, create) => {
  if (create.toId == null) return;
  const to = ctx.parseUri(create.toId);
  if (to?.type !== "actor") return;
  const recipient = to.identifier;
  // Do something with the recipient
});
~~~~

The `to`, `cc`, `bto`, and `bcc` fields can contain multiple recipients,
so you may need to iterate over them to determine the recipient of the activity:

~~~~ typescript twoslash
import { Create, type InboxListenerSetters } from "@fedify/fedify";
(0 as unknown as InboxListenerSetters<void>)
// ---cut-before---
.on(Create, async (ctx, create) => {
  for (const toId of create.toIds) {
    const to = ctx.parseUri(toId);
    if (to?.type !== "actor") continue;
    const recipient = to.identifier;
    // Do something with the recipient
  }
});
~~~~

Also, the `to`, `cc`, `bto`, and `bcc` fields can contain both actor and
collection objects.  In such cases, you may need to recursively resolve the
collection objects to determine the recipients of the activity:

~~~~ typescript twoslash
import { 
  Collection,
  Create,
  type InboxListenerSetters,
  isActor,
} from "@fedify/fedify";
(0 as unknown as InboxListenerSetters<void>)
// ---cut-before---
.on(Create, async (ctx, create) => {
  for await (const to of create.getTos()) {
    if (isActor(to)) {
      // `to` is a recipient of the activity
      // Do something with the recipient
    } else if (to instanceof Collection) {
      // `to` is a collection object
      for await (const actor of to.getItems()) {
        if (!isActor(actor)) continue;
        // `actor` is a recipient of the activity
        // Do something with the recipient
      }
    }
  }
});
~~~~

> [!TIP]
> It might look strange, non-scalar accessor methods for `to`, `cc`, `bto`,
> and `bcc` fields are named as `~Object.getTos()`, `~Object.getCcs()`,
> `~Object.getBtos()`, and `~Object.getBccs()`, respectively.

### Looking at the `InboxContext.recipient` property

*This API is available since Fedify 1.2.0.*

However, the `to`, `cc`, `bto`, and `bcc` fields are not always present in
an activity.  In such cases, you can determine the recipient by looking at
the `InboxContext.recipient` property.  The below example shows how to determine
the recipient of a `Follow` activity:

~~~~ typescript twoslash
import { Follow, type InboxListenerSetters } from "@fedify/fedify";
(0 as unknown as InboxListenerSetters<void>)
// ---cut-before---
.on(Follow, async (ctx, follow) => {
  const recipient = ctx.recipient;
  // Do something with the recipient
});
~~~~

The `~InboxContext.recipient` property is set to the identifier of the actor
who is the recipient of the activity.  If the invocation is not for a personal
inbox, but for a shared inbox, the `~InboxContext.recipient` property is set to
`null`.


`Context.documentLoader` on an inbox listener
---------------------------------------------

+14 −1
Original line number Diff line number Diff line
@@ -152,7 +152,20 @@ export async function sendActivity(
  } else {
    request = await signRequest(request, rsaKey.privateKey, rsaKey.keyId);
  }
  const response = await fetch(request);
  let response: Response;
  try {
    response = await fetch(request);
  } catch (error) {
    logger.error(
      "Failed to send activity {activityId} to {inbox}:\n{error}",
      {
        activityId,
        inbox: inbox.href,
        error,
      },
    );
    throw error;
  }
  if (!response.ok) {
    let error;
    try {