fdba547124
Deploy Indiekit Server / deploy (push) Successful in 1m15s
bsky.brid.gy DMs arrive as ChatMessage objects with content in source.content (plain text) instead of content (HTML). The inbox handler only checked object.content, so all bridged DMs were stored with empty text and unviewable in Mona. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
62 lines
2.3 KiB
JavaScript
62 lines
2.3 KiB
JavaScript
/**
|
|
* Patch: extract DM content from object.source.content when object.content is empty.
|
|
*
|
|
* Bluesky DMs bridged via bsky.brid.gy arrive as Create activities wrapping a
|
|
* ChatMessage object. Bridgy Fed sends the message text in `source.content`
|
|
* (plain text, mediaType: text/plain) without a `content` field (HTML).
|
|
*
|
|
* The DM handler only checked `object.content`, so all bsky.brid.gy DMs were
|
|
* stored with empty content, making them unviewable in Mona.
|
|
*
|
|
* Fix: after extracting `rawHtml` from `object.content`, also read
|
|
* `object.source?.content` as a plain-text fallback for `contentText` when
|
|
* `rawHtml` is empty.
|
|
*/
|
|
|
|
import { access, readFile, writeFile } from "node:fs/promises";
|
|
|
|
const candidates = [
|
|
"node_modules/@rmdes/indiekit-endpoint-activitypub/lib/inbox-handlers.js",
|
|
"node_modules/@indiekit/indiekit/node_modules/@rmdes/indiekit-endpoint-activitypub/lib/inbox-handlers.js",
|
|
];
|
|
|
|
const MARKER = "// [patch] bsky-source-content-fallback";
|
|
|
|
const OLD = ` const rawHtml = object.content?.toString() || "";
|
|
const contentHtml = sanitizeContent(rawHtml);
|
|
const contentText = rawHtml.replace(/<[^>]*>/g, "").substring(0, 500);`;
|
|
|
|
const NEW = ` const rawHtml = object.content?.toString() || "";
|
|
const sourceText = object.source?.content?.toString() || ""; // [patch] bsky-source-content-fallback
|
|
const contentHtml = sanitizeContent(rawHtml);
|
|
const contentText = rawHtml
|
|
? rawHtml.replace(/<[^>]*>/g, "").substring(0, 500)
|
|
: sourceText.substring(0, 500);`;
|
|
|
|
async function exists(p) {
|
|
try { await access(p); return true; } catch { return false; }
|
|
}
|
|
|
|
let patched = false;
|
|
for (const filePath of candidates) {
|
|
if (!(await exists(filePath))) continue;
|
|
const src = await readFile(filePath, "utf8");
|
|
if (src.includes(MARKER)) {
|
|
console.log(`[postinstall] patch-ap-dm-bsky-source-content: already applied in ${filePath}`);
|
|
patched = true;
|
|
break;
|
|
}
|
|
if (!src.includes(OLD)) {
|
|
console.log(`[postinstall] patch-ap-dm-bsky-source-content: target snippet not found in ${filePath}`);
|
|
continue;
|
|
}
|
|
await writeFile(filePath, src.replace(OLD, NEW), "utf8");
|
|
console.log(`[postinstall] patch-ap-dm-bsky-source-content: applied to ${filePath}`);
|
|
patched = true;
|
|
break;
|
|
}
|
|
|
|
if (!patched) {
|
|
console.log("[postinstall] patch-ap-dm-bsky-source-content: no target file found");
|
|
}
|