diff --git a/src/remote/activitypub/act/create/index.ts b/src/remote/activitypub/act/create/index.ts index d210aa4c5..7ab4c2aba 100644 --- a/src/remote/activitypub/act/create/index.ts +++ b/src/remote/activitypub/act/create/index.ts @@ -16,8 +16,6 @@ export default async (actor: IRemoteUser, activity): Promise => { log(`Create: ${uri}`); - // TODO: 同じURIをもつものが既に登録されていないかチェック - const resolver = new Resolver(); let object; diff --git a/src/remote/activitypub/act/create/note.ts b/src/remote/activitypub/act/create/note.ts index 8b22f1b47..253478b6f 100644 --- a/src/remote/activitypub/act/create/note.ts +++ b/src/remote/activitypub/act/create/note.ts @@ -4,23 +4,31 @@ import * as debug from 'debug'; import Resolver from '../../resolver'; import Post, { IPost } from '../../../../models/post'; import createPost from '../../../../services/post/create'; -import { IRemoteUser, isRemoteUser } from '../../../../models/user'; +import { IRemoteUser } from '../../../../models/user'; import resolvePerson from '../../resolve-person'; import createImage from './image'; +import config from '../../../../config'; const log = debug('misskey:activitypub'); +/** + * 投稿作成アクティビティを捌きます + */ export default async function createNote(resolver: Resolver, actor: IRemoteUser, note, silent = false): Promise { - if ( - ('attributedTo' in note && actor.account.uri !== note.attributedTo) || - typeof note.id !== 'string' - ) { + if (typeof note.id !== 'string') { log(`invalid note: ${JSON.stringify(note, null, 2)}`); throw new Error('invalid note'); } + // 既に同じURIを持つものが登録されていないかチェックし、登録されていたらそれを返す + const exist = await Post.findOne({ uri: note.id }); + if (exist) { + return exist; + } + log(`Creating the Note: ${note.id}`); + //#region 添付メディア const media = []; if ('attachment' in note && note.attachment != null) { // TODO: attachmentは必ずしもImageではない @@ -30,21 +38,31 @@ export default async function createNote(resolver: Resolver, actor: IRemoteUser, media.push(created); }); } + //#endregion + //#region リプライ let reply = null; if ('inReplyTo' in note && note.inReplyTo != null) { - const inReplyToPost = await Post.findOne({ uri: note.inReplyTo.id || note.inReplyTo }); + // リプライ先の投稿がMisskeyに登録されているか調べる + const uri: string = note.inReplyTo.id || note.inReplyTo; + const inReplyToPost = uri.startsWith(config.url + '/') + ? await Post.findOne({ _id: uri.split('/').pop() }) + : await Post.findOne({ uri }); + if (inReplyToPost) { reply = inReplyToPost; } else { + // 無かったらフェッチ const inReplyTo = await resolver.resolve(note.inReplyTo) as any; - const actor = await resolvePerson(inReplyTo.attributedTo); - if (isRemoteUser(actor)) { - // TODO: silentを常にtrueにしてはならない - reply = await createNote(resolver, actor, inReplyTo); - } + + // リプライ先の投稿の投稿者をフェッチ + const actor = await resolvePerson(inReplyTo.attributedTo) as IRemoteUser; + + // TODO: silentを常にtrueにしてはならない + reply = await createNote(resolver, actor, inReplyTo); } } + //#endregion const { window } = new JSDOM(note.content); diff --git a/src/remote/activitypub/renderer/note.ts b/src/remote/activitypub/renderer/note.ts index e45b10215..b971a5395 100644 --- a/src/remote/activitypub/renderer/note.ts +++ b/src/remote/activitypub/renderer/note.ts @@ -19,11 +19,11 @@ export default async (user: IUser, post: IPost) => { if (inReplyToPost !== null) { const inReplyToUser = await User.findOne({ - _id: post.userId, + _id: inReplyToPost.userId, }); if (inReplyToUser !== null) { - inReplyTo = `${config.url}@${inReplyToUser.username}/${inReplyToPost._id}`; + inReplyTo = inReplyToPost.uri || `${config.url}/@${inReplyToUser.username}/${inReplyToPost._id}`; } } } else {