Deployment
The shape of a bot that runs for months: configuration from the environment, a health check and a clean shutdown.
Before you start
Create an application, install it in a test server and set three environment variables (see Getting started):
export ZRZUR_BOT_TOKEN=YOUR_BOT_TOKEN
export ZRZUR_API_URL=https://api.zrzur.com
export ZRZUR_WS_URL=wss://events.zrzur.comThe code
// Production shape: configuration from the environment, a health endpoint
// for the process manager, and a clean shutdown on SIGTERM.
import { createServer } from "node:http";
import { Client } from "@zrzur/sdk/bot";
for (const name of ["ZRZUR_BOT_TOKEN", "ZRZUR_API_URL", "ZRZUR_WS_URL"]) {
if (!process.env[name]) {
console.error(`${name} is not set`);
process.exit(2);
}
}
const bot = new Client({
token: process.env.ZRZUR_BOT_TOKEN,
apiUrl: process.env.ZRZUR_API_URL,
wsUrl: process.env.ZRZUR_WS_URL,
});
let ready = false;
bot.on("Ready", () => (ready = true));
bot.on("Disconnected", () => (ready = false));
bot.command("hello", (i) => i.reply("Hello!"));
// /healthz answers 200 once connected; bind to loopback only
const health = createServer((request, response) => {
if (request.url === "/healthz")
return response.writeHead(ready ? 200 : 503).end(ready ? "ok" : "starting");
response.writeHead(404).end();
});
health.listen(Number(process.env.HEALTH_PORT ?? 8080), "127.0.0.1");
async function shutdown() {
health.close();
bot.destroy();
process.exit(0);
}
process.on("SIGTERM", shutdown);
process.on("SIGINT", shutdown);
await bot.login();
await bot.syncCommands([{ name: "hello", description: "Say hello" }]);
console.log("ready");
Run it with node deploy.mjs.
Try it
Run it under a process manager (systemd, Docker, a PaaS) and point its health check at http://127.0.0.1:8080/healthz.
What it shows
- The bot refuses to start when a variable is missing (exit code 2).
/healthzanswers 200 once the gateway is connected, 503 before.- On SIGTERM it closes the health server and the gateway, then exits.
- Keep the token in the platform's secret store; restart the bot after resetting the token.