-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathGoat.js
More file actions
173 lines (148 loc) · 5.95 KB
/
Copy pathGoat.js
File metadata and controls
173 lines (148 loc) · 5.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/**
* @author NTKhang & Modded for Telegram by frnAlt & Gtajisan
* ! GoatBot V2 Main Logic & Bot Orchestration
*/
const log = require("./logger/log.js");
// Handle runtime process exceptions cleanly
process.on("unhandledRejection", (error) => {
log.error("UNHANDLED_REJECTION", error?.message || error);
});
process.on("uncaughtException", (error) => {
log.error("UNCAUGHT_EXCEPTION", error?.message || error);
log.error("UNCAUGHT_EXCEPTION", error?.stack || "No stack trace");
setTimeout(() => process.exit(1), 1000);
});
const path = require("path");
const fs = require("fs-extra");
const TTLMap = require("./func/TTLMap.js");
const utils = require("./utils.js");
global.utils = utils;
// Universal module resolver for aliases and TypeScript/ESM transpilation
require("./func/moduleResolver.js");
const dirConfig = path.normalize(`${__dirname}/config.json`);
const dirConfigCommands = path.normalize(`${__dirname}/configCommands.json`);
if (!fs.existsSync(dirConfig)) {
log.error("CONFIG", "config.json not found!");
process.exit(1);
}
const config = require(dirConfig);
const configCommands = fs.existsSync(dirConfigCommands) ? require(dirConfigCommands) : { envGlobal: {}, envCommands: {}, envEvents: {} };
// Setup global GoatBot object
global.GoatBot = {
startTime: Date.now(),
commands: new Map(),
eventCommands: new Map(),
aliases: new Map(),
onChat: [],
onEvent: [],
onAnyEvent: [],
onFirstChat: [],
onReply: new TTLMap({ ttl: 30 * 60 * 1000, maxSize: 500, cleanupInterval: 60000 }),
onReaction: new TTLMap({ ttl: 30 * 60 * 1000, maxSize: 500, cleanupInterval: 60000 }),
commandFilesPath: [],
eventCommandsFilesPath: [],
config,
configCommands,
envCommands: configCommands.envCommands || {},
envEvents: configCommands.envEvents || {},
envGlobal: configCommands.envGlobal || {},
botID: null,
botInfo: null
};
// Aliases for multi-engine compatibility
global.FloppaBot = global.GoatBot;
global.Cassidy = global.GoatBot;
global.db = {
allThreadData: [],
allUserData: [],
allDashBoardData: [],
allGlobalData: [],
threadsData: {
get: async (id) => ({ threadID: id }),
getAll: async () => []
},
usersData: {
get: async (id) => ({ userID: id }),
getAll: async () => []
},
dashBoardData: {
get: async () => ({}),
getAll: async () => []
}
};
global.client = {
dirConfig,
dirConfigCommands,
countDown: {},
cache: {},
database: {
creatingThreadData: [],
creatingUserData: [],
creatingDashBoardData: [],
creatingGlobalData: []
}
};
// Memory Manager for 512MB RAM constraints (Render/Railway)
class MemoryManager {
constructor(options = {}) {
this.options = {
checkInterval: 3 * 60 * 1000,
heapThreshold: 350 * 1024 * 1024,
...options
};
this._startMonitoring();
}
_startMonitoring() {
setInterval(() => this._checkMemory(), this.options.checkInterval);
}
_checkMemory() {
const memUsage = process.memoryUsage();
if (memUsage.heapUsed > this.options.heapThreshold) {
log.warn("MEMORY", `Memory high: ${(memUsage.heapUsed / 1024 / 1024).toFixed(2)} MB heap used. Cleaning up...`);
if (global.gc) {
global.gc();
}
}
}
}
const memoryManager = new MemoryManager();
// Main Execution Async Function
(async () => {
try {
log.info("SYSTEM", "Starting GrammChatBot Telegram Engine...");
// 1. Initialize Auto Cleanup Cron Job (every 30 minutes)
const { initAutoCleanup } = require("./bot/cron/autoCleanup.js");
initAutoCleanup(config);
// Initialize Database Controllers
const initDB = require("./database/controller/index.js");
await initDB(null);
// 2. Load Commands and Events
const loadScripts = require("./bot/login/loadScripts.js");
await loadScripts(global.db);
// 3. Initialize Telegram Token Manager & Start Polling
const tokenManager = require("./bot/telegram/tokenManager.js");
tokenManager.init(config.telegramTokens);
const { handleTelegramEvent } = require("./bot.js");
const bot = await tokenManager.createBotInstance((botInstance) => {
botInstance.on("message", (ctx) => handleTelegramEvent(ctx));
botInstance.on("edited_message", (ctx) => handleTelegramEvent(ctx));
botInstance.on("callback_query", (ctx) => handleTelegramEvent(ctx));
});
if (bot) {
tokenManager.startPolling(bot);
} else {
log.warn("SYSTEM", "Bot instance could not be started. Check telegramTokens in config.json.");
}
// 4. Start Express Web Dashboard
if (config.dashBoard?.enable !== false) {
try {
const startDashboard = require("./dashboard/app.js");
await startDashboard(tokenManager);
} catch (e) {
log.error("DASHBOARD", `Failed to start Web Dashboard: ${e.message}`);
}
}
} catch (err) {
log.error("FATAL_START", `Error starting GoatBot: ${err.stack || err.message}`);
}
})();