mirror of
https://github.com/thedrewen/protojx-manager.git
synced 2026-03-23 05:01:54 +01:00
Status management by a service. Displays the ping of the bot and the API.
This commit is contained in:
29
package-lock.json
generated
29
package-lock.json
generated
@@ -10,6 +10,7 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/ping": "^0.4.4",
|
"@types/ping": "^0.4.4",
|
||||||
|
"cron": "^4.3.3",
|
||||||
"discord.js": "^14.24.1",
|
"discord.js": "^14.24.1",
|
||||||
"dotenv": "^17.2.2",
|
"dotenv": "^17.2.2",
|
||||||
"ping": "^1.0.0"
|
"ping": "^1.0.0"
|
||||||
@@ -178,6 +179,12 @@
|
|||||||
"npm": ">=7.0.0"
|
"npm": ">=7.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/luxon": {
|
||||||
|
"version": "3.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.7.1.tgz",
|
||||||
|
"integrity": "sha512-H3iskjFIAn5SlJU7OuxUmTEpebK6TKB8rxZShDslBMZJ5u9S//KM1sbdAisiSrqwLQncVjnpi2OK2J51h+4lsg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "24.9.1",
|
"version": "24.9.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.9.1.tgz",
|
||||||
@@ -212,6 +219,19 @@
|
|||||||
"npm": ">=7.0.0"
|
"npm": ">=7.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/cron": {
|
||||||
|
"version": "4.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/cron/-/cron-4.3.3.tgz",
|
||||||
|
"integrity": "sha512-B/CJj5yL3sjtlun6RtYHvoSB26EmQ2NUmhq9ZiJSyKIM4K/fqfh9aelDFlIayD2YMeFZqWLi9hHV+c+pq2Djkw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/luxon": "~3.7.0",
|
||||||
|
"luxon": "~3.7.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/discord-api-types": {
|
"node_modules/discord-api-types": {
|
||||||
"version": "0.38.31",
|
"version": "0.38.31",
|
||||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.38.31.tgz",
|
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.38.31.tgz",
|
||||||
@@ -278,6 +298,15 @@
|
|||||||
"integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==",
|
"integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/luxon": {
|
||||||
|
"version": "3.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz",
|
||||||
|
"integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/magic-bytes.js": {
|
"node_modules/magic-bytes.js": {
|
||||||
"version": "1.12.1",
|
"version": "1.12.1",
|
||||||
"resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.12.1.tgz",
|
"resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.12.1.tgz",
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/ping": "^0.4.4",
|
"@types/ping": "^0.4.4",
|
||||||
|
"cron": "^4.3.3",
|
||||||
"discord.js": "^14.24.1",
|
"discord.js": "^14.24.1",
|
||||||
"dotenv": "^17.2.2",
|
"dotenv": "^17.2.2",
|
||||||
"ping": "^1.0.0"
|
"ping": "^1.0.0"
|
||||||
|
|||||||
@@ -14,6 +14,6 @@ export default {
|
|||||||
InteractionContextType.PrivateChannel
|
InteractionContextType.PrivateChannel
|
||||||
),
|
),
|
||||||
async execute(interaction : ChatInputCommandInteraction) {
|
async execute(interaction : ChatInputCommandInteraction) {
|
||||||
await interaction.reply('Pong !');
|
await interaction.reply(`🏓 Latency is ${Date.now() - interaction.createdTimestamp}ms. API Latency : ${interaction.client.ws.ping}ms`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import { ApplicationIntegrationType, ChatInputCommandInteraction, CommandInteraction, EmbedBuilder, InteractionContextType, SlashCommandBuilder } from "discord.js";
|
import { ApplicationIntegrationType, ChatInputCommandInteraction, CommandInteraction, EmbedBuilder, InteractionContextType, SlashCommandBuilder } from "discord.js";
|
||||||
import ping from "ping";
|
import ping from "ping";
|
||||||
|
import statusService from "../../services/status.service";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
@@ -17,88 +18,13 @@ export default {
|
|||||||
async execute(interaction : ChatInputCommandInteraction) {
|
async execute(interaction : ChatInputCommandInteraction) {
|
||||||
await interaction.deferReply();
|
await interaction.deferReply();
|
||||||
|
|
||||||
const hosts : {host: string, name: string, alive: boolean, type: 'ping' | 'website'}[] = [
|
|
||||||
{
|
|
||||||
'host': 'https://protojx.com',
|
|
||||||
'name': 'Protojx Website 🌐',
|
|
||||||
alive: false,
|
|
||||||
type: 'website'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'host': 'https://manager.protojx.com',
|
|
||||||
'name': 'Espace Client 💻',
|
|
||||||
alive: false,
|
|
||||||
type: 'website'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
host: '5.178.99.4',
|
|
||||||
name: 'RYZEN 01 🖥️',
|
|
||||||
alive: false,
|
|
||||||
type: 'ping'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
host: '5.167.99.6',
|
|
||||||
name: 'RYZEN 02 🖥️',
|
|
||||||
alive: false,
|
|
||||||
type: 'ping'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
host: '5.178.99.5',
|
|
||||||
name: 'RYZEN 03 🖥️',
|
|
||||||
alive: false,
|
|
||||||
type: 'ping'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
host: '5.178.99.177',
|
|
||||||
name: 'XEON 01 (2697A V4) 🖥️',
|
|
||||||
alive: false,
|
|
||||||
type: 'ping'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
host: '5.178.99.248',
|
|
||||||
name: 'XEON 02 (2687W V4) 🖥️',
|
|
||||||
alive: false,
|
|
||||||
type: 'ping'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
host: '5.178.99.53',
|
|
||||||
name: 'RYZEN-GAME 01 👾',
|
|
||||||
alive: false,
|
|
||||||
type: 'ping'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
host: '5.178.99.63',
|
|
||||||
name: 'XEON-GAME 01 👾',
|
|
||||||
alive: false,
|
|
||||||
type: 'ping'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
async function fetchAlive(host: {host: string, name: string, alive: boolean, type: 'ping' | 'website'}) {
|
|
||||||
if(host.type === 'ping'){
|
|
||||||
let res = await ping.promise.probe(host.host, {timeout: 5});
|
|
||||||
host.alive = res.alive;
|
|
||||||
}else if(host.type === 'website'){
|
|
||||||
try {
|
|
||||||
const response = await fetch(host.host, { method: 'HEAD', signal: AbortSignal.timeout(3000) });
|
|
||||||
host.alive = response.ok;
|
|
||||||
} catch (error) {
|
|
||||||
host.alive = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return host;
|
|
||||||
}
|
|
||||||
|
|
||||||
const fetchPromises = hosts.map(host => fetchAlive(host));
|
|
||||||
const hosts_ = await Promise.all(fetchPromises);
|
|
||||||
|
|
||||||
const embed = new EmbedBuilder();
|
const embed = new EmbedBuilder();
|
||||||
embed.setTitle('Status of protojx servers');
|
embed.setTitle('Status of protojx servers');
|
||||||
embed.setColor(0xffffff);
|
embed.setColor(0xffffff);
|
||||||
embed.setTimestamp(new Date());
|
embed.setTimestamp(new Date());
|
||||||
embed.setThumbnail(interaction.client.user.avatarURL())
|
embed.setThumbnail(interaction.client.user.avatarURL())
|
||||||
|
|
||||||
for(let host of hosts_){
|
for(let host of statusService.hosts){
|
||||||
embed.addFields({name: host.name, value: host.alive ? '<a:online:1432684754276323431> Online' : '<a:offline:1432684900175183882> Offline', inline: false});
|
embed.addFields({name: host.name, value: host.alive ? '<a:online:1432684754276323431> Online' : '<a:offline:1432684900175183882> Offline', inline: false});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
112
src/services/status.service.ts
Normal file
112
src/services/status.service.ts
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
import ping from "ping";
|
||||||
|
import * as cron from 'cron';
|
||||||
|
|
||||||
|
export class StatusService {
|
||||||
|
|
||||||
|
public hosts : Host[] = [
|
||||||
|
{
|
||||||
|
'host': 'https://protojx.com',
|
||||||
|
'name': 'Protojx Website 🌐',
|
||||||
|
alive: false,
|
||||||
|
type: 'website'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'host': 'https://manager.protojx.com',
|
||||||
|
'name': 'Espace Client 💻',
|
||||||
|
alive: false,
|
||||||
|
type: 'website'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
host: '5.178.99.4',
|
||||||
|
name: 'RYZEN 01 🖥️',
|
||||||
|
alive: false,
|
||||||
|
type: 'ping'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
host: '5.167.99.6',
|
||||||
|
name: 'RYZEN 02 🖥️',
|
||||||
|
alive: false,
|
||||||
|
type: 'ping'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
host: '5.178.99.5',
|
||||||
|
name: 'RYZEN 03 🖥️',
|
||||||
|
alive: false,
|
||||||
|
type: 'ping'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
host: '5.178.99.177',
|
||||||
|
name: 'XEON 01 (2697A V4) 🖥️',
|
||||||
|
alive: false,
|
||||||
|
type: 'ping'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
host: '5.178.99.248',
|
||||||
|
name: 'XEON 02 (2687W V4) 🖥️',
|
||||||
|
alive: false,
|
||||||
|
type: 'ping'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
host: '5.178.99.53',
|
||||||
|
name: 'RYZEN-GAME 01 👾',
|
||||||
|
alive: false,
|
||||||
|
type: 'ping'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
host: '5.178.99.63',
|
||||||
|
name: 'XEON-GAME 01 👾',
|
||||||
|
alive: false,
|
||||||
|
type: 'ping'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
const cronJob = new cron.CronJob('*/2 * * * *', async () => {
|
||||||
|
try {
|
||||||
|
await this.fetch();
|
||||||
|
console.log('Status check completed at:', new Date().toISOString());
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error during status check:', error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cronJob.start();
|
||||||
|
console.log('Status monitoring started - checking every 2 minutes');
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetch(max = 1): Promise<Host[]> {
|
||||||
|
|
||||||
|
const hosts = this.hosts.filter((value, index) => index < max * 10 && index >= (max - 1) * 10);
|
||||||
|
async function fetchAlive(host: Host) {
|
||||||
|
if(host.type === 'ping'){
|
||||||
|
let res = await ping.promise.probe(host.host, {timeout: 5});
|
||||||
|
host.alive = res.alive;
|
||||||
|
}else if(host.type === 'website'){
|
||||||
|
try {
|
||||||
|
const response = await fetch(host.host, { method: 'HEAD', signal: AbortSignal.timeout(3000) });
|
||||||
|
host.alive = response.ok;
|
||||||
|
} catch (error) {
|
||||||
|
host.alive = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchPromises = hosts.map(host => fetchAlive(host));
|
||||||
|
const updatedHosts = await Promise.all(fetchPromises);
|
||||||
|
|
||||||
|
updatedHosts.forEach((updatedHost, index) => {
|
||||||
|
const originalIndex = (max - 1) * 10 + index;
|
||||||
|
if (originalIndex < this.hosts.length) {
|
||||||
|
this.hosts[originalIndex] = updatedHost;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(this.hosts.length > max * 10) {
|
||||||
|
await this.fetch(max + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.hosts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new StatusService();
|
||||||
1
src/type.d.ts
vendored
Normal file
1
src/type.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
type Host = { host: string, name: string, alive: boolean, type: 'ping' | 'website' };
|
||||||
Reference in New Issue
Block a user