diff --git a/packages/backend/src/core/ChatService.ts b/packages/backend/src/core/ChatService.ts index 5cd336a097..565141ea9c 100644 --- a/packages/backend/src/core/ChatService.ts +++ b/packages/backend/src/core/ChatService.ts @@ -28,6 +28,8 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js'; import { emojiRegex } from '@/misc/emoji-regex.js'; import { NotificationService } from '@/core/NotificationService.js'; import { ModerationLogService } from '@/core/ModerationLogService.js'; +import { ApDeliverManagerService } from '@/core/activitypub/ApDeliverManagerService.js'; +import { trackPromise } from '@/misc/promise-tracker.js'; const MAX_ROOM_MEMBERS = 50; const MAX_REACTIONS_PER_MESSAGE = 100; @@ -81,6 +83,7 @@ export class ChatService { private chatEntityService: ChatEntityService, private idService: IdService, private globalEventService: GlobalEventService, + private apDeliverManagerService: ApDeliverManagerService, private apRendererService: ApRendererService, private queueService: QueueService, private pushNotificationService: PushNotificationService, @@ -236,6 +239,19 @@ export class ChatService { }, 3000); } + //#region AP deliver + if (this.userEntityService.isLocalUser(fromUser) && this.userEntityService.isRemoteUser(toUser)) { + (async () => { + const content = await this.apRendererService.renderChatMessage(inserted, false); + const activity = this.apRendererService.addContext(content); + + const dm = this.apDeliverManagerService.createDeliverManager(fromUser, activity); + dm.addDirectRecipe(toUser); + trackPromise(dm.execute()); + })(); + } + //#endregion + return packedMessage; } diff --git a/packages/backend/src/core/activitypub/ApRendererService.ts b/packages/backend/src/core/activitypub/ApRendererService.ts index 55521d6e3a..9a84d77e0b 100644 --- a/packages/backend/src/core/activitypub/ApRendererService.ts +++ b/packages/backend/src/core/activitypub/ApRendererService.ts @@ -23,7 +23,7 @@ import { MfmService, type Appender } from '@/core/MfmService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js'; import type { MiUserKeypair } from '@/models/UserKeypair.js'; -import type { UsersRepository, UserProfilesRepository, NotesRepository, DriveFilesRepository, PollsRepository, MiMeta } from '@/models/_.js'; +import type { UsersRepository, UserProfilesRepository, NotesRepository, DriveFilesRepository, PollsRepository, MiMeta, MiChatMessage } from '@/models/_.js'; import { bindThis } from '@/decorators.js'; import { CustomEmojiService } from '@/core/CustomEmojiService.js'; import { IdService } from '@/core/IdService.js'; @@ -502,6 +502,37 @@ export class ApRendererService { }; } + @bindThis + public async renderChatMessage(message: MiChatMessage, dive = true): Promise { + const getPromisedFiles = async (ids: string[]): Promise => { + if (ids.length === 0) return []; + const items = await this.driveFilesRepository.findBy({ id: In(ids) }); + return ids.map(id => items.find(item => item.id === id)).filter(x => x != null); + }; + + const attributedTo = this.userEntityService.genLocalUserUri(message.fromUserId); + + const files = await getPromisedFiles([message.fileId]); + + const emojis = await this.getEmojis(message.emojis); + const apemojis = emojis.filter(emoji => !emoji.localOnly).map(emoji => this.renderEmoji(emoji)); + + const tag = [ + ...apemojis, + ]; + + return { + id: `${this.config.url}/chat-messages/${message.id}`, + type: 'Misskey:ChatMessage', + attributedTo, + text: message.text, + published: this.idService.parse(note.id).date.toISOString(), + to: message.toUserId, + attachment: files.map(x => this.renderDocument(x)), + tag, + }; + } + @bindThis public async renderPerson(user: MiLocalUser) { const id = this.userEntityService.genLocalUserUri(user.id); diff --git a/packages/backend/src/models/ChatMessage.ts b/packages/backend/src/models/ChatMessage.ts index 3d2b64268e..ca647efee9 100644 --- a/packages/backend/src/models/ChatMessage.ts +++ b/packages/backend/src/models/ChatMessage.ts @@ -55,6 +55,8 @@ export class MiChatMessage { }) public text: string | null; + // 連合用 + // ローカルはnull @Column('varchar', { length: 512, nullable: true, }) @@ -82,4 +84,22 @@ export class MiChatMessage { length: 1024, array: true, default: '{}', }) public reactions: string[]; + + // 連合用 + @Column('varchar', { + length: 128, array: true, default: '{}', + }) + public emojis: string[]; + + // 連合用 + @Column('boolean', { + default: false, + }) + public isDelivering: boolean; + + // 連合用 + @Column('boolean', { + default: false, + }) + public isDeliverFailed: boolean; }