This commit is contained in:
2025-10-10 12:56:25 +02:00
parent aacae79769
commit bb946e9e6a
2 changed files with 103 additions and 41 deletions

View File

@@ -8,21 +8,101 @@ import { AccessToken, CharacterUpdate, Env, PlanetWithInfo } from "../types";
import { MainGrid } from "./components/MainGrid"; import { MainGrid } from "./components/MainGrid";
import { refreshToken } from "@/esi-sso"; import { refreshToken } from "@/esi-sso";
import { import {
CharacterContext, CharacterContext,
ColorContext, ColorContext,
ColorSelectionType, ColorSelectionType,
SessionContext, SessionContext,
defaultColors, defaultColors,
} from "./context/Context"; } from "./context/Context";
import { useSearchParams } from "next/navigation"; import { useSearchParams } from "next/navigation";
import { EvePraisalResult, fetchAllPrices } from "@/eve-praisal"; import { EvePraisalResult, fetchAllPrices } from "@/eve-praisal";
import { getPlanet, getPlanetUniverse, getPlanets } from "@/planets"; import { getPlanet, getPlanetUniverse, getPlanets } from "@/planets";
import { PlanetConfig } from "@/types"; import { PlanetConfig } from "@/types";
import { runWebhookChecks } from "@/utils/webhookService"; // Webhook service removed - using direct API calls
import { WebhookConfig } from "@/types/webhook"; import { WebhookConfig } from "@/types/webhook";
import { cleanupOldWebhookStates } from "@/utils/webhookTracker"; import { cleanupOldWebhookStates } from "@/utils/webhookTracker";
import { planetCalculations } from "@/planets"; import { planetCalculations } from "@/planets";
// Webhook check functions
const checkExtractorExpiry = async (character: any, planet: any, extractors: any[], config: WebhookConfig) => {
if (!config.enabled || !config.zulipUrl) return;
const now = new Date();
const expiryThreshold = new Date(now.getTime() + 12 * 60 * 60 * 1000); // 12 hours from now
for (const extractor of extractors) {
if (extractor.expiry_time) {
const expiryTime = new Date(extractor.expiry_time);
if (expiryTime <= expiryThreshold) {
const hoursRemaining = Math.round((expiryTime.getTime() - now.getTime()) / (1000 * 60 * 60));
const message = `⚠️ Extractor ${extractor.type_name} expires in ${hoursRemaining} hours`;
await fetch('/api/zulip-webhook', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
type: 'extractor_expiring',
message,
characterName: character.character.name,
planetName: planet.infoUniverse.name,
timestamp: now.toISOString(),
zulipUrl: config.zulipUrl,
zulipEmail: config.zulipEmail,
zulipApiKey: config.zulipApiKey,
zulipStream: config.zulipStream
})
});
}
}
}
};
const checkStorageCapacity = async (character: any, planet: any, storage: any[], config: WebhookConfig) => {
if (!config.enabled || !config.zulipUrl) return;
for (const storageItem of storage) {
const fillPercentage = (storageItem.used / storageItem.capacity) * 100;
if (fillPercentage >= config.storageCriticalThreshold) {
const message = `🚨 Storage ${storageItem.type_name} is ${fillPercentage.toFixed(1)}% full!`;
await fetch('/api/zulip-webhook', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
type: 'storage_full',
message,
characterName: character.character.name,
planetName: planet.infoUniverse.name,
timestamp: new Date().toISOString(),
zulipUrl: config.zulipUrl,
zulipEmail: config.zulipEmail,
zulipApiKey: config.zulipApiKey,
zulipStream: config.zulipStream
})
});
} else if (fillPercentage >= config.storageWarningThreshold) {
const message = `⚠️ Storage ${storageItem.type_name} is ${fillPercentage.toFixed(1)}% full`;
await fetch('/api/zulip-webhook', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
type: 'storage_almost_full',
message,
characterName: character.character.name,
planetName: planet.infoUniverse.name,
timestamp: new Date().toISOString(),
zulipUrl: config.zulipUrl,
zulipEmail: config.zulipEmail,
zulipApiKey: config.zulipApiKey,
zulipStream: config.zulipStream
})
});
}
}
};
// Add batch processing utility // Add batch processing utility
const processInBatches = async <T, R>( const processInBatches = async <T, R>(
items: T[], items: T[],
@@ -152,29 +232,23 @@ const Home = () => {
info: await getPlanet(c, p), info: await getPlanet(c, p),
infoUniverse: await getPlanetUniverse(p), infoUniverse: await getPlanetUniverse(p),
}) })
); );
// Run webhook checks for each planet if webhooks are enabled // Run webhook checks for each planet if webhooks are enabled
if (webhookConfig.enabled) { if (webhookConfig.enabled) {
console.log(`🔍 Running webhook checks for ${c.character.name} (${planetsWithInfo.length} planets)`); console.log(`🔍 Running webhook checks for ${c.character.name} (${planetsWithInfo.length} planets)`);
for (const planet of planetsWithInfo) { for (const planet of planetsWithInfo) {
try { try {
const calculations = planetCalculations(planet); const calculations = planetCalculations(planet);
await runWebhookChecks( await checkExtractorExpiry(c, planet, calculations.extractors, webhookConfig);
c, await checkStorageCapacity(c, planet, planet.info.pins, webhookConfig);
planet, } catch (error) {
calculations.extractors, console.warn('Webhook check failed for planet:', planet.infoUniverse.name, error);
webhookConfig }
);
} catch (error) {
console.warn('Webhook check failed for planet:', planet.infoUniverse.name, error);
} }
} }
} else {
console.log('🔕 Webhooks disabled, skipping checks'); return {
}
return {
...c, ...c,
planets: planetsWithInfo, planets: planetsWithInfo,
}; };
@@ -405,19 +479,7 @@ const Home = () => {
for (const character of currentCharacters) { for (const character of currentCharacters) {
if (character.needsLogin || !character.planets) continue; if (character.needsLogin || !character.planets) continue;
for (const planet of character.planets) { // Webhook checks removed
try {
const calculations = planetCalculations(planet);
await runWebhookChecks(
character,
planet,
calculations.extractors,
webhookConfig
);
} catch (error) {
console.warn('Regular webhook check failed for planet:', planet.infoUniverse.name, error);
}
}
} }
// Cleanup old webhook states // Cleanup old webhook states

View File

@@ -81,7 +81,7 @@ export default async function handler(
} }
// Create topic in format: CharacterName-PlanetName-ActionType // Create topic in format: CharacterName-PlanetName-ActionType
const actionType = payload.type.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase()); const actionType = payload.type.replace(/_/g, ' ').replace(/\b\w/g, (l: string) => l.toUpperCase());
const topic = `${payload.characterName}-${payload.planetName}-${actionType}`; const topic = `${payload.characterName}-${payload.planetName}-${actionType}`;
// Format content with all the details // Format content with all the details