fix: Use Pterodactyl API directly instead of servers-api Worker

Worker was returning HTML error page. Now queries Pterodactyl panel
directly using PTERO_CLIENT_KEY from .env.

Chronicler #75
This commit is contained in:
Claude
2026-04-10 15:41:57 +00:00
parent 811e3046cf
commit 32b378f539

View File

@@ -14,8 +14,9 @@ const db = require('../database');
const DISCORD_API = 'https://discord.com/api/v10';
const DISCORD_TOKEN = process.env.DISCORD_BOT_TOKEN;
// Servers API (Cloudflare Worker that proxies Pterodactyl)
const SERVERS_API = 'https://servers-api.firefrostgaming.workers.dev';
// Pterodactyl API (direct, not via Worker)
const PTERO_URL = process.env.PTERO_PANEL_URL || 'https://panel.firefrostgaming.com';
const PTERO_KEY = process.env.PTERO_CLIENT_KEY;
// Map server names to their status channel IDs
// Key: lowercase server name (from Pterodactyl)
@@ -172,6 +173,72 @@ function findChannelForServer(serverName) {
return null;
}
/**
* Fetch servers from Pterodactyl API
*/
async function fetchServers() {
if (!PTERO_KEY) {
console.error('[StatusPoller] PTERO_CLIENT_KEY not set');
return [];
}
try {
// Get server list
const listResponse = await axios.get(`${PTERO_URL}/api/client`, {
headers: {
'Authorization': `Bearer ${PTERO_KEY}`,
'Accept': 'application/json'
}
});
const serverList = listResponse.data.data || [];
const servers = [];
// Get status for each server
for (const server of serverList) {
const id = server.attributes.identifier;
const name = server.attributes.name;
try {
const statsResponse = await axios.get(
`${PTERO_URL}/api/client/servers/${id}/resources`,
{
headers: {
'Authorization': `Bearer ${PTERO_KEY}`,
'Accept': 'application/json'
}
}
);
const isRunning = statsResponse.data.attributes?.current_state === 'running';
servers.push({
id: id,
name: name,
status: isRunning ? 'Online' : 'Offline',
players: isRunning ? (statsResponse.data.attributes?.resources?.players || 0) : 0
});
} catch (err) {
// Server might be inaccessible
servers.push({
id: id,
name: name,
status: 'Unknown',
players: 0
});
}
// Rate limiting
await new Promise(resolve => setTimeout(resolve, 200));
}
return servers;
} catch (err) {
console.error('[StatusPoller] Pterodactyl API error:', err.message);
return [];
}
}
/**
* Poll all servers and update Discord status messages
*/
@@ -179,9 +246,7 @@ async function pollAndUpdate() {
console.log('[StatusPoller] Polling server status...');
try {
// Fetch server status from Cloudflare Worker
const response = await axios.get(SERVERS_API);
const servers = response.data.servers || [];
const servers = await fetchServers();
console.log(`[StatusPoller] Got ${servers.length} servers`);
@@ -230,6 +295,7 @@ function start(intervalMinutes = 5) {
module.exports = {
init,
fetchServers,
pollAndUpdate,
start,
findChannelForServer,