diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2023-02-15 13:06:06 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-02-15 13:06:06 +0900 |
| commit | 8f2049bcd261c3fb10afdc8c15cf4edffe1baa71 (patch) | |
| tree | dc5aa1cefc24d3f6eb36bb1723d7433f8a19e5a2 /packages/backend/src/core | |
| parent | Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop (diff) | |
| download | misskey-8f2049bcd261c3fb10afdc8c15cf4edffe1baa71.tar.gz misskey-8f2049bcd261c3fb10afdc8c15cf4edffe1baa71.tar.bz2 misskey-8f2049bcd261c3fb10afdc8c15cf4edffe1baa71.zip | |
drop messaging (#9919)
* drop messaging (from backend)
* wip
Diffstat (limited to 'packages/backend/src/core')
11 files changed, 9 insertions, 553 deletions
diff --git a/packages/backend/src/core/CoreModule.ts b/packages/backend/src/core/CoreModule.ts index 6a6d1b864a..0524585ca6 100644 --- a/packages/backend/src/core/CoreModule.ts +++ b/packages/backend/src/core/CoreModule.ts @@ -22,7 +22,6 @@ import { IdService } from './IdService.js'; import { ImageProcessingService } from './ImageProcessingService.js'; import { InstanceActorService } from './InstanceActorService.js'; import { InternalStorageService } from './InternalStorageService.js'; -import { MessagingService } from './MessagingService.js'; import { MetaService } from './MetaService.js'; import { MfmService } from './MfmService.js'; import { ModerationLogService } from './ModerationLogService.js'; @@ -82,7 +81,6 @@ import { GalleryLikeEntityService } from './entities/GalleryLikeEntityService.js import { GalleryPostEntityService } from './entities/GalleryPostEntityService.js'; import { HashtagEntityService } from './entities/HashtagEntityService.js'; import { InstanceEntityService } from './entities/InstanceEntityService.js'; -import { MessagingMessageEntityService } from './entities/MessagingMessageEntityService.js'; import { ModerationLogEntityService } from './entities/ModerationLogEntityService.js'; import { MutingEntityService } from './entities/MutingEntityService.js'; import { NoteEntityService } from './entities/NoteEntityService.js'; @@ -146,7 +144,6 @@ const $IdService: Provider = { provide: 'IdService', useExisting: IdService }; const $ImageProcessingService: Provider = { provide: 'ImageProcessingService', useExisting: ImageProcessingService }; const $InstanceActorService: Provider = { provide: 'InstanceActorService', useExisting: InstanceActorService }; const $InternalStorageService: Provider = { provide: 'InternalStorageService', useExisting: InternalStorageService }; -const $MessagingService: Provider = { provide: 'MessagingService', useExisting: MessagingService }; const $MetaService: Provider = { provide: 'MetaService', useExisting: MetaService }; const $MfmService: Provider = { provide: 'MfmService', useExisting: MfmService }; const $ModerationLogService: Provider = { provide: 'ModerationLogService', useExisting: ModerationLogService }; @@ -207,7 +204,6 @@ const $GalleryLikeEntityService: Provider = { provide: 'GalleryLikeEntityService const $GalleryPostEntityService: Provider = { provide: 'GalleryPostEntityService', useExisting: GalleryPostEntityService }; const $HashtagEntityService: Provider = { provide: 'HashtagEntityService', useExisting: HashtagEntityService }; const $InstanceEntityService: Provider = { provide: 'InstanceEntityService', useExisting: InstanceEntityService }; -const $MessagingMessageEntityService: Provider = { provide: 'MessagingMessageEntityService', useExisting: MessagingMessageEntityService }; const $ModerationLogEntityService: Provider = { provide: 'ModerationLogEntityService', useExisting: ModerationLogEntityService }; const $MutingEntityService: Provider = { provide: 'MutingEntityService', useExisting: MutingEntityService }; const $NoteEntityService: Provider = { provide: 'NoteEntityService', useExisting: NoteEntityService }; @@ -273,7 +269,6 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting ImageProcessingService, InstanceActorService, InternalStorageService, - MessagingService, MetaService, MfmService, ModerationLogService, @@ -333,7 +328,6 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting GalleryPostEntityService, HashtagEntityService, InstanceEntityService, - MessagingMessageEntityService, ModerationLogEntityService, MutingEntityService, NoteEntityService, @@ -394,7 +388,6 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting $ImageProcessingService, $InstanceActorService, $InternalStorageService, - $MessagingService, $MetaService, $MfmService, $ModerationLogService, @@ -454,7 +447,6 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting $GalleryPostEntityService, $HashtagEntityService, $InstanceEntityService, - $MessagingMessageEntityService, $ModerationLogEntityService, $MutingEntityService, $NoteEntityService, @@ -516,7 +508,6 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting ImageProcessingService, InstanceActorService, InternalStorageService, - MessagingService, MetaService, MfmService, ModerationLogService, @@ -575,7 +566,6 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting GalleryPostEntityService, HashtagEntityService, InstanceEntityService, - MessagingMessageEntityService, ModerationLogEntityService, MutingEntityService, NoteEntityService, @@ -636,7 +626,6 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting $ImageProcessingService, $InstanceActorService, $InternalStorageService, - $MessagingService, $MetaService, $MfmService, $ModerationLogService, @@ -695,7 +684,6 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting $GalleryPostEntityService, $HashtagEntityService, $InstanceEntityService, - $MessagingMessageEntityService, $ModerationLogEntityService, $MutingEntityService, $NoteEntityService, diff --git a/packages/backend/src/core/GlobalEventService.ts b/packages/backend/src/core/GlobalEventService.ts index 784612149d..f70347c46a 100644 --- a/packages/backend/src/core/GlobalEventService.ts +++ b/packages/backend/src/core/GlobalEventService.ts @@ -11,13 +11,9 @@ import type { AdminStreamTypes, AntennaStreamTypes, BroadcastTypes, - ChannelStreamTypes, DriveStreamTypes, - GroupMessagingStreamTypes, InternalStreamTypes, MainStreamTypes, - MessagingIndexStreamTypes, - MessagingStreamTypes, NoteStreamTypes, UserListStreamTypes, UserStreamTypes, @@ -84,11 +80,6 @@ export class GlobalEventService { } @bindThis - public publishChannelStream<K extends keyof ChannelStreamTypes>(channelId: Channel['id'], type: K, value?: ChannelStreamTypes[K]): void { - this.publish(`channelStream:${channelId}`, type, typeof value === 'undefined' ? null : value); - } - - @bindThis public publishUserListStream<K extends keyof UserListStreamTypes>(listId: UserList['id'], type: K, value?: UserListStreamTypes[K]): void { this.publish(`userListStream:${listId}`, type, typeof value === 'undefined' ? null : value); } @@ -99,21 +90,6 @@ export class GlobalEventService { } @bindThis - public publishMessagingStream<K extends keyof MessagingStreamTypes>(userId: User['id'], otherpartyId: User['id'], type: K, value?: MessagingStreamTypes[K]): void { - this.publish(`messagingStream:${userId}-${otherpartyId}`, type, typeof value === 'undefined' ? null : value); - } - - @bindThis - public publishGroupMessagingStream<K extends keyof GroupMessagingStreamTypes>(groupId: UserGroup['id'], type: K, value?: GroupMessagingStreamTypes[K]): void { - this.publish(`messagingStream:${groupId}`, type, typeof value === 'undefined' ? null : value); - } - - @bindThis - public publishMessagingIndexStream<K extends keyof MessagingIndexStreamTypes>(userId: User['id'], type: K, value?: MessagingIndexStreamTypes[K]): void { - this.publish(`messagingIndexStream:${userId}`, type, typeof value === 'undefined' ? null : value); - } - - @bindThis public publishNotesStream(note: Packed<'Note'>): void { this.publish('notesStream', null, note); } diff --git a/packages/backend/src/core/MessagingService.ts b/packages/backend/src/core/MessagingService.ts deleted file mode 100644 index 3a8a25c602..0000000000 --- a/packages/backend/src/core/MessagingService.ts +++ /dev/null @@ -1,307 +0,0 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { In, Not } from 'typeorm'; -import { DI } from '@/di-symbols.js'; -import type { Config } from '@/config.js'; -import type { DriveFile } from '@/models/entities/DriveFile.js'; -import type { MessagingMessage } from '@/models/entities/MessagingMessage.js'; -import type { Note } from '@/models/entities/Note.js'; -import type { User, RemoteUser } from '@/models/entities/User.js'; -import type { UserGroup } from '@/models/entities/UserGroup.js'; -import { QueueService } from '@/core/QueueService.js'; -import { toArray } from '@/misc/prelude/array.js'; -import { IdentifiableError } from '@/misc/identifiable-error.js'; -import type { MessagingMessagesRepository, MutingsRepository, UserGroupJoiningsRepository, UsersRepository } from '@/models/index.js'; -import { IdService } from '@/core/IdService.js'; -import { GlobalEventService } from '@/core/GlobalEventService.js'; -import { UserEntityService } from '@/core/entities/UserEntityService.js'; -import { ApRendererService } from '@/core/activitypub/ApRendererService.js'; -import { MessagingMessageEntityService } from '@/core/entities/MessagingMessageEntityService.js'; -import { PushNotificationService } from '@/core/PushNotificationService.js'; -import { bindThis } from '@/decorators.js'; - -@Injectable() -export class MessagingService { - constructor( - @Inject(DI.config) - private config: Config, - - @Inject(DI.usersRepository) - private usersRepository: UsersRepository, - - @Inject(DI.messagingMessagesRepository) - private messagingMessagesRepository: MessagingMessagesRepository, - - @Inject(DI.userGroupJoiningsRepository) - private userGroupJoiningsRepository: UserGroupJoiningsRepository, - - @Inject(DI.mutingsRepository) - private mutingsRepository: MutingsRepository, - - private userEntityService: UserEntityService, - private messagingMessageEntityService: MessagingMessageEntityService, - private idService: IdService, - private globalEventService: GlobalEventService, - private apRendererService: ApRendererService, - private queueService: QueueService, - private pushNotificationService: PushNotificationService, - ) { - } - - @bindThis - public async createMessage(user: { id: User['id']; host: User['host']; }, recipientUser: User | undefined, recipientGroup: UserGroup | undefined, text: string | null | undefined, file: DriveFile | null, uri?: string) { - const message = { - id: this.idService.genId(), - createdAt: new Date(), - fileId: file ? file.id : null, - recipientId: recipientUser ? recipientUser.id : null, - groupId: recipientGroup ? recipientGroup.id : null, - text: text ? text.trim() : null, - userId: user.id, - isRead: false, - reads: [] as any[], - uri, - } as MessagingMessage; - - await this.messagingMessagesRepository.insert(message); - - const messageObj = await this.messagingMessageEntityService.pack(message); - - if (recipientUser) { - if (this.userEntityService.isLocalUser(user)) { - // 自分のストリーム - this.globalEventService.publishMessagingStream(message.userId, recipientUser.id, 'message', messageObj); - this.globalEventService.publishMessagingIndexStream(message.userId, 'message', messageObj); - this.globalEventService.publishMainStream(message.userId, 'messagingMessage', messageObj); - } - - if (this.userEntityService.isLocalUser(recipientUser)) { - // 相手のストリーム - this.globalEventService.publishMessagingStream(recipientUser.id, message.userId, 'message', messageObj); - this.globalEventService.publishMessagingIndexStream(recipientUser.id, 'message', messageObj); - this.globalEventService.publishMainStream(recipientUser.id, 'messagingMessage', messageObj); - } - } else if (recipientGroup) { - // グループのストリーム - this.globalEventService.publishGroupMessagingStream(recipientGroup.id, 'message', messageObj); - - // メンバーのストリーム - const joinings = await this.userGroupJoiningsRepository.findBy({ userGroupId: recipientGroup.id }); - for (const joining of joinings) { - this.globalEventService.publishMessagingIndexStream(joining.userId, 'message', messageObj); - this.globalEventService.publishMainStream(joining.userId, 'messagingMessage', messageObj); - } - } - - // 2秒経っても(今回作成した)メッセージが既読にならなかったら「未読のメッセージがありますよ」イベントを発行する - setTimeout(async () => { - const freshMessage = await this.messagingMessagesRepository.findOneBy({ id: message.id }); - if (freshMessage == null) return; // メッセージが削除されている場合もある - - if (recipientUser && this.userEntityService.isLocalUser(recipientUser)) { - if (freshMessage.isRead) return; // 既読 - - //#region ただしミュートされているなら発行しない - const mute = await this.mutingsRepository.findBy({ - muterId: recipientUser.id, - }); - if (mute.map(m => m.muteeId).includes(user.id)) return; - //#endregion - - this.globalEventService.publishMainStream(recipientUser.id, 'unreadMessagingMessage', messageObj); - this.pushNotificationService.pushNotification(recipientUser.id, 'unreadMessagingMessage', messageObj); - } else if (recipientGroup) { - const joinings = await this.userGroupJoiningsRepository.findBy({ userGroupId: recipientGroup.id, userId: Not(user.id) }); - for (const joining of joinings) { - if (freshMessage.reads.includes(joining.userId)) return; // 既読 - this.globalEventService.publishMainStream(joining.userId, 'unreadMessagingMessage', messageObj); - this.pushNotificationService.pushNotification(joining.userId, 'unreadMessagingMessage', messageObj); - } - } - }, 2000); - - if (recipientUser && this.userEntityService.isLocalUser(user) && this.userEntityService.isRemoteUser(recipientUser)) { - const note = { - id: message.id, - createdAt: message.createdAt, - fileIds: message.fileId ? [message.fileId] : [], - text: message.text, - userId: message.userId, - visibility: 'specified', - mentions: [recipientUser].map(u => u.id), - mentionedRemoteUsers: JSON.stringify([recipientUser].map(u => ({ - uri: u.uri, - username: u.username, - host: u.host, - }))), - } as Note; - - const activity = this.apRendererService.addContext(this.apRendererService.renderCreate(await this.apRendererService.renderNote(note, false, true), note)); - - this.queueService.deliver(user, activity, recipientUser.inbox); - } - return messageObj; - } - - @bindThis - public async deleteMessage(message: MessagingMessage) { - await this.messagingMessagesRepository.delete(message.id); - this.postDeleteMessage(message); - } - - @bindThis - private async postDeleteMessage(message: MessagingMessage) { - if (message.recipientId) { - const user = await this.usersRepository.findOneByOrFail({ id: message.userId }); - const recipient = await this.usersRepository.findOneByOrFail({ id: message.recipientId }); - - if (this.userEntityService.isLocalUser(user)) this.globalEventService.publishMessagingStream(message.userId, message.recipientId, 'deleted', message.id); - if (this.userEntityService.isLocalUser(recipient)) this.globalEventService.publishMessagingStream(message.recipientId, message.userId, 'deleted', message.id); - - if (this.userEntityService.isLocalUser(user) && this.userEntityService.isRemoteUser(recipient)) { - const activity = this.apRendererService.addContext(this.apRendererService.renderDelete(this.apRendererService.renderTombstone(`${this.config.url}/notes/${message.id}`), user)); - this.queueService.deliver(user, activity, recipient.inbox); - } - } else if (message.groupId) { - this.globalEventService.publishGroupMessagingStream(message.groupId, 'deleted', message.id); - } - } - - /** - * Mark messages as read - */ - @bindThis - public async readUserMessagingMessage( - userId: User['id'], - otherpartyId: User['id'], - messageIds: MessagingMessage['id'][], - ) { - if (messageIds.length === 0) return; - - const messages = await this.messagingMessagesRepository.findBy({ - id: In(messageIds), - }); - - for (const message of messages) { - if (message.recipientId !== userId) { - throw new IdentifiableError('e140a4bf-49ce-4fb6-b67c-b78dadf6b52f', 'Access denied (user).'); - } - } - - // Update documents - await this.messagingMessagesRepository.update({ - id: In(messageIds), - userId: otherpartyId, - recipientId: userId, - isRead: false, - }, { - isRead: true, - }); - - // Publish event - this.globalEventService.publishMessagingStream(otherpartyId, userId, 'read', messageIds); - this.globalEventService.publishMessagingIndexStream(userId, 'read', messageIds); - - if (!await this.userEntityService.getHasUnreadMessagingMessage(userId)) { - // 全ての(いままで未読だった)自分宛てのメッセージを(これで)読みましたよというイベントを発行 - this.globalEventService.publishMainStream(userId, 'readAllMessagingMessages'); - this.pushNotificationService.pushNotification(userId, 'readAllMessagingMessages', undefined); - } else { - // そのユーザーとのメッセージで未読がなければイベント発行 - const count = await this.messagingMessagesRepository.count({ - where: { - userId: otherpartyId, - recipientId: userId, - isRead: false, - }, - take: 1, - }); - - if (!count) { - this.pushNotificationService.pushNotification(userId, 'readAllMessagingMessagesOfARoom', { userId: otherpartyId }); - } - } - } - - /** - * Mark messages as read - */ - @bindThis - public async readGroupMessagingMessage( - userId: User['id'], - groupId: UserGroup['id'], - messageIds: MessagingMessage['id'][], - ) { - if (messageIds.length === 0) return; - - // check joined - const joining = await this.userGroupJoiningsRepository.findOneBy({ - userId: userId, - userGroupId: groupId, - }); - - if (joining == null) { - throw new IdentifiableError('930a270c-714a-46b2-b776-ad27276dc569', 'Access denied (group).'); - } - - const messages = await this.messagingMessagesRepository.findBy({ - id: In(messageIds), - }); - - const reads: MessagingMessage['id'][] = []; - - for (const message of messages) { - if (message.userId === userId) continue; - if (message.reads.includes(userId)) continue; - - // Update document - await this.messagingMessagesRepository.createQueryBuilder().update() - .set({ - reads: (() => `array_append("reads", '${joining.userId}')`) as any, - }) - .where('id = :id', { id: message.id }) - .execute(); - - reads.push(message.id); - } - - // Publish event - this.globalEventService.publishGroupMessagingStream(groupId, 'read', { - ids: reads, - userId: userId, - }); - this.globalEventService.publishMessagingIndexStream(userId, 'read', reads); - - if (!await this.userEntityService.getHasUnreadMessagingMessage(userId)) { - // 全ての(いままで未読だった)自分宛てのメッセージを(これで)読みましたよというイベントを発行 - this.globalEventService.publishMainStream(userId, 'readAllMessagingMessages'); - this.pushNotificationService.pushNotification(userId, 'readAllMessagingMessages', undefined); - } else { - // そのグループにおいて未読がなければイベント発行 - const unreadExist = await this.messagingMessagesRepository.createQueryBuilder('message') - .where('message.groupId = :groupId', { groupId: groupId }) - .andWhere('message.userId != :userId', { userId: userId }) - .andWhere('NOT (:userId = ANY(message.reads))', { userId: userId }) - .andWhere('message.createdAt > :joinedAt', { joinedAt: joining.createdAt }) // 自分が加入する前の会話については、未読扱いしない - .getOne().then(x => x != null); - - if (!unreadExist) { - this.pushNotificationService.pushNotification(userId, 'readAllMessagingMessagesOfARoom', { groupId }); - } - } - } - - @bindThis - public async deliverReadActivity(user: { id: User['id']; host: null; }, recipient: RemoteUser, messages: MessagingMessage | MessagingMessage[]) { - messages = toArray(messages).filter(x => x.uri); - const contents = messages.map(x => this.apRendererService.renderRead(user, x)); - - if (contents.length > 1) { - const collection = this.apRendererService.renderOrderedCollection(null, contents.length, undefined, undefined, contents); - this.queueService.deliver(user, this.apRendererService.addContext(collection), recipient.inbox); - } else { - for (const content of contents) { - this.queueService.deliver(user, this.apRendererService.addContext(content), recipient.inbox); - } - } - } -} diff --git a/packages/backend/src/core/PushNotificationService.ts b/packages/backend/src/core/PushNotificationService.ts index b18b7bb2cd..aff233a3e4 100644 --- a/packages/backend/src/core/PushNotificationService.ts +++ b/packages/backend/src/core/PushNotificationService.ts @@ -11,15 +11,12 @@ import { bindThis } from '@/decorators.js'; // Defined also packages/sw/types.ts#L13 type pushNotificationsTypes = { 'notification': Packed<'Notification'>; - 'unreadMessagingMessage': Packed<'MessagingMessage'>; 'unreadAntennaNote': { antenna: { id: string, name: string }; note: Packed<'Note'>; }; 'readNotifications': { notificationIds: string[] }; 'readAllNotifications': undefined; - 'readAllMessagingMessages': undefined; - 'readAllMessagingMessagesOfARoom': { userId: string } | { groupId: string }; 'readAntenna': { antennaId: string }; 'readAllAntennas': undefined; }; @@ -40,11 +37,10 @@ function truncateBody<T extends keyof pushNotificationsTypes>(type: T, body: pus reply: undefined, renote: undefined, user: type === 'notification' ? undefined as any : body.note.user, - } + }, } : {}), }; - return body; } @Injectable() @@ -81,8 +77,6 @@ export class PushNotificationService { if ([ 'readNotifications', 'readAllNotifications', - 'readAllMessagingMessages', - 'readAllMessagingMessagesOfARoom', 'readAntenna', 'readAllAntennas', ].includes(type) && !subscription.sendReadMessage) continue; diff --git a/packages/backend/src/core/activitypub/ApDbResolverService.ts b/packages/backend/src/core/activitypub/ApDbResolverService.ts index 9a894826c8..d0a4ad7a75 100644 --- a/packages/backend/src/core/activitypub/ApDbResolverService.ts +++ b/packages/backend/src/core/activitypub/ApDbResolverService.ts @@ -1,13 +1,12 @@ import { Inject, Injectable } from '@nestjs/common'; import escapeRegexp from 'escape-regexp'; import { DI } from '@/di-symbols.js'; -import type { MessagingMessagesRepository, NotesRepository, UserPublickeysRepository, UsersRepository } from '@/models/index.js'; +import type { NotesRepository, UserPublickeysRepository, UsersRepository } from '@/models/index.js'; import type { Config } from '@/config.js'; import { Cache } from '@/misc/cache.js'; import type { UserPublickey } from '@/models/entities/UserPublickey.js'; import { UserCacheService } from '@/core/UserCacheService.js'; import type { Note } from '@/models/entities/Note.js'; -import type { MessagingMessage } from '@/models/entities/MessagingMessage.js'; import { bindThis } from '@/decorators.js'; import { RemoteUser, User } from '@/models/entities/User.js'; import { getApId } from './type.js'; @@ -42,9 +41,6 @@ export class ApDbResolverService { @Inject(DI.usersRepository) private usersRepository: UsersRepository, - @Inject(DI.messagingMessagesRepository) - private messagingMessagesRepository: MessagingMessagesRepository, - @Inject(DI.notesRepository) private notesRepository: NotesRepository, @@ -101,23 +97,6 @@ export class ApDbResolverService { } } - @bindThis - public async getMessageFromApId(value: string | IObject): Promise<MessagingMessage | null> { - const parsed = this.parseUri(value); - - if (parsed.local) { - if (parsed.type !== 'notes') return null; - - return await this.messagingMessagesRepository.findOneBy({ - id: parsed.id, - }); - } else { - return await this.messagingMessagesRepository.findOneBy({ - uri: parsed.uri, - }); - } - } - /** * AP Person => Misskey User in DB */ diff --git a/packages/backend/src/core/activitypub/ApInboxService.ts b/packages/backend/src/core/activitypub/ApInboxService.ts index 62f3827343..15d7d097c9 100644 --- a/packages/backend/src/core/activitypub/ApInboxService.ts +++ b/packages/backend/src/core/activitypub/ApInboxService.ts @@ -19,8 +19,7 @@ import { UtilityService } from '@/core/UtilityService.js'; import { NoteEntityService } from '@/core/entities/NoteEntityService.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { QueueService } from '@/core/QueueService.js'; -import { MessagingService } from '@/core/MessagingService.js'; -import type { UsersRepository, NotesRepository, FollowingsRepository, MessagingMessagesRepository, AbuseUserReportsRepository, FollowRequestsRepository } from '@/models/index.js'; +import type { UsersRepository, NotesRepository, FollowingsRepository, AbuseUserReportsRepository, FollowRequestsRepository } from '@/models/index.js'; import { bindThis } from '@/decorators.js'; import type { RemoteUser } from '@/models/entities/User.js'; import { getApId, getApIds, getApType, isAccept, isActor, isAdd, isAnnounce, isBlock, isCollection, isCollectionOrOrderedCollection, isCreate, isDelete, isFlag, isFollow, isLike, isPost, isRead, isReject, isRemove, isTombstone, isUndo, isUpdate, validActor, validPost } from './type.js'; @@ -51,9 +50,6 @@ export class ApInboxService { @Inject(DI.followingsRepository) private followingsRepository: FollowingsRepository, - @Inject(DI.messagingMessagesRepository) - private messagingMessagesRepository: MessagingMessagesRepository, - @Inject(DI.abuseUserReportsRepository) private abuseUserReportsRepository: AbuseUserReportsRepository, @@ -81,7 +77,6 @@ export class ApInboxService { private apPersonService: ApPersonService, private apQuestionService: ApQuestionService, private queueService: QueueService, - private messagingService: MessagingService, ) { this.logger = this.apLoggerService.logger; } @@ -124,8 +119,6 @@ export class ApInboxService { await this.delete(actor, activity); } else if (isUpdate(activity)) { await this.update(actor, activity); - } else if (isRead(activity)) { - await this.read(actor, activity); } else if (isFollow(activity)) { await this.follow(actor, activity); } else if (isAccept(activity)) { @@ -186,29 +179,6 @@ export class ApInboxService { } @bindThis - private async read(actor: RemoteUser, activity: IRead): Promise<string> { - const id = await getApId(activity.object); - - if (!this.utilityService.isSelfHost(this.utilityService.extractDbHost(id))) { - return `skip: Read to foreign host (${id})`; - } - - const messageId = id.split('/').pop(); - - const message = await this.messagingMessagesRepository.findOneBy({ id: messageId }); - if (message == null) { - return 'skip: message not found'; - } - - if (actor.id !== message.recipientId) { - return 'skip: actor is not a message recipient'; - } - - await this.messagingService.readUserMessagingMessage(message.recipientId!, message.userId, [message.id]); - return `ok: mark as read (${message.userId} => ${message.recipientId} ${message.id})`; - } - - @bindThis private async accept(actor: RemoteUser, activity: IAccept): Promise<string> { const uri = activity.id ?? activity; @@ -504,16 +474,7 @@ export class ApInboxService { const note = await this.apDbResolverService.getNoteFromApId(uri); if (note == null) { - const message = await this.apDbResolverService.getMessageFromApId(uri); - if (message == null) return 'message not found'; - - if (message.userId !== actor.id) { - return '投稿を削除しようとしているユーザーは投稿の作成者ではありません'; - } - - await this.messagingService.deleteMessage(message); - - return 'ok: message deleted'; + return 'message not found'; } if (note.userId !== actor.id) { diff --git a/packages/backend/src/core/activitypub/ApRendererService.ts b/packages/backend/src/core/activitypub/ApRendererService.ts index 92bc1869e5..c4f9cc0556 100644 --- a/packages/backend/src/core/activitypub/ApRendererService.ts +++ b/packages/backend/src/core/activitypub/ApRendererService.ts @@ -13,7 +13,6 @@ import type { DriveFile } from '@/models/entities/DriveFile.js'; import type { NoteReaction } from '@/models/entities/NoteReaction.js'; import type { Emoji } from '@/models/entities/Emoji.js'; import type { Poll } from '@/models/entities/Poll.js'; -import type { MessagingMessage } from '@/models/entities/MessagingMessage.js'; import type { PollVote } from '@/models/entities/PollVote.js'; import { UserKeypairStoreService } from '@/core/UserKeypairStoreService.js'; import { MfmService } from '@/core/MfmService.js'; @@ -293,7 +292,7 @@ export class ApRendererService { } @bindThis - public async renderNote(note: Note, dive = true, isTalk = false): Promise<IPost> { + public async renderNote(note: Note, dive = true): Promise<IPost> { const getPromisedFiles = async (ids: string[]) => { if (!ids || ids.length === 0) return []; const items = await this.driveFilesRepository.findBy({ id: In(ids) }); @@ -407,11 +406,7 @@ export class ApRendererService { }, })), } as const : {}; - - const asTalk = isTalk ? { - _misskey_talk: true, - } as const : {}; - + return { id: `${this.config.url}/notes/${note.id}`, type: 'Note', @@ -433,7 +428,6 @@ export class ApRendererService { sensitive: note.cw != null || files.some(file => file.isSensitive), tag, ...asPoll, - ...asTalk, }; } @@ -533,15 +527,6 @@ export class ApRendererService { } @bindThis - public renderRead(user: { id: User['id'] }, message: MessagingMessage): IRead { - return { - type: 'Read', - actor: `${this.config.url}/users/${user.id}`, - object: message.uri!, - }; - } - - @bindThis public renderReject(object: any, user: { id: User['id'] }): IReject { return { type: 'Reject', @@ -643,7 +628,6 @@ export class ApRendererService { '_misskey_quote': 'misskey:_misskey_quote', '_misskey_reaction': 'misskey:_misskey_reaction', '_misskey_votes': 'misskey:_misskey_votes', - '_misskey_talk': 'misskey:_misskey_talk', 'isCat': 'misskey:isCat', // vcard vcard: 'http://www.w3.org/2006/vcard/ns#', diff --git a/packages/backend/src/core/activitypub/models/ApNoteService.ts b/packages/backend/src/core/activitypub/models/ApNoteService.ts index d4c4836887..eced94a926 100644 --- a/packages/backend/src/core/activitypub/models/ApNoteService.ts +++ b/packages/backend/src/core/activitypub/models/ApNoteService.ts @@ -1,7 +1,7 @@ import { forwardRef, Inject, Injectable } from '@nestjs/common'; import promiseLimit from 'promise-limit'; import { DI } from '@/di-symbols.js'; -import type { MessagingMessagesRepository, PollsRepository, EmojisRepository, UsersRepository } from '@/models/index.js'; +import type { PollsRepository, EmojisRepository, UsersRepository } from '@/models/index.js'; import type { Config } from '@/config.js'; import type { RemoteUser } from '@/models/entities/User.js'; import type { Note } from '@/models/entities/Note.js'; @@ -16,7 +16,6 @@ import { IdService } from '@/core/IdService.js'; import { PollService } from '@/core/PollService.js'; import { StatusError } from '@/misc/status-error.js'; import { UtilityService } from '@/core/UtilityService.js'; -import { MessagingService } from '@/core/MessagingService.js'; import { bindThis } from '@/decorators.js'; import { getOneApId, getApId, getOneApHrefNullable, validPost, isEmoji, getApType } from '../type.js'; // eslint-disable-next-line @typescript-eslint/consistent-type-imports @@ -47,9 +46,6 @@ export class ApNoteService { @Inject(DI.emojisRepository) private emojisRepository: EmojisRepository, - @Inject(DI.messagingMessagesRepository) - private messagingMessagesRepository: MessagingMessagesRepository, - private idService: IdService, private apMfmService: ApMfmService, private apResolverService: ApResolverService, @@ -64,7 +60,6 @@ export class ApNoteService { private apImageService: ApImageService, private apQuestionService: ApQuestionService, private metaService: MetaService, - private messagingService: MessagingService, private appLockService: AppLockService, private pollService: PollService, private noteCreateService: NoteCreateService, @@ -165,8 +160,6 @@ export class ApNoteService { } } - let isMessaging = note._misskey_talk && visibility === 'specified'; - const apMentions = await this.apMentionService.extractApMentions(note.tag, resolver); const apHashtags = await extractApHashtags(note.tag); @@ -193,17 +186,6 @@ export class ApNoteService { return x; } }).catch(async err => { - // トークだったらinReplyToのエラーは無視 - const uri = getApId(note.inReplyTo); - if (uri.startsWith(this.config.url + '/')) { - const id = uri.split('/').pop(); - const talk = await this.messagingMessagesRepository.findOneBy({ id }); - if (talk) { - isMessaging = true; - return null; - } - } - this.logger.warn(`Error in inReplyTo ${note.inReplyTo} - ${err.statusCode ?? err}`); throw err; }) @@ -292,14 +274,7 @@ export class ApNoteService { const apEmojis = emojis.map(emoji => emoji.name); const poll = await this.apQuestionService.extractPollFromQuestion(note, resolver).catch(() => undefined); - - if (isMessaging) { - for (const recipient of visibleUsers) { - await this.messagingService.createMessage(actor, recipient, undefined, text ?? undefined, (files && files.length > 0) ? files[0] : null, object.id); - return null; - } - } - + return await this.noteCreateService.create(actor, { createdAt: note.published ? new Date(note.published) : null, files, diff --git a/packages/backend/src/core/activitypub/type.ts b/packages/backend/src/core/activitypub/type.ts index 9dc7ed4e31..268bf99119 100644 --- a/packages/backend/src/core/activitypub/type.ts +++ b/packages/backend/src/core/activitypub/type.ts @@ -113,7 +113,6 @@ export interface IPost extends IObject { _misskey_quote?: string; _misskey_content?: string; quoteUrl?: string; - _misskey_talk?: boolean; } export interface IQuestion extends IObject { diff --git a/packages/backend/src/core/entities/MessagingMessageEntityService.ts b/packages/backend/src/core/entities/MessagingMessageEntityService.ts deleted file mode 100644 index cdb752dd81..0000000000 --- a/packages/backend/src/core/entities/MessagingMessageEntityService.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { DI } from '@/di-symbols.js'; -import type { MessagingMessagesRepository } from '@/models/index.js'; -import { awaitAll } from '@/misc/prelude/await-all.js'; -import type { Packed } from '@/misc/schema.js'; -import type { } from '@/models/entities/Blocking.js'; -import type { User } from '@/models/entities/User.js'; -import type { MessagingMessage } from '@/models/entities/MessagingMessage.js'; -import { UserEntityService } from './UserEntityService.js'; -import { DriveFileEntityService } from './DriveFileEntityService.js'; -import { UserGroupEntityService } from './UserGroupEntityService.js'; -import { bindThis } from '@/decorators.js'; - -@Injectable() -export class MessagingMessageEntityService { - constructor( - @Inject(DI.messagingMessagesRepository) - private messagingMessagesRepository: MessagingMessagesRepository, - - private userEntityService: UserEntityService, - private userGroupEntityService: UserGroupEntityService, - private driveFileEntityService: DriveFileEntityService, - ) { - } - - @bindThis - public async pack( - src: MessagingMessage['id'] | MessagingMessage, - me?: { id: User['id'] } | null | undefined, - options?: { - populateRecipient?: boolean, - populateGroup?: boolean, - }, - ): Promise<Packed<'MessagingMessage'>> { - const opts = options ?? { - populateRecipient: true, - populateGroup: true, - }; - - const message = typeof src === 'object' ? src : await this.messagingMessagesRepository.findOneByOrFail({ id: src }); - - return { - id: message.id, - createdAt: message.createdAt.toISOString(), - text: message.text, - userId: message.userId, - user: await this.userEntityService.pack(message.user ?? message.userId, me), - recipientId: message.recipientId, - recipient: message.recipientId && opts.populateRecipient ? await this.userEntityService.pack(message.recipient ?? message.recipientId, me) : undefined, - groupId: message.groupId, - group: message.groupId && opts.populateGroup ? await this.userGroupEntityService.pack(message.group ?? message.groupId) : undefined, - fileId: message.fileId, - file: message.fileId ? await this.driveFileEntityService.pack(message.fileId) : null, - isRead: message.isRead, - reads: message.reads, - }; - } -} - diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts index fa3337c019..19bae443c8 100644 --- a/packages/backend/src/core/entities/UserEntityService.ts +++ b/packages/backend/src/core/entities/UserEntityService.ts @@ -12,7 +12,7 @@ import { Cache } from '@/misc/cache.js'; import type { Instance } from '@/models/entities/Instance.js'; import type { LocalUser, RemoteUser, User } from '@/models/entities/User.js'; import { birthdaySchema, descriptionSchema, localUsernameSchema, locationSchema, nameSchema, passwordSchema } from '@/models/entities/User.js'; -import type { UsersRepository, UserSecurityKeysRepository, FollowingsRepository, FollowRequestsRepository, BlockingsRepository, MutingsRepository, DriveFilesRepository, NoteUnreadsRepository, ChannelFollowingsRepository, NotificationsRepository, UserNotePiningsRepository, UserProfilesRepository, InstancesRepository, AnnouncementReadsRepository, MessagingMessagesRepository, UserGroupJoiningsRepository, AnnouncementsRepository, AntennaNotesRepository, PagesRepository, UserProfile } from '@/models/index.js'; +import type { UsersRepository, UserSecurityKeysRepository, FollowingsRepository, FollowRequestsRepository, BlockingsRepository, MutingsRepository, DriveFilesRepository, NoteUnreadsRepository, ChannelFollowingsRepository, NotificationsRepository, UserNotePiningsRepository, UserProfilesRepository, InstancesRepository, AnnouncementReadsRepository, UserGroupJoiningsRepository, AnnouncementsRepository, AntennaNotesRepository, PagesRepository, UserProfile } from '@/models/index.js'; import { bindThis } from '@/decorators.js'; import { RoleService } from '@/core/RoleService.js'; import type { OnModuleInit } from '@nestjs/common'; @@ -102,9 +102,6 @@ export class UserEntityService implements OnModuleInit { @Inject(DI.announcementReadsRepository) private announcementReadsRepository: AnnouncementReadsRepository, - @Inject(DI.messagingMessagesRepository) - private messagingMessagesRepository: MessagingMessagesRepository, - @Inject(DI.userGroupJoiningsRepository) private userGroupJoiningsRepository: UserGroupJoiningsRepository, @@ -205,36 +202,6 @@ export class UserEntityService implements OnModuleInit { } @bindThis - public async getHasUnreadMessagingMessage(userId: User['id']): Promise<boolean> { - const mute = await this.mutingsRepository.findBy({ - muterId: userId, - }); - - const joinings = await this.userGroupJoiningsRepository.findBy({ userId: userId }); - - const groupQs = Promise.all(joinings.map(j => this.messagingMessagesRepository.createQueryBuilder('message') - .where('message.groupId = :groupId', { groupId: j.userGroupId }) - .andWhere('message.userId != :userId', { userId: userId }) - .andWhere('NOT (:userId = ANY(message.reads))', { userId: userId }) - .andWhere('message.createdAt > :joinedAt', { joinedAt: j.createdAt }) // 自分が加入する前の会話については、未読扱いしない - .getOne().then(x => x != null))); - - const [withUser, withGroups] = await Promise.all([ - this.messagingMessagesRepository.count({ - where: { - recipientId: userId, - isRead: false, - ...(mute.length > 0 ? { userId: Not(In(mute.map(x => x.muteeId))) } : {}), - }, - take: 1, - }).then(count => count > 0), - groupQs, - ]); - - return withUser || withGroups.some(x => x); - } - - @bindThis public async getHasUnreadAnnouncement(userId: User['id']): Promise<boolean> { const reads = await this.announcementReadsRepository.findBy({ userId: userId, @@ -492,7 +459,6 @@ export class UserEntityService implements OnModuleInit { hasUnreadAnnouncement: this.getHasUnreadAnnouncement(user.id), hasUnreadAntenna: this.getHasUnreadAntenna(user.id), hasUnreadChannel: this.getHasUnreadChannel(user.id), - hasUnreadMessagingMessage: this.getHasUnreadMessagingMessage(user.id), hasUnreadNotification: this.getHasUnreadNotification(user.id), hasPendingReceivedFollowRequest: this.getHasPendingReceivedFollowRequest(user.id), mutedWords: profile!.mutedWords, |