fix(mastodon-api): DM response "no data" — return full serialized status
The minimal bare JSON returned for visibility=direct DMs caused clients (Phanpy, Elk) to show "no data" — they expect a full Mastodon Status entity. Fix: build a proper ap_timeline document, store it with visibility=direct (home/public timelines already exclude direct items), and serialize it via serializeStatus() before returning. Also store the DM in ap_notifications for the thread view as before. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -284,12 +284,14 @@ router.post("/api/v1/statuses", async (req, res, next) => {
|
||||
});
|
||||
console.info(`[Mastodon API] Sent DM to ${recipientActorUrl}`);
|
||||
|
||||
// Store in ap_notifications so it appears in the DM thread view
|
||||
const now = new Date().toISOString();
|
||||
const hostname = new URL(publicationUrl).hostname;
|
||||
const profile = await collections.ap_profile.findOne({});
|
||||
|
||||
// Store in ap_notifications for the DM thread view
|
||||
try {
|
||||
const ap_notifications = collections.ap_notifications;
|
||||
if (ap_notifications) {
|
||||
const hostname = new URL(publicationUrl).hostname;
|
||||
const profile = await collections.ap_profile.findOne({});
|
||||
await addNotification({ ap_notifications }, {
|
||||
uid: noteId.href,
|
||||
url: noteId.href,
|
||||
@@ -303,23 +305,54 @@ router.post("/api/v1/statuses", async (req, res, next) => {
|
||||
actorHandle: `@${handle}@${hostname}`,
|
||||
inReplyTo: inReplyTo || null,
|
||||
content: { text: (statusText || "").trim(), html: (statusText || "").trim() },
|
||||
published: new Date().toISOString(),
|
||||
createdAt: new Date().toISOString(),
|
||||
published: now,
|
||||
createdAt: now,
|
||||
});
|
||||
}
|
||||
} catch (storeError) {
|
||||
console.warn("[Mastodon API] Failed to store outbound DM:", storeError.message);
|
||||
console.warn("[Mastodon API] Failed to store outbound DM in notifications:", storeError.message);
|
||||
}
|
||||
|
||||
// Return a minimal status object so the client doesn't error
|
||||
return res.json({
|
||||
id: noteId.href,
|
||||
created_at: new Date().toISOString(),
|
||||
content: (statusText || "").trim(),
|
||||
visibility: "direct",
|
||||
// Store in ap_timeline with visibility=direct so serializeStatus can
|
||||
// produce a full Mastodon status object. Home/public timelines already
|
||||
// exclude direct-visibility items (visibility: { $nin: ["direct"] }).
|
||||
const timelineItem = {
|
||||
uid: noteId.href,
|
||||
url: noteId.href,
|
||||
account: { acct: handle },
|
||||
type: "note",
|
||||
visibility: "direct",
|
||||
content: {
|
||||
text: (statusText || "").trim(),
|
||||
html: (statusText || "").trim(),
|
||||
},
|
||||
author: {
|
||||
name: profile?.name || handle,
|
||||
url: actorUri.href,
|
||||
photo: profile?.icon || "",
|
||||
handle: `@${handle}@${hostname}`,
|
||||
},
|
||||
published: now,
|
||||
createdAt: now,
|
||||
inReplyTo: inReplyTo || null,
|
||||
category: [],
|
||||
counts: { likes: 0, boosts: 0, replies: 0 },
|
||||
};
|
||||
|
||||
try {
|
||||
await addTimelineItem(collections.ap_timeline, timelineItem);
|
||||
} catch (storeError) {
|
||||
console.warn("[Mastodon API] Failed to store outbound DM in timeline:", storeError.message);
|
||||
}
|
||||
|
||||
// Return a full serialized status so clients (Phanpy, Elk) can render it
|
||||
const status = serializeStatus(timelineItem, {
|
||||
baseUrl,
|
||||
favouritedIds: new Set(),
|
||||
rebloggedIds: new Set(),
|
||||
bookmarkedIds: new Set(),
|
||||
pinnedIds: new Set(),
|
||||
});
|
||||
return res.json(status);
|
||||
}
|
||||
// ── End DM path ───────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
Reference in New Issue
Block a user