SkyScheduler#
Overview#
SkyScheduler is a lightweight Cloudflare Workers-based microservice application that allows you and/or your team to schedule/repost posts to a Bluesky account effortlessly. Perfect for content creators and social media managers who want to plan their social media content in advance.
Features#
- Multiple user/account handling: Manage multiple users/bsky accounts easily
- Bluesky Post Scheduling: Schedule multiple posts to your Bluesky account
- Hourly Time Slots: Time selection is limited to hourly intervals to optimize worker execution and reduce unnecessary runs
- Post Threading: Schedule entire post threads with full media support per post!
- Simple Setup: Fairly minimal setup and easy to use
- Supports media posts: Automatically handles content tagging and formatting your media so that it looks the best on BSky. Image transforms via Cloudflare Images
- Handles Link Embeds: Post your content with a link embed easily!
- Automatic reposting: Schedule how many times you want your post to be reposted on the network. Get more visibility and engagement without having to do more work
- Repost anything: Need to retweet something made out of SkyScheduler? Yeah, you can.
- Invite Keys: Want to throttle the signups to your portal or keep the pool to friends/org only? Use invite keys to manage signups
Getting Started#
Prerequisites#
- Node.js (v24.11 or later)
- Package Manager
- Cloudflare Pro Workers account (you will hit CPU limits otherwise)
Installation#
- Clone the repository
git clone https://github.com/socksthewolf/skyscheduler.git
cd skyscheduler
- Copy environment variables template
cp .dev.vars.example .dev.vars
- Configure your
.dev.varsfile with the following environment variables:BETTER_AUTH_SECRET- the cryptographic hash to use better auth (you can generate one from this page)BETTER_AUTH_URL- the working url of your site (this should be "*" in dev).DEFAULT_ADMIN_USER- the admin bsky handleDEFAULT_ADMIN_PASS- the admin passwordDEFAULT_ADMIN_BSKY_PASS- the above account's bsky app passwordTURNSTILE_PUBLIC_KEY- the turnstile public key for captchaTURNSTILE_SECRET_KEY- the turnstile secret key for captchaRESIZE_SECRET_HEADER- a header value that will be included on requests while trying to resize images. Protects the resize bucket while still making it accessible to CF Images.
Note: When deploying, these variables should also be configured as secrets in your Cloudflare worker dashboard. You can also do this via npx wrangler secret put <NAME_OF_SECRET>.
Alternatively, make a file like .env.prod and use npx wrangler secret bulk FILENAME to upload all the settings at once.
-
Update your
wrangler.tomlwith changes that reflect your account.- You'll need to update the values for the kv, r2, queues, d1 to reflect the bindings on your account.
- Also make sure you update the
BETTER_AUTH_URLto your working url as well. - Do remember to update/remove the domain bindings!
-
Install dependencies
npm install
- Run the development server
npm run dev
- Deploy the application to Cloudflare Workers. You might need to login to your Cloudflare account if you haven't already.
npm run deploy
- Create your D1 tables using the following command, this will set up your tables both locally and remotely.
NOTE: If you encounter issues running remotely, you can run the command again.
npm run migrate:all
-
Modify any site information located in:
limits.ts- site configuration and application limitssiteinfo.ts- site information such as name, description, domain, etc.ssclirc- sitemap domainsite.webmanifest- naming and color schemes
-
Run your application and go to
/setup. This will create the admin account.
Configuration#
Environment Variables#
Ensure you have configured the .dev.vars file with the necessary credentials and settings. The file is git-ignored to protect your sensitive information.
Application Variables#
Most of the application can be modified with wrangler.toml's vars section or via src/limits.ts. Both files are heavily commented to explain what the options control.
Site Variables#
Modifying key values such as meta tag data, the application name and any descriptions is fully controlled via src/siteinfo.ts. Changing these fields will modify the rest of the application's web output.
Minimization#
The application by default is configured to use the minified versions of the scripts in assets/js and assets/css. By default, all minimized files will rebuild whenever any typescript file is changed or the application is deployed/ran.
Project Structure#
skyscheduler/
├── assets/
│ ├── css/
│ ├── dep/
│ ├── icons/
│ ├── js/
│ └── thumbs/
├── src/
│ ├── auth/
│ ├── classes/
│ ├── db/
│ ├── endpoints/
│ ├── layout/
│ ├── middleware/
│ ├── pages/
│ ├── utils/
│ └── validation/
├── migrations/
├── .dev.vars
├── .node-version
├── .markdownlint.json
├── .minify.json
├── .ssclirc
├── drizzle.config.ts
├── package.json
├── tsconfig.json
└── wrangler.toml
Middleware Stack#
Server#
- BetterAuth - site login/authentication
- BetterAuthCloudflare - helper for BetterAuth on CF
- hono - request routing/processing
- uuid - id generation
- zod - data validation
- image-dimensions - image data validation
- date-fns - date processing helpers
- drizzle - database orm/schemas
- just - js helper library
- human-id - passphrase generation for invite keys
Client#
- htmx - client requests and responsiveness
- tribute - client autocomplete library
- toastify - client notifications
- dropzone - file upload negotiation
- pico - styling, tabs, modals
- countable - dynamic input counter
Contributions#
We welcome contributions! Here's some ways to contribute:
- Report bugs
- Suggest enhancements
- Sponsor
License#
This project's source code is licensed under the MIT License Name, Logos and Branding are copyright SocksTheWolf, all rights reserved.
See the LICENSE file for details.