Update
This commit is contained in:
142
src/app/page.tsx
142
src/app/page.tsx
@@ -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
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user