summaryrefslogtreecommitdiff
path: root/packages/backend/src/queue
diff options
context:
space:
mode:
authorsyuilo <4439005+syuilo@users.noreply.github.com>2025-09-26 15:29:52 +0900
committerGitHub <noreply@github.com>2025-09-26 15:29:52 +0900
commitd1446d195abb52c560c7c97177d08103a175acf7 (patch)
tree355689adb542333f4c5abb186ab9819c29274612 /packages/backend/src/queue
parentfix(frontend): ビルド成果物のファイル名にlocalesのhashを含め... (diff)
downloadmisskey-d1446d195abb52c560c7c97177d08103a175acf7.tar.gz
misskey-d1446d195abb52c560c7c97177d08103a175acf7.tar.bz2
misskey-d1446d195abb52c560c7c97177d08103a175acf7.zip
feat: scheduled post (#16577)
* Update NoteDraft.ts * Update NoteDraft.ts * wip * Update CHANGELOG.md * wip * Update PostScheduledNoteProcessorService.ts * Update PostScheduledNoteProcessorService.ts * Update Notification.ts * wip * Update NoteDraftService.ts * Update NoteDraftService.ts * Update NoteDraftService.ts * wip * Create 1758677617888-scheduled-post.js * Update index.d.ts * Update stats.ts * wip * wip * wip * wip * wip * Update MkNotification.vue * wip * wip * wip * Update NoteDraftService.ts * Update NoteDraftService.ts * wip * wip * Update NoteDraftEntityService.ts * wip * Update index.d.ts * Update MkPostForm.vue * wip * wip * wip * Update NoteCreateService.ts * wip * wip * wip * Update NoteDraftEntityService.ts * Update NoteCreateService.ts * Update NoteDraftService.ts * wip * Update NoteDraftService.ts * wip * wip * Update MkPostForm.vue * wip * Update MkPostForm.vue * Update os.ts * wip * Update MkNoteDraftsDialog.vue
Diffstat (limited to 'packages/backend/src/queue')
-rw-r--r--packages/backend/src/queue/QueueProcessorModule.ts2
-rw-r--r--packages/backend/src/queue/QueueProcessorService.ts20
-rw-r--r--packages/backend/src/queue/const.ts1
-rw-r--r--packages/backend/src/queue/processors/PostScheduledNoteProcessorService.ts72
-rw-r--r--packages/backend/src/queue/types.ts4
5 files changed, 99 insertions, 0 deletions
diff --git a/packages/backend/src/queue/QueueProcessorModule.ts b/packages/backend/src/queue/QueueProcessorModule.ts
index e01414cd53..e64882c4df 100644
--- a/packages/backend/src/queue/QueueProcessorModule.ts
+++ b/packages/backend/src/queue/QueueProcessorModule.ts
@@ -10,6 +10,7 @@ import { QueueLoggerService } from './QueueLoggerService.js';
import { QueueProcessorService } from './QueueProcessorService.js';
import { DeliverProcessorService } from './processors/DeliverProcessorService.js';
import { EndedPollNotificationProcessorService } from './processors/EndedPollNotificationProcessorService.js';
+import { PostScheduledNoteProcessorService } from './processors/PostScheduledNoteProcessorService.js';
import { InboxProcessorService } from './processors/InboxProcessorService.js';
import { UserWebhookDeliverProcessorService } from './processors/UserWebhookDeliverProcessorService.js';
import { SystemWebhookDeliverProcessorService } from './processors/SystemWebhookDeliverProcessorService.js';
@@ -79,6 +80,7 @@ import { RelationshipProcessorService } from './processors/RelationshipProcessor
UserWebhookDeliverProcessorService,
SystemWebhookDeliverProcessorService,
EndedPollNotificationProcessorService,
+ PostScheduledNoteProcessorService,
DeliverProcessorService,
InboxProcessorService,
AggregateRetentionProcessorService,
diff --git a/packages/backend/src/queue/QueueProcessorService.ts b/packages/backend/src/queue/QueueProcessorService.ts
index 7b64182754..642d3fc8ad 100644
--- a/packages/backend/src/queue/QueueProcessorService.ts
+++ b/packages/backend/src/queue/QueueProcessorService.ts
@@ -14,6 +14,7 @@ import { CheckModeratorsActivityProcessorService } from '@/queue/processors/Chec
import { UserWebhookDeliverProcessorService } from './processors/UserWebhookDeliverProcessorService.js';
import { SystemWebhookDeliverProcessorService } from './processors/SystemWebhookDeliverProcessorService.js';
import { EndedPollNotificationProcessorService } from './processors/EndedPollNotificationProcessorService.js';
+import { PostScheduledNoteProcessorService } from './processors/PostScheduledNoteProcessorService.js';
import { DeliverProcessorService } from './processors/DeliverProcessorService.js';
import { InboxProcessorService } from './processors/InboxProcessorService.js';
import { DeleteDriveFilesProcessorService } from './processors/DeleteDriveFilesProcessorService.js';
@@ -85,6 +86,7 @@ export class QueueProcessorService implements OnApplicationShutdown {
private relationshipQueueWorker: Bull.Worker;
private objectStorageQueueWorker: Bull.Worker;
private endedPollNotificationQueueWorker: Bull.Worker;
+ private postScheduledNoteQueueWorker: Bull.Worker;
constructor(
@Inject(DI.config)
@@ -94,6 +96,7 @@ export class QueueProcessorService implements OnApplicationShutdown {
private userWebhookDeliverProcessorService: UserWebhookDeliverProcessorService,
private systemWebhookDeliverProcessorService: SystemWebhookDeliverProcessorService,
private endedPollNotificationProcessorService: EndedPollNotificationProcessorService,
+ private postScheduledNoteProcessorService: PostScheduledNoteProcessorService,
private deliverProcessorService: DeliverProcessorService,
private inboxProcessorService: InboxProcessorService,
private deleteDriveFilesProcessorService: DeleteDriveFilesProcessorService,
@@ -520,6 +523,21 @@ export class QueueProcessorService implements OnApplicationShutdown {
});
}
//#endregion
+
+ //#region post scheduled note
+ {
+ this.postScheduledNoteQueueWorker = new Bull.Worker(QUEUE.POST_SCHEDULED_NOTE, async (job) => {
+ if (this.config.sentryForBackend) {
+ return Sentry.startSpan({ name: 'Queue: PostScheduledNote' }, () => this.postScheduledNoteProcessorService.process(job));
+ } else {
+ return this.postScheduledNoteProcessorService.process(job);
+ }
+ }, {
+ ...baseWorkerOptions(this.config, QUEUE.POST_SCHEDULED_NOTE),
+ autorun: false,
+ });
+ }
+ //#endregion
}
@bindThis
@@ -534,6 +552,7 @@ export class QueueProcessorService implements OnApplicationShutdown {
this.relationshipQueueWorker.run(),
this.objectStorageQueueWorker.run(),
this.endedPollNotificationQueueWorker.run(),
+ this.postScheduledNoteQueueWorker.run(),
]);
}
@@ -549,6 +568,7 @@ export class QueueProcessorService implements OnApplicationShutdown {
this.relationshipQueueWorker.close(),
this.objectStorageQueueWorker.close(),
this.endedPollNotificationQueueWorker.close(),
+ this.postScheduledNoteQueueWorker.close(),
]);
}
diff --git a/packages/backend/src/queue/const.ts b/packages/backend/src/queue/const.ts
index 7e146a7e03..625204b7ad 100644
--- a/packages/backend/src/queue/const.ts
+++ b/packages/backend/src/queue/const.ts
@@ -12,6 +12,7 @@ export const QUEUE = {
INBOX: 'inbox',
SYSTEM: 'system',
ENDED_POLL_NOTIFICATION: 'endedPollNotification',
+ POST_SCHEDULED_NOTE: 'postScheduledNote',
DB: 'db',
RELATIONSHIP: 'relationship',
OBJECT_STORAGE: 'objectStorage',
diff --git a/packages/backend/src/queue/processors/PostScheduledNoteProcessorService.ts b/packages/backend/src/queue/processors/PostScheduledNoteProcessorService.ts
new file mode 100644
index 0000000000..d0eaeee090
--- /dev/null
+++ b/packages/backend/src/queue/processors/PostScheduledNoteProcessorService.ts
@@ -0,0 +1,72 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and misskey-project
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import { Inject, Injectable } from '@nestjs/common';
+import { DI } from '@/di-symbols.js';
+import type { NoteDraftsRepository } from '@/models/_.js';
+import type Logger from '@/logger.js';
+import { NotificationService } from '@/core/NotificationService.js';
+import { bindThis } from '@/decorators.js';
+import { NoteCreateService } from '@/core/NoteCreateService.js';
+import { QueueLoggerService } from '../QueueLoggerService.js';
+import type * as Bull from 'bullmq';
+import type { PostScheduledNoteJobData } from '../types.js';
+
+@Injectable()
+export class PostScheduledNoteProcessorService {
+ private logger: Logger;
+
+ constructor(
+ @Inject(DI.noteDraftsRepository)
+ private noteDraftsRepository: NoteDraftsRepository,
+
+ private noteCreateService: NoteCreateService,
+ private notificationService: NotificationService,
+ private queueLoggerService: QueueLoggerService,
+ ) {
+ this.logger = this.queueLoggerService.logger.createSubLogger('post-scheduled-note');
+ }
+
+ @bindThis
+ public async process(job: Bull.Job<PostScheduledNoteJobData>): Promise<void> {
+ const draft = await this.noteDraftsRepository.findOne({ where: { id: job.data.noteDraftId }, relations: ['user'] });
+ if (draft == null || draft.user == null || draft.scheduledAt == null || !draft.isActuallyScheduled) {
+ return;
+ }
+
+ try {
+ const note = await this.noteCreateService.fetchAndCreate(draft.user, {
+ createdAt: new Date(),
+ fileIds: draft.fileIds,
+ poll: draft.hasPoll ? {
+ choices: draft.pollChoices,
+ multiple: draft.pollMultiple,
+ expiresAt: draft.pollExpiredAfter ? new Date(Date.now() + draft.pollExpiredAfter) : draft.pollExpiresAt ? new Date(draft.pollExpiresAt) : null,
+ } : null,
+ text: draft.text ?? null,
+ replyId: draft.replyId,
+ renoteId: draft.renoteId,
+ cw: draft.cw,
+ localOnly: draft.localOnly,
+ reactionAcceptance: draft.reactionAcceptance,
+ visibility: draft.visibility,
+ visibleUserIds: draft.visibleUserIds,
+ channelId: draft.channelId,
+ });
+
+ // await不要
+ this.noteDraftsRepository.remove(draft);
+
+ // await不要
+ this.notificationService.createNotification(draft.userId, 'scheduledNotePosted', {
+ noteId: note.id,
+ });
+ } catch (err) {
+ this.notificationService.createNotification(draft.userId, 'scheduledNotePostFailed', {
+ noteDraftId: draft.id,
+ });
+ }
+ }
+}
diff --git a/packages/backend/src/queue/types.ts b/packages/backend/src/queue/types.ts
index 757daea88b..1cb2b93918 100644
--- a/packages/backend/src/queue/types.ts
+++ b/packages/backend/src/queue/types.ts
@@ -109,6 +109,10 @@ export type EndedPollNotificationJobData = {
noteId: MiNote['id'];
};
+export type PostScheduledNoteJobData = {
+ noteDraftId: string;
+};
+
export type SystemWebhookDeliverJobData<T extends SystemWebhookEventType = SystemWebhookEventType> = {
type: T;
content: SystemWebhookPayload<T>;