diff --git a/packages/backend/src/core/ChannelMutingService.ts b/packages/backend/src/core/ChannelMutingService.ts index 4917f80c37..041ac19305 100644 --- a/packages/backend/src/core/ChannelMutingService.ts +++ b/packages/backend/src/core/ChannelMutingService.ts @@ -5,8 +5,9 @@ import { Inject, Injectable } from '@nestjs/common'; import Redis from 'ioredis'; +import { In } from 'typeorm'; import { DI } from '@/di-symbols.js'; -import type { ChannelMutingRepository, ChannelsRepository, MiChannel, MiUser } from '@/models/_.js'; +import type { ChannelMutingRepository, ChannelsRepository, MiChannel, MiChannelMuting, MiUser } from '@/models/_.js'; import { IdService } from '@/core/IdService.js'; import { GlobalEvents, GlobalEventService } from '@/core/GlobalEventService.js'; import { bindThis } from '@/decorators.js'; @@ -64,7 +65,7 @@ export class ChannelMutingService { .where('channel_muting.userId = :userId', { userId: params.requestUserId }) .andWhere(qb => { qb.where('channel_muting.expiresAt IS NULL') - .orWhere('channel_muting.expiresAt > :now:', { now: new Date() }); + .orWhere('channel_muting.expiresAt > :now', { now: new Date() }); }); if (opts?.joinUser) { @@ -78,6 +79,32 @@ export class ChannelMutingService { return q.getMany(); } + /** + * 期限切れのチャンネルミュート情報を取得する. + * + * @param [opts] + * @param {(boolean|undefined)} [opts.joinUser=undefined] チャンネルミュートを設定したユーザ情報をJOINするかどうか(falseまたは省略時はJOINしない). + * @param {(boolean|undefined)} [opts.joinChannel=undefined] ミュート先のチャンネル情報をJOINするかどうか(falseまたは省略時はJOINしない). + */ + public async findExpiredMutings(opts?: { + joinUser?: boolean; + joinChannel?: boolean; + }): Promise { + const now = new Date(); + const q = this.channelMutingRepository.createQueryBuilder('channel_muting') + .where('channel_muting.expiresAt < :now', { now }); + + if (opts?.joinUser) { + q.innerJoinAndSelect('channel_muting.user', 'user'); + } + + if (opts?.joinChannel) { + q.leftJoinAndSelect('channel_muting.channel', 'channel'); + } + + return q.getMany(); + } + /** * 既にミュートされているかどうかをキャッシュから取得する. * @param params @@ -136,6 +163,20 @@ export class ChannelMutingService { }); } + /** + * 期限切れのチャンネルミュート情報を削除する. + */ + @bindThis + public async eraseExpiredMutings(): Promise { + const expiredMutings = await this.findExpiredMutings(); + await this.channelMutingRepository.delete({ id: In(expiredMutings.map(x => x.id)) }); + + const userIds = [...new Set(expiredMutings.map(x => x.userId))]; + for (const userId of userIds) { + this.userMutingChannelsCache.refresh(userId).then(); + } + } + @bindThis private async onMessage(_: string, data: string): Promise { const obj = JSON.parse(data); diff --git a/packages/backend/src/queue/processors/CheckExpiredMutingsProcessorService.ts b/packages/backend/src/queue/processors/CheckExpiredMutingsProcessorService.ts index 448fc9c763..e898e6dd48 100644 --- a/packages/backend/src/queue/processors/CheckExpiredMutingsProcessorService.ts +++ b/packages/backend/src/queue/processors/CheckExpiredMutingsProcessorService.ts @@ -4,14 +4,13 @@ */ import { Inject, Injectable } from '@nestjs/common'; -import { In } from 'typeorm'; import { DI } from '@/di-symbols.js'; import type { MutingsRepository } from '@/models/_.js'; import type Logger from '@/logger.js'; import { bindThis } from '@/decorators.js'; import { UserMutingService } from '@/core/UserMutingService.js'; +import { ChannelMutingService } from '@/core/ChannelMutingService.js'; import { QueueLoggerService } from '../QueueLoggerService.js'; -import type * as Bull from 'bullmq'; @Injectable() export class CheckExpiredMutingsProcessorService { @@ -22,6 +21,7 @@ export class CheckExpiredMutingsProcessorService { private mutingsRepository: MutingsRepository, private userMutingService: UserMutingService, + private channelMutingService: ChannelMutingService, private queueLoggerService: QueueLoggerService, ) { this.logger = this.queueLoggerService.logger.createSubLogger('check-expired-mutings'); @@ -41,6 +41,8 @@ export class CheckExpiredMutingsProcessorService { await this.userMutingService.unmute(expired); } + await this.channelMutingService.eraseExpiredMutings(); + this.logger.succ('All expired mutings checked.'); } }