Skip to content

Instantly share code, notes, and snippets.

@marutichintan
Created July 17, 2025 18:35
Show Gist options
  • Select an option

  • Save marutichintan/14aa1ef5d7e07366326b96caa072464a to your computer and use it in GitHub Desktop.

Select an option

Save marutichintan/14aa1ef5d7e07366326b96caa072464a to your computer and use it in GitHub Desktop.
// 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