Created
July 17, 2025 18:35
-
-
Save marutichintan/14aa1ef5d7e07366326b96caa072464a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Below code is for internal process manager and it not expose to internet or directly accessable. | |
| // Before using for production please validation all inputs to prevent exec injection. | |
| import dotenv from "dotenv"; | |
| dotenv.config(); | |
| import pm2 from "pm2"; | |
| import fs from "fs"; | |
| import Fastify from "fastify"; | |
| import { execSync } from "child_process"; | |
| const fastify = Fastify({ | |
| logger: true, | |
| }); | |
| const src_path = process.env.SRC_PATH; | |
| fastify.get("/start_instance/:instance", async (request, reply) => { | |
| reply.type("application/json").code(200); | |
| try { | |
| let instance = request.params.instance; | |
| let proxy = request.query.proxy || "NOPROXY"; | |
| let webhook = request.query.webhook || "0"; | |
| let auto_read_msg = request.query.auto_read_msg || "false"; | |
| console.log("[*] Process Starting", instance, proxy, webhook, auto_read_msg); | |
| if (isNaN(Number(instance))) { | |
| console.log("instance must be number"); | |
| return { status: false }; | |
| } | |
| // create dir in /instance with instance | |
| if(!fs.existsSync(`instance/session_${instance}`)){ | |
| fs.mkdirSync(`instance/session_${instance}`); | |
| fs.copyFileSync(`linux-amd64`, `instance/session_${instance}/linux-amd64`); | |
| execSync(`chmod +x instance/session_${instance}/linux-amd64`); | |
| } | |
| if (auto_read_msg == "1" || auto_read_msg == "true") { | |
| auto_read_msg = "true"; | |
| } | |
| // pm2 check if instance is already running | |
| const processList = await new Promise((resolve, reject) => { | |
| pm2.list((err, list) => { | |
| if (err) { | |
| console.error("[e] Error getting process list", err); | |
| reject(err); | |
| } else { | |
| resolve(list); | |
| } | |
| }); | |
| }); | |
| if (!Array.isArray(processList)) { | |
| console.error("[e] Invalid process list"); | |
| return { status: false, error: "Invalid process list" }; | |
| } | |
| const isRunning = processList.some((process) => process.name === instance); | |
| if (isRunning) { | |
| console.log(`[i] Process ${instance} is already running`, process); | |
| return { status: false, error: "Process is already running" }; | |
| } | |
| // instance path | |
| let instance_path = `${src_path}/instance/session_${instance}/`; | |
| console.log({ cwd: instance_path, env: { HTTP_PROXY: proxy, HTTPS_PROXY: proxy, HOME: "/root"}}); | |
| execSync(`pm2 start --name ${instance} ./linux-amd64 --interpreter none -x -- rest --port ${instance} --webhook ${webhook} --os "Mac OS" --debug --auto-mark-read=${auto_read_msg}`, { cwd: instance_path, env: { HTTP_PROXY: proxy, HTTPS_PROXY: proxy, HOME: "/root"}}); | |
| return { status: true }; | |
| } catch (error) { | |
| console.log("/start_instance", error); | |
| return { status: false, error: error.message }; | |
| } | |
| }); | |
| fastify.get("/stop_instance/:instance", async (request, reply) => { | |
| reply.type("application/json").code(200); | |
| try { | |
| let instance = request.params.instance; | |
| pm2.stop(instance, (err, process) => { | |
| console.log(err); | |
| }); | |
| return { status: true }; | |
| } catch (error) { | |
| console.log("/start_instance", error); | |
| return { status: false, error: error.message }; | |
| } | |
| }); | |
| fastify.get("/delete_instance/:instance", async (request, reply) => { | |
| reply.type("application/json").code(200); | |
| try { | |
| let instance = request.params.instance; | |
| pm2.delete(instance, (err, process) => { | |
| try { | |
| fs.rmSync(`instance/session_${instance}/`, { recursive: true, force: true }); | |
| } catch (error) { | |
| console.log("[e] no session file found.", instance); | |
| } | |
| }); | |
| return { status: true }; | |
| } catch (error) { | |
| console.log("/start_instance", error); | |
| return { status: false, error: error.message }; | |
| } | |
| }); | |
| fastify.get("/high_memory_processes", async (request, reply) => { | |
| reply.type("application/json").code(200); | |
| try { | |
| pm2.list((err, processList) => { | |
| if (err) { | |
| console.error("[e] Error getting process list", err); | |
| return { status: false, error: err.message }; | |
| } | |
| const highMemoryProcesses = processList.filter((process) => { | |
| const memoryUsage = process.monit.memory; | |
| return memoryUsage > 500 * 1024 * 1024; // Convert 500 MB to bytes | |
| }); | |
| const processInfo = highMemoryProcesses.map((process) => ({ | |
| name: process.name, | |
| pid: process.pid, | |
| memoryUsage: process.monit.memory, | |
| })); | |
| return { status: true, processes: processInfo }; | |
| }); | |
| } catch (error) { | |
| console.log("/high_memory_processes", error); | |
| return { status: false, error: error.message }; | |
| } | |
| }); | |
| fastify.get("/", async (request, reply) => { | |
| reply.type("application/json").code(200); | |
| return { hello: "world" }; | |
| }); | |
| fastify.listen(process.env.PORT, "0.0.0.0", (err, address) => { | |
| if (err) throw err; | |
| fastify.log.info(`server listening on ${address}`); | |
| }); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment