diff --git a/packages/backend/src/server/api/endpoints.ts b/packages/backend/src/server/api/endpoints.ts index a0d629439..bae486fa7 100644 --- a/packages/backend/src/server/api/endpoints.ts +++ b/packages/backend/src/server/api/endpoints.ts @@ -214,6 +214,7 @@ import * as ep___notes_clips from './endpoints/notes/clips.js'; import * as ep___notes_conversation from './endpoints/notes/conversation.js'; import * as ep___notes_create from './endpoints/notes/create.js'; import * as ep___notes_delete from './endpoints/notes/delete.js'; +import * as ep___notes_delete_many from './endpoints/notes/delete-many.js'; import * as ep___notes_featured from './endpoints/notes/featured.js'; import * as ep___notes_globalTimeline from './endpoints/notes/global-timeline.js'; import * as ep___notes_hybridTimeline from './endpoints/notes/hybrid-timeline.js'; @@ -509,6 +510,7 @@ const eps = [ ['notes/conversation', ep___notes_conversation], ['notes/create', ep___notes_create], ['notes/delete', ep___notes_delete], + ['notes/delete-many', ep___notes_delete_many], ['notes/featured', ep___notes_featured], ['notes/global-timeline', ep___notes_globalTimeline], ['notes/hybrid-timeline', ep___notes_hybridTimeline], diff --git a/packages/backend/src/server/api/endpoints/notes/delete-many.ts b/packages/backend/src/server/api/endpoints/notes/delete-many.ts new file mode 100644 index 000000000..a418be6c2 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/notes/delete-many.ts @@ -0,0 +1,46 @@ +import { deleteNotes } from '@/services/note/delete.js'; +import define from '@/server/api/define.js'; +import { Notes } from '@/models/index.js'; +import { ApiError } from '@/server/api/error.js'; + +export const meta = { + tags: ['notes'], + + description: 'Deletes multiple notes. This will be processed in a more performant way than deleting the notes with individual API calls.', + + requireCredential: true, + requireAdmin: true, + + kind: 'write:notes', + + // Since only admins can use this API endpoint, a rate limit would not + // apply to them anyway so the rate limit for deletions is not added here. + + errors: ['NO_SUCH_NOTE'], +} as const; + +export const paramDef = { + type: 'object', + properties: { + noteIds: { + type: 'array', + uniqueItems: true, + minItems: 1, + items: { type: 'string', format: 'misskey:id' }, + }, + }, + required: ['noteIds'], +} as const; + +// eslint-disable-next-line import/no-default-export +export default define(meta, paramDef, async (ps, user) => { + try { + const notes = await Promise.all( + ps.noteIds.map(noteId => Notes.findOneByOrFail({ id: noteId })) + ); + + await deleteNotes(notes); + } catch { + throw new ApiError('NO_SUCH_NOTE'); + } +});