mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-05-13 16:25:44 +02:00
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
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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(),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>;
|
||||
|
||||
Reference in New Issue
Block a user