Schedule posts to Bluesky with Cloudflare workers. skyscheduler.work
cf tool bsky-tool cloudflare bluesky schedule bsky service social-media cloudflare-workers
at main 215 lines 4.2 kB view raw
1import { BatchItem } from "drizzle-orm/batch"; 2import { Context } from "hono"; 3import { ScheduledContext } from "./classes/context"; 4import { Post } from "./classes/post"; 5import { Repost } from "./classes/repost"; 6 7/*** Settings config wrappers for bindings ***/ 8type ImageConfigSettings = { 9 enabled: boolean; 10 steps?: number[]; 11 bucket_url?: string; 12 max_width?: number; 13}; 14 15type SignupConfigSettings = { 16 use_captcha: boolean; 17 invite_only: boolean; 18 invite_thread?: string; 19 invite_uses: number; 20} 21 22type RedirectConfigSettings = { 23 contact: string; 24 tip: string; 25} 26 27type R2ConfigSettings = { 28 auto_prune: boolean; 29 prune_days?: number; 30} 31 32type QueueConfigSettings = { 33 enabled: boolean; 34 repostsEnabled: boolean; 35 threadEnabled: boolean; 36 postNowEnabled?: boolean; 37 pressure_retries?: boolean; 38 delay_val: number; 39 max_retries: number; 40 post_queues: string[]; 41 repost_queues: string[]; 42} 43 44export type AgentConfigSettings = { 45 use_posts: boolean; 46 use_reposts: boolean; 47} 48 49/** Types, types, types **/ 50export interface Bindings { 51 DB: D1Database; 52 R2: R2Bucket; 53 R2RESIZE: R2Bucket; 54 KV: KVNamespace; 55 IMAGES: ImagesBinding; 56 ASSETS?: Fetcher; 57 POST_QUEUE: Queue; 58 REPOST_QUEUE: Queue; 59 QUEUE_SETTINGS: QueueConfigSettings; 60 INVITE_POOL?: KVNamespace; 61 IMAGE_SETTINGS: ImageConfigSettings; 62 SIGNUP_SETTINGS: SignupConfigSettings; 63 TASK_SETTINGS: AgentConfigSettings; 64 R2_SETTINGS: R2ConfigSettings; 65 POST_LIMITER: RateLimit; 66 REPOST_LIMITER: RateLimit; 67 UPDATE_LIMITER: RateLimit; 68 ACCOUNT_LIMITER: RateLimit; 69 DEFAULT_ADMIN_USER: string; 70 DEFAULT_ADMIN_PASS: string; 71 DEFAULT_ADMIN_BSKY_PASS: string; 72 BETTER_AUTH_SECRET: string; 73 BETTER_AUTH_URL: string; 74 TURNSTILE_PUBLIC_KEY: string; 75 TURNSTILE_SECRET_KEY: string; 76 RESIZE_SECRET_HEADER: string; 77 RESET_BOT_USERNAME: string; 78 RESET_BOT_APP_PASS: string; 79 ENCRYPTED_PASS_KEY: string; 80 IN_DEV: boolean; 81 REDIRECTS: RedirectConfigSettings; 82}; 83 84export enum EmbedDataType { 85 None = 0, 86 Image = 1, 87 WebLink = 2, 88 Video = 3, 89 Record = 4, 90}; 91 92export type EmbedData = { 93 content: string; 94 alt?: string; 95 title?: string; 96 uri?: string; 97 type: EmbedDataType; 98 description?: string; 99 width?: number; 100 height?: number; 101 duration?: number; 102}; 103 104export enum PostLabel { 105 None = "None", 106 Suggestive = "Suggestive", 107 Nudity = "Nudity", 108 Adult = "Adult", 109 Graphic = "Graphic", 110 GraphicAdult = "GraphicAdult" 111}; 112 113export enum TaskType { 114 None, 115 Blast, 116 Post, 117 Repost, 118}; 119 120export type Violation = { 121 userId: string; 122 tosViolation: boolean; 123 userPassInvalid: boolean; 124 accountSuspended: boolean; 125 accountGone: boolean; 126 mediaTooBig: boolean; 127 createdAt: string; 128}; 129 130export type PostResponseObject = { 131 uri: string; 132 cid: string; 133}; 134 135export type PostRecordResponse = PostResponseObject & { 136 postID: string|null; 137 embeds?: EmbedData[]; 138}; 139 140export type PostStatus = { 141 records: PostRecordResponse[]; 142 // number of expected successes 143 expected: number; 144 // number of successes we got 145 got: number; 146}; 147 148export type DeleteResponse = { 149 success: boolean; 150 isRepost: boolean; 151 needsRefresh?: boolean; 152} 153 154export interface LooseObj { 155 [key: string]: any; 156}; 157 158export enum AccountStatus { 159 None = 0, 160 Ok, 161 Suspended, 162 Deactivated, 163 TakenDown, 164 InvalidAccount, 165 PlatformOutage, 166 MediaTooBig, 167 UnhandledError, 168 TOSViolation, 169}; 170 171export enum PWAutoCompleteSettings { 172 Off, 173 NewPass, 174 CurrentPass 175}; 176 177export type BskyEmbedWrapper = { 178 type: EmbedDataType; 179 data?: any; 180}; 181 182export type BskyRecordWrapper = { 183 cid?: string; 184 uri?: string; 185}; 186 187export type CreateObjectResponse = { 188 ok: boolean; 189 msg: string; 190 postId?: string; 191}; 192 193export type CreatePostQueryResponse = CreateObjectResponse & { 194 postNow?: boolean; 195}; 196 197export type QueueTaskData = { 198 type: TaskType; 199 data: Post|Repost|null; 200}; 201 202// Used for the pruning and database operations 203export type GetAllPostedBatch = { 204 id: string; 205 uri: string|null; 206}; 207 208export type R2BucketObject = { 209 name: string; 210 user: string|null; 211 date: Date 212} 213 214export type AllContext = Context|ScheduledContext; 215export type BatchQuery = [BatchItem<'sqlite'>, ...BatchItem<'sqlite'>[]];