Announcement Scheduling#
Misskey supports two distinct scheduling mechanisms for time-based content lifecycle management:
- Scheduled Notes — user notes published at a future datetime, added in 2025.10.0.
- Auto-archiving Announcements — a planned feature to automatically archive announcements past a given datetime .
These two features are independent: scheduled notes are fully implemented via the queue system; auto-archiving for announcements is an open feature request as of July 2026.
Scheduled Notes#
Data Model#
Scheduled notes extend the MiNoteDraft entity with two fields :
scheduledAt(TIMESTAMP WITH TIME ZONE, nullable) — the intended publish datetime.isActuallyScheduled(boolean, defaultfalse) — whether the draft has an active job in the queue. A draft can have ascheduledAttime without being committed to the queue; both fields must be set for a note to be auto-posted.
The DB migration that adds these columns is 1758677617888-scheduled-post.js.
Scheduling Flow#
- Draft creation/update — When a user submits a note with a future
scheduledAt,NoteDraftService.schedule()calculatesdelay = scheduledAt - nowin milliseconds and enqueues a job inpostScheduledNoteQueuewith that delay. - Queue processing — At the scheduled time,
PostScheduledNoteProcessorService.process()fires. It validates that the draft still exists,isActuallyScheduledis true, andscheduledAtis set, then callsnoteCreateService.fetchAndCreate()to create the note from the draft data. - Cleanup — After the note is created, the draft is deleted . The user receives a
scheduledNotePostednotification on success orscheduledNotePostFailedon error . - Cancellation/reschedule —
NoteDraftService.clearSchedule()removes the active queue job when a draft is updated or deleted .
Queue Wiring#
The postScheduledNoteQueue is registered in QueueService and QueueModule . The processor is wired in QueueProcessorModule / QueueProcessorService . Completed jobs are retained for 7 days (max 30); failed jobs are retained for 7 days (max 100).
Role-Gating#
Scheduled posting can be controlled per-role via role policy , similar to other note permissions.
Announcements (Current State — No Scheduling)#
The current MiAnnouncement entity has no datetime-based lifecycle fields — there is no scheduledAt, expiresAt, or equivalent column. Active/inactive state is controlled solely by the isActive boolean flag, which moderators set manually.
The AnnouncementService covers:
create()— persists a new announcement and broadcasts viaGlobalEventService.update()— togglesisActiveand other fields.delete()— hard-deletes the record.read()— marks an announcement as read; auto-deactivates user-targeted announcements after the targeted user reads them.
The admin API endpoint for creating announcements is admin/announcements/create; it accepts title, text, display (normal/banner/dialog), icon, silence, needConfirmationToRead, and optional userId for user-targeted announcements .
Planned: Auto-Archive by Datetime#
Issue #17688 proposes adding an optional auto-archive datetime to announcements — e.g., auto-deactivate a maintenance notice after the maintenance window ends. As of July 2026 this is not yet implemented; moderators must archive announcements manually.
Key Source Files#
| Purpose | Path |
|---|---|
| Note draft model (scheduled fields) | packages/backend/src/models/NoteDraft.ts |
| Schedule/clear-schedule logic | packages/backend/src/core/NoteDraftService.ts |
| Scheduled note queue processor | packages/backend/src/queue/processors/PostScheduledNoteProcessorService.ts |
| DB migration (scheduled post) | packages/backend/migration/1758677617888-scheduled-post.js |
| Announcement entity | packages/backend/src/models/Announcement.ts |
| Announcement service | packages/backend/src/core/AnnouncementService.ts |
| Admin create announcement API | packages/backend/src/server/api/endpoints/admin/announcements/create.ts |