diff --git a/README.md b/README.md index aae947575dab..f67ae510b141 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ - 新着ノート通知があった時まとめるように https://github.com/team-shahu/misskey/pull/40 - いいねボタンの実装 https://github.com/team-shahu/misskey/pull/41 https://github.com/team-shahu/misskey/pull/44 https://github.com/team-shahu/misskey/pull/45 - 独自機能ページの追加 https://github.com/team-shahu/misskey/pull/42 -- 予約投稿機能 https://github.com/team-shahu/misskey/pull/46 +- 予約投稿機能 https://github.com/team-shahu/misskey/pull/46 https://github.com/team-shahu/misskey/pull/49 https://github.com/team-shahu/misskey/pull/51 - フォロー/フォロリクの履歴 https://github.com/team-shahu/misskey/pull/49 https://github.com/team-shahu/misskey/pull/50 ## Special Thanks diff --git a/packages/backend/src/models/NoteSchedule.ts b/packages/backend/src/models/NoteSchedule.ts index dde0af6ad763..bb6cb4d7f39c 100644 --- a/packages/backend/src/models/NoteSchedule.ts +++ b/packages/backend/src/models/NoteSchedule.ts @@ -37,6 +37,7 @@ export type MiScheduleNoteType={ apMentions?: MinimumUser[] | null; apHashtags?: string[] | null; apEmojis?: string[] | null; + deleteAt?: string | null; } @Entity('note_schedule') diff --git a/packages/backend/src/queue/processors/ScheduleNotePostProcessorService.ts b/packages/backend/src/queue/processors/ScheduleNotePostProcessorService.ts index f281b0ed7bc2..8ec14ed11a41 100644 --- a/packages/backend/src/queue/processors/ScheduleNotePostProcessorService.ts +++ b/packages/backend/src/queue/processors/ScheduleNotePostProcessorService.ts @@ -119,6 +119,7 @@ export class ScheduleNotePostProcessorService { reply, renote, channel, + deleteAt: note.deleteAt ? new Date(note.deleteAt) : null, }); await this.noteScheduleRepository.remove(data); this.notificationService.createNotification(me.id, 'scheduledNotePosted', { diff --git a/packages/backend/src/server/api/endpoints/notes/schedule/create.ts b/packages/backend/src/server/api/endpoints/notes/schedule/create.ts index 520837ce94d2..9018e6c75705 100644 --- a/packages/backend/src/server/api/endpoints/notes/schedule/create.ts +++ b/packages/backend/src/server/api/endpoints/notes/schedule/create.ts @@ -117,6 +117,18 @@ export const meta = { code: 'CANNOT_RENOTE_OUTSIDE_OF_CHANNEL', id: '33510210-8452-094c-6227-4a6c05d99f00', }, + + cannotScheduleDeleteEarlierThanNow: { + message: 'Scheduled delete time is earlier than now.', + code: 'CANNOT_SCHEDULE_DELETE_EARLIER_THAN_NOW', + id: '9576c3c8-d8f3-11ee-ac15-00155d19d35d', + }, + + cannotScheduleDeleteLaterThanOneYear: { + message: 'Scheduled delete time is later than one year.', + code: 'CANNOT_SCHEDULE_DELETE_LATER_THAN_ONE_YEAR', + id: 'b02b5edb-2741-4841-b692-d9893f1e6515', + }, }, } as const; @@ -181,6 +193,14 @@ export const paramDef = { scheduledAt: { type: 'integer', nullable: false }, }, }, + scheduledDelete: { + type: 'object', + nullable: true, + properties: { + deleteAt: { type: 'number', nullable: true }, + deleteAfter: { type: 'number', nullable: true }, + }, + }, }, // (re)note with text, files and poll are optional anyOf: [ @@ -326,6 +346,21 @@ export default class extends Endpoint { // eslint- } else { throw new ApiError(meta.errors.cannotCreateAlreadyExpiredSchedule); } + + if (ps.scheduledDelete) { + if (typeof ps.scheduledDelete.deleteAt === 'number') { + if (ps.scheduledDelete.deleteAt < Date.now()) { + throw new ApiError(meta.errors.cannotScheduleDeleteEarlierThanNow); + } + } else if (typeof ps.scheduledDelete.deleteAfter === 'number') { + ps.scheduledDelete.deleteAt = ps.scheduleNote.scheduledAt + ps.scheduledDelete.deleteAfter; + } + + if (ps.scheduledDelete.deleteAt && ps.scheduledDelete.deleteAt > ps.scheduleNote.scheduledAt + ms('1year')) { + throw new ApiError(meta.errors.cannotScheduleDeleteLaterThanOneYear); + } + } + const note: MiScheduleNoteType = { files: files.map(f => f.id), poll: ps.poll ? { @@ -344,6 +379,9 @@ export default class extends Endpoint { // eslint- apMentions: ps.noExtractMentions ? [] : undefined, apHashtags: ps.noExtractHashtags ? [] : undefined, apEmojis: ps.noExtractEmojis ? [] : undefined, + deleteAt: ps.scheduledDelete && ps.scheduledDelete.deleteAt + ? new Date(ps.scheduledDelete.deleteAt).toISOString() + : null, }; if (ps.scheduleNote.scheduledAt) {