94 lines
3.1 KiB
JavaScript
94 lines
3.1 KiB
JavaScript
|
|
import cron from 'node-cron';
|
||
|
|
import pool from '../config/database.js';
|
||
|
|
import {
|
||
|
|
sendDemoExpiryReminderMail,
|
||
|
|
sendDemoLastDayMail,
|
||
|
|
sendDemoExpiredMail,
|
||
|
|
} from './mail.js';
|
||
|
|
|
||
|
|
// Findet Demo-Tenants, deren Ablauf in [from, to] liegt UND fuer die noch
|
||
|
|
// keine entsprechende Benachrichtigung versandt wurde, schickt die Mail
|
||
|
|
// und markiert die Spalte mit NOW().
|
||
|
|
async function processWindow({ flagColumn, daysFrom, daysTo, sender }) {
|
||
|
|
const [rows] = await pool.query(
|
||
|
|
`SELECT id, name, kontakt_email, slug, demo_expires_at
|
||
|
|
FROM tenants
|
||
|
|
WHERE typ = 'demo'
|
||
|
|
AND kontakt_email IS NOT NULL
|
||
|
|
AND ${flagColumn} IS NULL
|
||
|
|
AND demo_expires_at IS NOT NULL
|
||
|
|
AND demo_expires_at BETWEEN DATE_ADD(NOW(), INTERVAL ? DAY)
|
||
|
|
AND DATE_ADD(NOW(), INTERVAL ? DAY)`,
|
||
|
|
[daysFrom, daysTo]
|
||
|
|
);
|
||
|
|
for (const t of rows) {
|
||
|
|
try {
|
||
|
|
await sender(t);
|
||
|
|
await pool.query(`UPDATE tenants SET ${flagColumn} = NOW() WHERE id = ?`, [t.id]);
|
||
|
|
console.log(`[expiry] ${flagColumn} -> ${t.kontakt_email} (slug=${t.slug})`);
|
||
|
|
} catch (e) {
|
||
|
|
console.error(`[expiry] Mail-Fehler ${flagColumn} fuer ${t.kontakt_email}:`, e.message);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
async function processExpiredToday() {
|
||
|
|
const [rows] = await pool.query(
|
||
|
|
`SELECT id, name, kontakt_email, slug, demo_expires_at
|
||
|
|
FROM tenants
|
||
|
|
WHERE typ = 'demo'
|
||
|
|
AND kontakt_email IS NOT NULL
|
||
|
|
AND notified_expired_at IS NULL
|
||
|
|
AND demo_expires_at IS NOT NULL
|
||
|
|
AND demo_expires_at <= NOW()`
|
||
|
|
);
|
||
|
|
for (const t of rows) {
|
||
|
|
try {
|
||
|
|
await sendDemoExpiredMail({ to: t.kontakt_email, name: t.name });
|
||
|
|
await pool.query(
|
||
|
|
`UPDATE tenants SET notified_expired_at = NOW(),
|
||
|
|
status = 'abgelaufen'
|
||
|
|
WHERE id = ?`,
|
||
|
|
[t.id]
|
||
|
|
);
|
||
|
|
console.log(`[expiry] expired-mail -> ${t.kontakt_email} (slug=${t.slug})`);
|
||
|
|
} catch (e) {
|
||
|
|
console.error(`[expiry] expired-Mail-Fehler ${t.kontakt_email}:`, e.message);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function runExpiryCheck() {
|
||
|
|
console.log('[expiry] check start', new Date().toISOString());
|
||
|
|
// 7-Tage-Erinnerung: Ablauf in [6, 7] Tagen
|
||
|
|
await processWindow({
|
||
|
|
flagColumn: 'notified_7d_at',
|
||
|
|
daysFrom: 6, daysTo: 7,
|
||
|
|
sender: (t) => sendDemoExpiryReminderMail({
|
||
|
|
to: t.kontakt_email, name: t.name, slug: t.slug,
|
||
|
|
daysLeft: 7, expiresAt: t.demo_expires_at,
|
||
|
|
}),
|
||
|
|
});
|
||
|
|
// 1-Tag-Erinnerung: Ablauf in [0, 1] Tagen (aber noch nicht abgelaufen)
|
||
|
|
await processWindow({
|
||
|
|
flagColumn: 'notified_1d_at',
|
||
|
|
daysFrom: 0, daysTo: 1,
|
||
|
|
sender: (t) => sendDemoLastDayMail({
|
||
|
|
to: t.kontakt_email, name: t.name, slug: t.slug,
|
||
|
|
expiresAt: t.demo_expires_at,
|
||
|
|
}),
|
||
|
|
});
|
||
|
|
// Heute (oder bereits) abgelaufen
|
||
|
|
await processExpiredToday();
|
||
|
|
console.log('[expiry] check done');
|
||
|
|
}
|
||
|
|
|
||
|
|
export function startExpiryCron() {
|
||
|
|
// Taeglich um 08:00 Uhr (Server-Zeit = UTC). Anpassbar via env CRON_EXPIRY_AT
|
||
|
|
const expr = process.env.CRON_EXPIRY_AT || '0 8 * * *';
|
||
|
|
cron.schedule(expr, () => {
|
||
|
|
runExpiryCheck().catch(e => console.error('[expiry] cron error:', e));
|
||
|
|
});
|
||
|
|
console.log('[expiry] cron registriert:', expr);
|
||
|
|
}
|