button zum prüfen
This commit is contained in:
@@ -98,6 +98,16 @@ async function sendSlotNotification({ profileId, storeName, pickupDate, onlyNoti
|
||||
});
|
||||
}
|
||||
|
||||
function formatStoreWatchStatus(status) {
|
||||
if (status === 1) {
|
||||
return 'Suchend';
|
||||
}
|
||||
if (status === 0) {
|
||||
return 'Nicht suchend';
|
||||
}
|
||||
return 'Status unbekannt';
|
||||
}
|
||||
|
||||
async function sendStoreWatchNotification({ profileId, storeName, storeId, regionName }) {
|
||||
const storeLink = storeId ? `https://foodsharing.de/store/${storeId}` : null;
|
||||
const title = `Team sucht Verstärkung: ${storeName}`;
|
||||
@@ -112,6 +122,33 @@ async function sendStoreWatchNotification({ profileId, storeName, storeId, regio
|
||||
});
|
||||
}
|
||||
|
||||
async function sendStoreWatchSummaryNotification({ profileId, entries = [], triggeredBy = 'manual' }) {
|
||||
if (!profileId || !Array.isArray(entries) || entries.length === 0) {
|
||||
return;
|
||||
}
|
||||
const lines = entries
|
||||
.map((entry) => {
|
||||
const regionSuffix = entry.regionName ? ` (${entry.regionName})` : '';
|
||||
const statusLabel = formatStoreWatchStatus(entry.status);
|
||||
const timestamp = entry.checkedAt ? ` – Stand ${formatDateLabel(entry.checkedAt)}` : '';
|
||||
const errorLabel = entry.error ? ` – Fehler: ${entry.error}` : '';
|
||||
return `• ${entry.storeName || `Store ${entry.storeId}`}${regionSuffix}: ${statusLabel}${timestamp}${errorLabel}`;
|
||||
})
|
||||
.join('\n');
|
||||
const prefix =
|
||||
triggeredBy === 'manual'
|
||||
? 'Manuell angestoßene Store-Watch-Prüfung abgeschlossen:'
|
||||
: 'Store-Watch-Prüfung abgeschlossen:';
|
||||
const title =
|
||||
triggeredBy === 'manual' ? 'Ad-hoc Store-Watch-Prüfung' : 'Store-Watch-Prüfung';
|
||||
const message = `${prefix}\n${lines}`;
|
||||
await notifyChannels(profileId, {
|
||||
title,
|
||||
message,
|
||||
priority: 'default'
|
||||
});
|
||||
}
|
||||
|
||||
async function sendDesiredWindowMissedNotification({ profileId, storeName, desiredWindowLabel }) {
|
||||
if (!profileId) {
|
||||
return;
|
||||
@@ -165,6 +202,7 @@ async function sendTestNotification(profileId, channel) {
|
||||
module.exports = {
|
||||
sendSlotNotification,
|
||||
sendStoreWatchNotification,
|
||||
sendStoreWatchSummaryNotification,
|
||||
sendTestNotification,
|
||||
sendDesiredWindowMissedNotification
|
||||
};
|
||||
|
||||
@@ -411,28 +411,30 @@ async function checkEntry(sessionId, entry, settings) {
|
||||
}
|
||||
}
|
||||
|
||||
async function checkWatchedStores(sessionId, settings = DEFAULT_SETTINGS) {
|
||||
async function checkWatchedStores(sessionId, settings = DEFAULT_SETTINGS, options = {}) {
|
||||
const session = sessionStore.get(sessionId);
|
||||
if (!session?.profile?.id) {
|
||||
return;
|
||||
return [];
|
||||
}
|
||||
const watchers = readStoreWatch(session.profile.id);
|
||||
if (!Array.isArray(watchers) || watchers.length === 0) {
|
||||
return;
|
||||
return [];
|
||||
}
|
||||
|
||||
const ready = await ensureSession(session);
|
||||
if (!ready) {
|
||||
return;
|
||||
return [];
|
||||
}
|
||||
|
||||
const perRequestDelay = Math.max(0, Number(settings?.storeWatchRequestDelayMs) || 0);
|
||||
let changed = false;
|
||||
const summary = [];
|
||||
for (let index = 0; index < watchers.length; index += 1) {
|
||||
const watcher = watchers[index];
|
||||
try {
|
||||
const details = await foodsharingClient.fetchStoreDetails(watcher.storeId, session.cookieHeader);
|
||||
const status = details?.teamSearchStatus === 1 ? 1 : 0;
|
||||
const checkedAt = Date.now();
|
||||
if (status === 1 && watcher.lastTeamSearchStatus !== 1) {
|
||||
await notificationService.sendStoreWatchNotification({
|
||||
profileId: session.profile.id,
|
||||
@@ -445,8 +447,25 @@ async function checkWatchedStores(sessionId, settings = DEFAULT_SETTINGS) {
|
||||
watcher.lastTeamSearchStatus = status;
|
||||
changed = true;
|
||||
}
|
||||
watcher.lastStatusCheckAt = checkedAt;
|
||||
changed = true;
|
||||
summary.push({
|
||||
storeId: watcher.storeId,
|
||||
storeName: watcher.storeName,
|
||||
regionName: watcher.regionName,
|
||||
status,
|
||||
checkedAt
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(`[WATCH] Prüfung für Store ${watcher.storeId} fehlgeschlagen:`, error.message);
|
||||
summary.push({
|
||||
storeId: watcher.storeId,
|
||||
storeName: watcher.storeName,
|
||||
regionName: watcher.regionName,
|
||||
status: null,
|
||||
checkedAt: Date.now(),
|
||||
error: error.message || 'Unbekannter Fehler'
|
||||
});
|
||||
} finally {
|
||||
const hasNext = index < watchers.length - 1;
|
||||
if (hasNext && perRequestDelay > 0) {
|
||||
@@ -458,6 +477,18 @@ async function checkWatchedStores(sessionId, settings = DEFAULT_SETTINGS) {
|
||||
if (changed) {
|
||||
writeStoreWatch(session.profile.id, watchers);
|
||||
}
|
||||
if (options.sendSummary && summary.length > 0) {
|
||||
try {
|
||||
await notificationService.sendStoreWatchSummaryNotification({
|
||||
profileId: session.profile.id,
|
||||
entries: summary,
|
||||
triggeredBy: options.triggeredBy || 'manual'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('[WATCH] Zusammenfassung konnte nicht versendet werden:', error.message);
|
||||
}
|
||||
}
|
||||
return summary;
|
||||
}
|
||||
|
||||
function scheduleStoreWatchers(sessionId, settings) {
|
||||
@@ -538,6 +569,12 @@ function scheduleConfig(sessionId, config, settings) {
|
||||
);
|
||||
}
|
||||
|
||||
async function runStoreWatchCheck(sessionId, settings, options = {}) {
|
||||
const resolvedSettings = resolveSettings(settings);
|
||||
return checkWatchedStores(sessionId, resolvedSettings, options);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
scheduleConfig
|
||||
scheduleConfig,
|
||||
runStoreWatchCheck
|
||||
};
|
||||
|
||||
@@ -17,6 +17,7 @@ function sanitizeEntry(entry) {
|
||||
if (!entry || !entry.storeId) {
|
||||
return null;
|
||||
}
|
||||
const parsedLastCheck = Number(entry.lastStatusCheckAt);
|
||||
const normalized = {
|
||||
storeId: String(entry.storeId),
|
||||
storeName: entry.storeName ? String(entry.storeName).trim() : `Store ${entry.storeId}`,
|
||||
@@ -27,7 +28,8 @@ function sanitizeEntry(entry) {
|
||||
? 1
|
||||
: entry.lastTeamSearchStatus === 0
|
||||
? 0
|
||||
: null
|
||||
: null,
|
||||
lastStatusCheckAt: Number.isFinite(parsedLastCheck) ? parsedLastCheck : null
|
||||
};
|
||||
if (!normalized.regionId) {
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user