From b51b12fb518509986cb54cdf0a58663dbc6f12c2 Mon Sep 17 00:00:00 2001 From: Dominik Koch Date: Sat, 7 Sep 2024 23:45:51 +0200 Subject: [PATCH] fix: add express server (#631) * fix: add express server * version bump --- docker-compose.yaml | 2 ++ package.json | 2 +- src/events/ready.ts | 3 ++ src/util/expressServer.ts | 58 +++++++++++++++++++++++++++++++++++++++ src/util/wouldYou.ts | 6 ++-- 5 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 src/util/expressServer.ts diff --git a/docker-compose.yaml b/docker-compose.yaml index 8c071fff..f252515e 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -6,6 +6,8 @@ services: context: . dockerfile: Dockerfile restart: unless-stopped + ports: + - "4959" stdin_open: true tty: true env_file: diff --git a/package.json b/package.json index 6345f011..a5e4170d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "would-you", - "version": "2.0.2", + "version": "2.0.3", "description": "Would You is a popular Discord bot that allows you to play the classic game of Would You Rather with your friends!", "main": "dist/cluster.js", "scripts": { diff --git a/src/events/ready.ts b/src/events/ready.ts index c4286586..fd8d11b0 100644 --- a/src/events/ready.ts +++ b/src/events/ready.ts @@ -15,6 +15,9 @@ const event: Event = { event: "ready", execute: async (client: WouldYou) => { if (client.cluster.id === 0) { + + client.server.startServer(); + let globalCommands = Array.from( client.commands.filter((x) => x.requireGuild === true).values(), ).map((x) => x.data.toJSON()) as RESTPostAPIApplicationCommandsJSONBody[]; diff --git a/src/util/expressServer.ts b/src/util/expressServer.ts new file mode 100644 index 00000000..61d1c20f --- /dev/null +++ b/src/util/expressServer.ts @@ -0,0 +1,58 @@ +import express, { Request, Response } from 'express'; +import type { WebSocketShard, Guild, Shard } from 'discord.js'; +import type WouldYou from '../util/wouldYou'; + +interface ShardStats { + id: number; + status: string; + ping: number; + guilds: number; + members: number; +} + +export default class ExpressServer { + private client: WouldYou; + private port: number; + private app: express.Application; + + constructor(client: WouldYou, port: number = 3000) { + this.client = client; + this.port = process.env.PORT ? parseInt(process.env.PORT) : port; + this.app = express(); + this.initializeRoutes(); + } + + private async getRequestStats(): Promise { + const results = await this.client?.cluster.broadcastEval((client) => { + const statsPerShard = client.ws.shards.map((shard: WebSocketShard) => { + return { + id: shard.id, + status: shard.status, + ping: Math.floor(shard.ping), + guilds: client.guilds.cache.filter((g: Guild) => g.shardId === shard.id).size, + members: client.guilds.cache + .filter((g: Guild) => g.shardId === shard.id) + .reduce((a: number, b: Guild) => a + b.memberCount, 0), + }; + }); + return statsPerShard; + }); + return results as unknown as ShardStats[]; + } + + private initializeRoutes(): void { + this.app.get('/api/status', async (req: Request, res: Response) => { + if(req.headers.authorization !== process.env.AUTH) return res.status(401).json({ error: 'Unauthorized' }); + try { + const stats = await this.getRequestStats(); + res.json(stats); + } catch (error) { + res.status(500).json({ error: 'Failed to fetch stats' }); + } + }); + } + + public startServer(): void { + this.app.listen(this.port); + } +} diff --git a/src/util/wouldYou.ts b/src/util/wouldYou.ts index acc70aac..2b86de2f 100644 --- a/src/util/wouldYou.ts +++ b/src/util/wouldYou.ts @@ -26,6 +26,7 @@ import PremiumHandler from "./premiumHandler"; import TranslationHandler from "./translationHandler"; import Voting from "./votingHandler"; import WebhookHandler from "./webhookHandler"; +import ExpressServer from "./expressServer"; export default class WouldYou extends Client { public commands: Collection; @@ -44,6 +45,7 @@ export default class WouldYou extends Client { public dailyMessage: DailyMessage; public voting: Voting; public config: IConfig; + public server: ExpressServer; translate: any; constructor() { @@ -101,8 +103,6 @@ export default class WouldYou extends Client { // Init the cluster client this.cluster = new ClusterClient(this); - this.config = Config; - this.cluster.on("ready", async () => { // The database handler this.database = new DatabaseHandler(process.env.MONGO_URI as string); @@ -115,6 +115,8 @@ export default class WouldYou extends Client { }); this.database.startSweeper(this); + this.server = new ExpressServer(this, parseInt(process.env.PORT!)); + // The translations handler this.translation = new TranslationHandler();