refactor: match Java cron message format

This commit is contained in:
2026-05-10 21:05:41 +07:00
parent 675f802746
commit ded8a69c91
3 changed files with 22 additions and 63 deletions
+22 -35
View File
@@ -1,5 +1,5 @@
import { buildTable, formatNumber, truncateString } from '../util/table.js';
import { daysBetween, formatDateInTz, formatDateTimeInTz, weekdayInTz } from '../util/time.js';
import { buildTable } from '../util/table.js';
import { daysBetween, formatDateInTz, weekdayInTz } from '../util/time.js';
import { resolveDaysWarning } from '../util/group-settings.js';
// One-shot daily check, invoked from api/cron.js. The cron schedule lives in
@@ -38,7 +38,8 @@ async function checkGroup(groupId, silent, now, config, store, sender, appleScra
}
const threshold = resolveDaysWarning(group, config);
const stale = [];
const staleApple = [];
const staleGoogle = [];
for (const info of group.appleApps) {
try {
@@ -48,15 +49,10 @@ async function checkGroup(groupId, silent, now, config, store, sender, appleScra
if (Number.isNaN(updatedMs)) continue;
const days = daysBetween(updatedMs, now.getTime());
if (days > threshold) {
stale.push({
staleApple.push({
appId: info.appId,
title: app.title,
days,
updated: formatDateInTz(new Date(updatedMs), config.timezone),
score: app.score,
reviews: Number(app.reviews ?? 0),
ratings: Number(app.ratings ?? 0),
isApple: true,
});
}
} catch (err) {
@@ -72,15 +68,10 @@ async function checkGroup(groupId, silent, now, config, store, sender, appleScra
if (!Number.isFinite(updatedMs)) continue;
const days = daysBetween(updatedMs, now.getTime());
if (days > threshold) {
stale.push({
staleGoogle.push({
appId: info.appId,
title: app.title,
days,
updated: formatDateInTz(new Date(updatedMs), config.timezone),
score: app.score,
reviews: Number(app.reviews ?? 0),
ratings: Number(app.ratings ?? 0),
isApple: false,
});
}
} catch (err) {
@@ -88,31 +79,27 @@ async function checkGroup(groupId, silent, now, config, store, sender, appleScra
}
}
if (stale.length === 0) {
const total = staleApple.length + staleGoogle.length;
if (total === 0) {
logger.info({ groupId }, 'All apps up-to-date');
return;
}
const message = buildReport(groupId, stale, now, config, threshold);
const message = buildReport(staleApple, staleGoogle);
if (silent) await sender.sendMessageSilent(groupId, message);
else await sender.sendMessage(groupId, message);
}
function buildReport(groupId, apps, now, config, threshold) {
const headers = ['App', 'Store', 'Days', 'Updated', 'Score', 'Reviews', 'Ratings'];
const rows = apps.map((a) => [
truncateString(a.title || '', 30),
a.isApple ? 'Apple' : 'Google',
String(a.days),
a.updated,
Number(a.score ?? 0).toFixed(1),
String(a.reviews),
formatNumber(a.ratings),
]);
return (
`<b>Daily App Check Report</b>\n` +
`Date: ${formatDateTimeInTz(now, config.timezone)}\n` +
`Group: <code>${groupId}</code>\n` +
`Apps not updated in &gt;${threshold} days: <b>${apps.length}</b>\n\n` +
`<pre>${buildTable(headers, rows)}</pre>`
);
function buildReport(staleApple, staleGoogle) {
const total = staleApple.length + staleGoogle.length;
const headers = ['#', 'AppId', 'Updated', 'Days'];
let out = `You have ${total} app(s) need to be updated!\n`;
if (staleApple.length > 0) {
const rows = staleApple.map((a, i) => [String(i + 1), a.appId, a.updated, String(a.days)]);
out += `<b>${staleApple.length} Apple Apps:</b>\n<code>\n${buildTable(headers, rows)}\n</code>\n`;
}
if (staleGoogle.length > 0) {
const rows = staleGoogle.map((a, i) => [String(i + 1), a.appId, a.updated, String(a.days)]);
out += `<b>${staleGoogle.length} Google Apps:</b>\n<code>\n${buildTable(headers, rows)}\n</code>`;
}
return out;
}
-13
View File
@@ -51,16 +51,3 @@ function writeSeparator(widths) {
function padRight(s, len) {
return s.length >= len ? s : s + ' '.repeat(len - s.length);
}
export function truncateString(s, maxLen) {
if (s.length <= maxLen) return s;
if (maxLen <= 3) return s.slice(0, maxLen);
return s.slice(0, maxLen - 3) + '...';
}
export function formatNumber(n) {
const v = Number(n);
if (v >= 1_000_000) return `${(v / 1_000_000).toFixed(1)}M`;
if (v >= 1_000) return `${(v / 1_000).toFixed(1)}K`;
return String(v);
}
-15
View File
@@ -9,21 +9,6 @@ export function formatDateInTz(date, timezone) {
return fmt.format(date);
}
// Format datetime as "YYYY-MM-DD HH:MM" in given IANA timezone.
export function formatDateTimeInTz(date, timezone) {
const fmt = new Intl.DateTimeFormat('en-CA', {
timeZone: timezone,
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
hour12: false,
});
// en-CA produces "YYYY-MM-DD, HH:MM" — strip the comma.
return fmt.format(date).replace(', ', ' ');
}
// Day-of-week (0=Sun..6=Sat) for `date` in given timezone.
export function weekdayInTz(date, timezone) {
const fmt = new Intl.DateTimeFormat('en-US', { timeZone: timezone, weekday: 'short' });