mirror of
https://github.com/thedrewen/protojx-manager.git
synced 2026-03-23 05:01:54 +01:00
feat(status): enhance server status command with structured response and improved host categorization
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
import { ApplicationIntegrationType, ChatInputCommandInteraction, CommandInteraction, EmbedBuilder, InteractionContextType, SlashCommandBuilder } from "discord.js";
|
import { ApplicationIntegrationType, ChatInputCommandInteraction, CommandInteraction, ContainerBuilder, EmbedBuilder, InteractionContextType, MessageFlags, SlashCommandBuilder } from "discord.js";
|
||||||
import ping from "ping";
|
import ping from "ping";
|
||||||
import statusService from "../../services/status.service";
|
import statusService from "../../services/status.service";
|
||||||
import { CommandDefinition } from "../../type";
|
import { CommandDefinition, InfraType } from "../../type";
|
||||||
|
import { secureHeapUsed } from "crypto";
|
||||||
|
|
||||||
const cmd : CommandDefinition = {
|
const cmd : CommandDefinition = {
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
@@ -18,18 +19,57 @@ const cmd : CommandDefinition = {
|
|||||||
),
|
),
|
||||||
async execute(interaction : ChatInputCommandInteraction) {
|
async execute(interaction : ChatInputCommandInteraction) {
|
||||||
await interaction.deferReply();
|
await interaction.deferReply();
|
||||||
|
|
||||||
const embed = new EmbedBuilder();
|
|
||||||
embed.setTitle('Status of protojx servers');
|
|
||||||
embed.setColor(0xffffff);
|
|
||||||
embed.setTimestamp(new Date());
|
|
||||||
embed.setThumbnail(interaction.client.user.avatarURL())
|
|
||||||
|
|
||||||
for(let host of statusService.hosts){
|
const hostTexts = statusService.hosts.map((s) => {
|
||||||
embed.addFields({name: host.name, value: host.alive ? `${process.env.EMOJI_STATUS_ONLINE} Online` : `${process.env.EMOJI_STATUS_OFFLINE} Offline`, inline: false});
|
return {type: s.type, value: `- ${s.name} : ${s.alive ? `${process.env.EMOJI_STATUS_ONLINE} Online` : `${process.env.EMOJI_STATUS_OFFLINE} Offline`}`};
|
||||||
}
|
});
|
||||||
|
|
||||||
|
const container = new ContainerBuilder()
|
||||||
|
.setAccentColor(0x0000ed)
|
||||||
|
.addTextDisplayComponents((text) => text.setContent('# Status of protojx servers'))
|
||||||
|
|
||||||
await interaction.editReply({embeds: [embed]});
|
const sections : {title: string, type: InfraType, thumbnail: string}[] = [
|
||||||
|
{
|
||||||
|
title: 'Websites',
|
||||||
|
type: 'website',
|
||||||
|
thumbnail: 'https://protojx.com/assets/img/home2/agent.png'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Ryzens',
|
||||||
|
type: 'ryzen',
|
||||||
|
thumbnail: 'https://iconape.com/wp-content/png_logo_vector/ryzen.png'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Xeons',
|
||||||
|
type: 'xeon',
|
||||||
|
thumbnail: 'https://upload.wikimedia.org/wikipedia/commons/3/31/Intel-Xeon-Badge-2024.jpg'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Games',
|
||||||
|
type: 'games',
|
||||||
|
thumbnail: 'https://protojx.com/assets/img/hero-img.png'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
sections.map((sectionData) => {
|
||||||
|
container.addSeparatorComponents((s) => s)
|
||||||
|
container.addSectionComponents(
|
||||||
|
(section) =>
|
||||||
|
section.addTextDisplayComponents(
|
||||||
|
(text) =>
|
||||||
|
text.setContent('## '+sectionData.title+'\n'+hostTexts.filter((v) => v.type == sectionData.type).map((v) => v.value).join('\n'))
|
||||||
|
)
|
||||||
|
.setThumbnailAccessory(
|
||||||
|
(acc) =>
|
||||||
|
acc.setURL(sectionData.thumbnail)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
const now = new Date();
|
||||||
|
container.addTextDisplayComponents((text) => text.setContent(`${now.getDate()}-${now.getMonth() + 1}-${now.getFullYear()} ${(now.getHours()+'').padStart(2, "0")}:${(now.getMinutes()+'').padStart(2, "0")}`))
|
||||||
|
|
||||||
|
await interaction.editReply({components: [container], flags: MessageFlags.IsComponentsV2});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,73 +5,78 @@ import { Host } from "../type";
|
|||||||
import { loadEnvFile } from "process";
|
import { loadEnvFile } from "process";
|
||||||
import { configDotenv } from "dotenv";
|
import { configDotenv } from "dotenv";
|
||||||
|
|
||||||
configDotenv();
|
|
||||||
|
|
||||||
export class StatusService {
|
export class StatusService {
|
||||||
|
|
||||||
private EMOJI_RYZEN : string = process.env.EMOJI_RYZEN as string;
|
|
||||||
private EMOJI_XEON : string = process.env.EMOJI_XEON as string;
|
|
||||||
|
|
||||||
public hosts: Host[] = [
|
public hosts: Host[] = [
|
||||||
{
|
{
|
||||||
'host': 'https://protojx.com',
|
'host': 'https://protojx.com',
|
||||||
'name': 'Protojx Website 🌐',
|
'name': 'Protojx Website',
|
||||||
alive: false,
|
alive: false,
|
||||||
|
ping_type: 'website',
|
||||||
type: 'website'
|
type: 'website'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'host': 'https://manager.protojx.com',
|
'host': 'https://manager.protojx.com',
|
||||||
'name': 'Espace Client 💻',
|
'name': 'Espace Client',
|
||||||
alive: false,
|
alive: false,
|
||||||
|
ping_type: 'website',
|
||||||
type: 'website'
|
type: 'website'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
host: '5.178.99.4',
|
host: '5.178.99.4',
|
||||||
name: 'RYZEN 01 ' + this.EMOJI_RYZEN,
|
name: 'RYZEN 01',
|
||||||
alive: false,
|
alive: false,
|
||||||
type: 'ping'
|
ping_type: 'ping',
|
||||||
|
type: 'ryzen'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
host: '5.178.99.6',
|
host: '5.178.99.6',
|
||||||
name: 'RYZEN 02 ' + this.EMOJI_RYZEN,
|
name: 'RYZEN 02',
|
||||||
alive: false,
|
alive: false,
|
||||||
type: 'ping'
|
ping_type: 'ping',
|
||||||
|
type: 'ryzen'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
host: '5.178.99.5',
|
host: '5.178.99.5',
|
||||||
name: 'RYZEN 03 ' + this.EMOJI_RYZEN,
|
name: 'RYZEN 03',
|
||||||
alive: false,
|
alive: false,
|
||||||
type: 'ping'
|
ping_type: 'ping',
|
||||||
|
type: 'ryzen'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
host: '154.16.254.10',
|
host: '154.16.254.10',
|
||||||
name: 'RYZEN7 04 ' + this.EMOJI_RYZEN,
|
name: 'RYZEN7 04',
|
||||||
alive: false,
|
alive: false,
|
||||||
type: 'ping'
|
ping_type: 'ping',
|
||||||
|
type: 'ryzen'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
host: '5.178.99.177',
|
host: '5.178.99.177',
|
||||||
name: 'XEON 01 (2697A V4) ' + this.EMOJI_XEON,
|
name: 'XEON 01 (2697A V4)',
|
||||||
alive: false,
|
alive: false,
|
||||||
type: 'ping'
|
ping_type: 'ping',
|
||||||
|
type: 'xeon'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
host: '5.178.99.248',
|
host: '5.178.99.248',
|
||||||
name: 'XEON 02 (2687W V4) ' + this.EMOJI_XEON,
|
name: 'XEON 02 (2687W V4)',
|
||||||
alive: false,
|
alive: false,
|
||||||
type: 'ping'
|
ping_type: 'ping',
|
||||||
|
type: 'xeon'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
host: '5.178.99.53',
|
host: '5.178.99.53',
|
||||||
name: 'RYZEN-GAME 01 👾',
|
name: 'RYZEN-GAME 01',
|
||||||
alive: false,
|
alive: false,
|
||||||
type: 'ping'
|
ping_type: 'ping',
|
||||||
|
type: 'games'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
host: '5.178.99.63',
|
host: '5.178.99.63',
|
||||||
name: 'XEON-GAME 01 👾',
|
name: 'XEON-GAME 01',
|
||||||
alive: false,
|
alive: false,
|
||||||
type: 'ping'
|
ping_type: 'ping',
|
||||||
|
type: 'games'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -120,10 +125,10 @@ export class StatusService {
|
|||||||
|
|
||||||
const hosts = this.hosts.filter((value, index) => index < max * max_ping && index >= (max - 1) * max_ping);
|
const hosts = this.hosts.filter((value, index) => index < max * max_ping && index >= (max - 1) * max_ping);
|
||||||
async function fetchAlive(host: Host) {
|
async function fetchAlive(host: Host) {
|
||||||
if (host.type === 'ping') {
|
if (host.ping_type === 'ping') {
|
||||||
let res = await ping.promise.probe(host.host, { timeout: 10 });
|
let res = await ping.promise.probe(host.host, { timeout: 10 });
|
||||||
host.alive = res.alive;
|
host.alive = res.alive;
|
||||||
} else if (host.type === 'website') {
|
} else if (host.ping_type === 'website') {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(host.host, { method: 'HEAD', signal: AbortSignal.timeout(10000) });
|
const response = await fetch(host.host, { method: 'HEAD', signal: AbortSignal.timeout(10000) });
|
||||||
host.alive = response.ok;
|
host.alive = response.ok;
|
||||||
|
|||||||
9
src/type.d.ts
vendored
9
src/type.d.ts
vendored
@@ -1,4 +1,11 @@
|
|||||||
import { ButtonInteraction, ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
|
import { ButtonInteraction, ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
|
||||||
|
|
||||||
export type Host = { host: string, name: string, alive: boolean, type: 'ping' | 'website' };
|
export type InfraType = 'website' | 'ryzen' | 'xeon' | 'games';
|
||||||
|
export type Host = {
|
||||||
|
host: string,
|
||||||
|
name: string,
|
||||||
|
alive: boolean,
|
||||||
|
ping_type: 'ping' | 'website',
|
||||||
|
type: InfraType
|
||||||
|
};
|
||||||
export type CommandDefinition = { data: SlashCommandBuilder, execute: (interaction: ChatInputCommandInteraction) => void, buttons?: { id: string, handle: (interaction: ButtonInteraction) => void}[]};
|
export type CommandDefinition = { data: SlashCommandBuilder, execute: (interaction: ChatInputCommandInteraction) => void, buttons?: { id: string, handle: (interaction: ButtonInteraction) => void}[]};
|
||||||
Reference in New Issue
Block a user