a moon tracking bot for Bluesky
1import * as dotenv from "dotenv";
2import { PostScheduler } from "./core/scheduler";
3import { DebugMode } from "./core/debugMode";
4import { postMoonPhaseToBluesky } from "./services/blueskyService";
5
6// Load environment variables
7dotenv.config({ path: "./src/config.env" });
8
9class MoonPhaseBot {
10 private readonly isDebugMode: boolean;
11 private readonly hasCredentials: boolean;
12
13 constructor() {
14 this.isDebugMode = process.env.DEBUG_MODE === "true";
15 this.hasCredentials = !!(process.env.BLUESKY_USERNAME && process.env.BLUESKY_PASSWORD);
16 }
17
18 public async run(): Promise<void> {
19 console.log("🌙 Moon Phase Bot Starting...");
20 console.log(`Debug Mode: ${this.isDebugMode ? 'ON' : 'OFF'}`);
21 console.log(`Credentials Available: ${this.hasCredentials ? 'YES' : 'NO'}`);
22
23 try {
24 if (this.isDebugMode) {
25 await this.runDebugMode();
26 } else {
27 await this.runProductionMode();
28 }
29 } catch (error) {
30 console.error("Fatal error:", error);
31 process.exit(1);
32 }
33 }
34
35 private async runDebugMode(): Promise<void> {
36 if (this.hasCredentials) {
37 console.log("Debug mode with credentials - posting immediately...");
38 await postMoonPhaseToBluesky();
39 } else {
40 console.log("Debug mode without credentials - generating sample messages...");
41 const debugMode = new DebugMode();
42 await debugMode.runDebugLoop();
43 }
44 }
45
46 private async runProductionMode(): Promise<void> {
47 if (!this.hasCredentials) {
48 throw new Error("Production mode requires BLUESKY_USERNAME and BLUESKY_PASSWORD environment variables");
49 }
50
51 const scheduler = new PostScheduler();
52
53 // Handle graceful shutdown
54 process.on('SIGINT', () => {
55 console.log("\nReceived SIGINT, shutting down gracefully...");
56 scheduler.stop();
57 process.exit(0);
58 });
59
60 process.on('SIGTERM', () => {
61 console.log("\nReceived SIGTERM, shutting down gracefully...");
62 scheduler.stop();
63 process.exit(0);
64 });
65
66 await scheduler.start();
67 }
68}
69
70// Entry point
71const bot = new MoonPhaseBot();
72bot.run().catch(error => {
73 console.error("Unhandled error:", error);
74 process.exit(1);
75});