Schedule posts to Bluesky with Cloudflare workers. skyscheduler.work
cf tool bsky-tool cloudflare bluesky schedule bsky service social-media cloudflare-workers
at main 127 lines 4.7 kB view raw
1import remove from "just-remove"; 2 3/** APPLICATION CONFIGURATIONS **/ 4 5// minimum length of a post 6export const MIN_LENGTH: number = 1; 7// max amount of times something can be reposted 8export const MAX_REPOST_INTERVAL: number = 15; 9// max amount of time something can be reposted over 10export const MAX_REPOST_DAYS: number = 10; 11// max length of an animated gif in minutes 12export const MAX_GIF_LENGTH: number = 1; 13// if gifs should be allowed to upload 14export const GIF_UPLOAD_ALLOWED: boolean = false; 15// max posts per thread 16export const MAX_POSTS_PER_THREAD: number = 10; 17 18// This is the length of how much we keep in the DB after a post has been made 19export const MAX_POSTED_LENGTH: number = 50; 20 21// Dashboard password length settings 22export const MIN_DASHBOARD_PASS: number = 8; 23export const MAX_DASHBOARD_PASS: number = 30; 24 25// max amount of returns from bsky handle search 26export const BSKY_NAME_LOOKUP_LIMIT: number = 8; // 8 is the same value bsky uses 27// number of characters to activate a bsky handle search 28export const BSKY_NAME_TYPE_AHEAD_CHARS: number = 2; 29 30// the maximum size of an image file to generate a thumbnail for, in MB. 31// generation is done on client side using canvas elements. 32export const MAX_THUMBNAIL_SIZE: number = 15; 33 34// the maximum amount of repost posts an account can have at any one time. 35// because some people went incredibly overboard. 36export const MAX_REPOST_POSTS: number = 40; 37 38// a limit for the maximum number of repost rules a single post can have 39export const MAX_REPOST_RULES_PER_POST: number = 5; 40 41/** INTERNAL LIMITS, DO NOT CHANGE **/ 42// Maximums used internally, do not change these directly. 43export const MAX_REPOST_INTERVAL_LIMIT: number = MAX_REPOST_INTERVAL + 1; 44export const MAX_REPOST_IN_HOURS: number = (MAX_REPOST_DAYS * 24) + 1; 45 46// Helper conversion math 47export const MB_TO_BYTES: number = 1000 * 1000; 48export const TO_SEC: number = 60; 49export const TO_MS: number = TO_SEC*1000; 50 51// Max post length limit via 52// https://github.com/bluesky-social/social-app/blob/b38013a12ff22a3ebd3075baa0d98bc96302a316/src/lib/constants.ts#L63 53export const MAX_LENGTH: number = 300; 54 55// Alt text limit via 56// https://github.com/bluesky-social/social-app/blob/b38013a12ff22a3ebd3075baa0d98bc96302a316/src/lib/constants.ts#L69 57export const MAX_ALT_TEXT: number = 2000; 58 59// Image limit values via 60// https://github.com/bluesky-social/social-app/blob/b38013a12ff22a3ebd3075baa0d98bc96302a316/src/lib/constants.ts#L97 61export const BSKY_IMG_MAX_WIDTH: number = 2000; 62export const BSKY_IMG_MAX_HEIGHT: number = 2000; 63export const BSKY_IMG_SIZE_LIMIT_IN_MB: number = 1; 64export const BSKY_IMG_MIME_TYPES: string[] = [ 65 "image/png", 66 "image/jpeg", 67 "image/webp", 68 "image/heic", 69 "image/bmp", 70 "image/avif", 71 "image/svg+xml" 72]; 73 74// Used for human readable display 75export const BSKY_IMG_FILE_EXTS: string = [ 76 "png", 77 "jpg", 78 "jpeg", 79 "bmp", 80 "webp", 81 "heic", 82 "svg" 83].join(", "); 84 85// BSky limits that are inferred 86export const BSKY_MIN_USERNAME_LENGTH: number = 4; 87export const BSKY_MAX_USERNAME_LENGTH: number = 256; // since these are domains, they should be about 256 88export const BSKY_MAX_APP_PASSWORD_LENGTH: number = 20; 89export const MAX_EMBEDS_PER_POST: number = 4; 90 91// Video limits values via 92// https://github.com/bluesky-social/social-app/blob/b38013a12ff22a3ebd3075baa0d98bc96302a316/src/lib/constants.ts#L184 93export const BSKY_VIDEO_MAX_DURATION: number = 3; // in minutes 94export const BSKY_VIDEO_MAX_SIZE_IN_MB: number = 100; 95export const BSKY_VIDEO_MIME_TYPES: string[] = [ 96 "video/mp4", 97 "video/mpeg", 98 "video/webm", 99 "video/quicktime" 100]; 101 102// Used for human readable display 103export const BSKY_GIF_MIME_TYPES: string[] = [ 104 "image/gif" 105]; 106 107// Used for human readable display 108export const BSKY_VIDEO_FILE_EXTS: string = remove([ 109 "mp4", 110 "mpeg", 111 "mov", 112 "webm", 113 /* This is handled in a special case because bluesky */ 114 (GIF_UPLOAD_ALLOWED ? "animated gif" : undefined) 115], [undefined]).join(", "); 116 117// Max size of files that can go to R2 without doing multipart uploads 118export const R2_FILE_SIZE_LIMIT_IN_MB: number = 100; 119export const R2_FILE_SIZE_LIMIT: number = R2_FILE_SIZE_LIMIT_IN_MB * MB_TO_BYTES; 120export const BSKY_IMG_SIZE_LIMIT: number = BSKY_IMG_SIZE_LIMIT_IN_MB * MB_TO_BYTES; 121export const BSKY_VIDEO_SIZE_LIMIT: number = BSKY_VIDEO_MAX_SIZE_IN_MB * MB_TO_BYTES; 122export const BSKY_VIDEO_LENGTH_LIMIT: number = BSKY_VIDEO_MAX_DURATION * TO_SEC; 123export const MAX_GIF_LENGTH_LIMIT: number = MAX_GIF_LENGTH * TO_SEC; 124// Max size of Cloudflare Images files 125export const CF_IMAGES_FILE_SIZE_LIMIT_IN_MB: number = 70; 126export const CF_IMAGES_FILE_SIZE_LIMIT: number = CF_IMAGES_FILE_SIZE_LIMIT_IN_MB * MB_TO_BYTES; 127export const CF_IMAGES_MAX_DIMENSION: number = 10000;