diff --git a/packages/backend/src/remote/activitypub/kernel/update/index.ts b/packages/backend/src/remote/activitypub/kernel/update/index.ts index 4f1514ddd1..d805557801 100644 --- a/packages/backend/src/remote/activitypub/kernel/update/index.ts +++ b/packages/backend/src/remote/activitypub/kernel/update/index.ts @@ -1,10 +1,10 @@ import type { CacheableRemoteUser } from "@/models/entities/user.js"; -import type { IUpdate } from "../../type.js"; +import type { IPost, IUpdate } from "../../type.js"; import { getApType, isActor } from "../../type.js"; import { apLogger } from "../../logger.js"; -import { updateQuestion } from "../../models/question.js"; import Resolver from "../../resolver.js"; import { updatePerson } from "../../models/person.js"; +import { updatePost } from "../../models/note.js"; /** * Handler for the Update activity @@ -29,10 +29,17 @@ export default async ( if (isActor(object)) { await updatePerson(actor.uri!, resolver, object); return "ok: Person updated"; - } else if (getApType(object) === "Question") { - await updateQuestion(object, resolver).catch((e) => console.log(e)); - return "ok: Question updated"; - } else { - return `skip: Unknown type: ${getApType(object)}`; + } + + switch (getApType(object)) { + case 'Question': + case 'Note': + case 'Article': + case 'Document': + case 'Page': + await updatePost(activity, object as IPost, resolver); + return `ok: Post updated`; + default: + return `skip: Unknown type: ${getApType(object)}`; } }; diff --git a/packages/backend/src/remote/activitypub/models/note.ts b/packages/backend/src/remote/activitypub/models/note.ts index 72953c5bfb..cc98e3cc11 100644 --- a/packages/backend/src/remote/activitypub/models/note.ts +++ b/packages/backend/src/remote/activitypub/models/note.ts @@ -9,15 +9,15 @@ import type { CacheableRemoteUser } from "@/models/entities/user.js"; import { htmlToMfm } from "../misc/html-to-mfm.js"; import { extractApHashtags } from "./tag.js"; import { unique, toArray, toSingle } from "@/prelude/array.js"; -import { extractPollFromQuestion } from "./question.js"; +import { extractPollFromQuestion, updateQuestion } from "./question.js"; import vote from "@/services/note/polls/vote.js"; import { apLogger } from "../logger.js"; import type { DriveFile } from "@/models/entities/drive-file.js"; import { deliverQuestionUpdate } from "@/services/note/polls/update.js"; import { extractDbHost, toPuny } from "@/misc/convert-host.js"; -import { Emojis, Polls, MessagingMessages } from "@/models/index.js"; +import { Emojis, Polls, MessagingMessages, Notes } from "@/models/index.js"; import type { Note } from "@/models/entities/note.js"; -import type { IObject, IPost } from "../type.js"; +import type { IObject, IPost, IUpdate } from "../type.js"; import { getOneApId, getApId, @@ -350,6 +350,33 @@ export async function createNote( ); } +/** + * Update info of Post + * @param uri URI of AP post object + * @returns true if updated + */ +export async function updatePost(activity: IUpdate, value: any, resolver?: Resolver) { + + const uri = typeof value === "string" ? value : value.id; + + // Skip if URI points to this server + if (uri.startsWith(`${config.url}/`)) throw new Error("uri points local"); + + //#region Already registered with this server? + const note = await Notes.findOneBy({ uri }); + if (note == null) throw new Error("Post is not registed"); + //#endregion + + // resolve new Post object + if (resolver == null) resolver = new Resolver(); + const post = (await resolver.resolve(value)) as IPost; + + if (post.type == "Question") { + updateQuestion(value, resolver, note); + } + +} + /** * Resolve Note. * diff --git a/packages/backend/src/remote/activitypub/models/question.ts b/packages/backend/src/remote/activitypub/models/question.ts index 520b9fee94..18aa1ca619 100644 --- a/packages/backend/src/remote/activitypub/models/question.ts +++ b/packages/backend/src/remote/activitypub/models/question.ts @@ -50,27 +50,18 @@ export async function extractPollFromQuestion( * @param uri URI of AP Question object * @returns true if updated */ -export async function updateQuestion(value: any, resolver?: Resolver) { +export async function updateQuestion(value: any, resolver: Resolver, note: any) { const uri = typeof value === "string" ? value : value.id; - // Skip if URI points to this server - if (uri.startsWith(`${config.url}/`)) throw new Error("uri points local"); - //#region Already registered with this server? - const note = await Notes.findOneBy({ uri }); - if (note == null) throw new Error("Question is not registed"); - const poll = await Polls.findOneBy({ noteId: note.id }); if (poll == null) throw new Error("Question is not registed"); //#endregion // resolve new Question object - if (resolver == null) resolver = new Resolver(); const question = (await resolver.resolve(value)) as IQuestion; apLogger.debug(`fetched question: ${JSON.stringify(question, null, 2)}`); - if (question.type !== "Question") throw new Error("object is not a Question"); - const apChoices = question.oneOf || question.anyOf; let changed = false; diff --git a/packages/backend/src/remote/activitypub/type.ts b/packages/backend/src/remote/activitypub/type.ts index b0bdb0a8b4..ebfee8c792 100644 --- a/packages/backend/src/remote/activitypub/type.ts +++ b/packages/backend/src/remote/activitypub/type.ts @@ -148,6 +148,7 @@ export interface IQuestion extends IObject { }; _misskey_quote?: string; quoteUrl?: string; + quoteUri?: string; oneOf?: IQuestionChoice[]; anyOf?: IQuestionChoice[]; endTime?: Date;