Scheduled posts: written now, published at their time

POST /api/v1/statuses with scheduled_at no longer posts at once: the post is
kept as asked (at least five minutes ahead; 300 waiting, 25 a day, as
Mastodon allows), its media kept from the janitor, and a PublishScheduled job
publishes it at its time as the persona. scheduled_statuses lists, moves and
drops them; a moved post's old job finds it not due. Idempotency-Key holds
for scheduling too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
This commit is contained in:
thepraandClaude Opus 5.5 committed 2026-10-05 02:55:17 +02:00
1 parent 73c362de96
commit cafd2e6db3
13 files changed
+418 -26

No files matched your search

+2 -1
View File
@@ -31,7 +31,8 @@ namespace PrivaPub.Models.Jobs
CrawlPlan,
CrawlInstance,
SendRecovery,
CountAccount
CountAccount,
PublishScheduled
}
public enum JobState
+1
View File
@@ -18,6 +18,7 @@ namespace PrivaPub.Models.Media
public float[] Focus { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime? AttachedAt { get; set; }
public string ScheduledStatusId { get; set; }//kept for a scheduled post until it is published or dropped
}
public class MediaSecret : Entity
+37
View File
@@ -0,0 +1,37 @@
using MongoDB.Entities;
namespace PrivaPub.Models.Social
{
//a post a persona wrote to be published later (Mastodon's scheduled statuses, owner decision 2026-10-04): what it
//asked for, kept as it asked, published by a PublishScheduled job at ScheduledAt. Nothing leaves before then.
public class ScheduledStatus : Entity
{
public string AvatarId { get; set; }
public DateTime ScheduledAt { get; set; }
public ScheduledParams Params { get; set; } = new();
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
}
public class ScheduledParams
{
public string Text { get; set; }
public string SpoilerText { get; set; }
public bool Sensitive { get; set; }
public string Visibility { get; set; }//public, unlisted, private, direct
public string InReplyToId { get; set; }
public string Language { get; set; }
public List<string> MediaIds { get; set; } = new();
public ScheduledPoll Poll { get; set; }
public string QuotedStatusId { get; set; }
public string QuotePolicy { get; set; }
public string Idempotency { get; set; }
}
public class ScheduledPoll
{
public List<string> Options { get; set; } = new();
public int ExpiresIn { get; set; }
public bool Multiple { get; set; }
public bool HideTotals { get; set; }
}
}