fix: read inbound mention/hashtag tags via getTags(), not object.tag

A hydrated Fedify object has no .tag property — tags are exposed through the
async getTags() iterator. The mention-notification check (if object.tag) and
the followed-hashtag check were therefore dead code: every inbound mention
failed to create a notification, and followed-tag posts never landed in the
timeline. Proven by replaying a real captured Bridgy Create payload: object.tag
=== undefined while getTags() yields the Mention. Switched both sites to
for await (... object.getTags()) with constructor.name type checks.
This commit is contained in:
svemagie
2026-06-14 18:04:31 +02:00
parent 6a1d55b836
commit 32ea375378
+14 -10
View File
@@ -781,12 +781,12 @@ export async function handleCreate(item, collections, ctx, handle) {
} }
} }
// Check for mentions of our actor // Check for mentions of our actor.
if (object.tag) { // NB: a hydrated Fedify object exposes tags via async getTags(), NOT a `.tag`
const tags = Array.isArray(object.tag) ? object.tag : [object.tag]; // property — `object.tag` is always undefined, so the old check never ran.
{
for (const tag of tags) { for await (const tag of object.getTags({ documentLoader: authLoader })) {
if (tag.type === "Mention" && tag.href?.href === ourActorUrl) { if (tag.constructor?.name === "Mention" && tag.href?.href === ourActorUrl) {
const actorInfo = await extractActorInfo(actorObj, { documentLoader: authLoader }); const actorInfo = await extractActorInfo(actorObj, { documentLoader: authLoader });
const rawMentionHtml = object.content?.toString() || ""; const rawMentionHtml = object.content?.toString() || "";
const mentionHtml = sanitizeContent(rawMentionHtml); const mentionHtml = sanitizeContent(rawMentionHtml);
@@ -860,10 +860,14 @@ export async function handleCreate(item, collections, ctx, handle) {
// Not a followed account — check if the post's hashtags match any followed tags // Not a followed account — check if the post's hashtags match any followed tags
// so tagged posts from across the fediverse appear in the timeline // so tagged posts from across the fediverse appear in the timeline
try { try {
const objectTags = Array.isArray(object.tag) ? object.tag : (object.tag ? [object.tag] : []); // Tags come from async getTags() — `object.tag` is always undefined on a
const postHashtags = objectTags // hydrated Fedify object (same gotcha as the mention check above).
.filter((t) => t.type === "Hashtag" && t.name) const postHashtags = [];
.map((t) => t.name.toString().replace(/^#/, "").toLowerCase()); for await (const t of object.getTags({ documentLoader: authLoader })) {
if (t.constructor?.name === "Hashtag" && t.name) {
postHashtags.push(t.name.toString().replace(/^#/, "").toLowerCase());
}
}
if (postHashtags.length > 0) { if (postHashtags.length > 0) {
const followedTags = await getFollowedTags(collections); const followedTags = await getFollowedTags(collections);