Push-Erinnerungen: Widget, Backend-Scheduler, Pushover-Versand jede Minute
This commit is contained in:
@@ -84,17 +84,20 @@ async function sendPushoverMsg(userKey, appToken, message) {
|
|||||||
|
|
||||||
setInterval(async () => {
|
setInterval(async () => {
|
||||||
try {
|
try {
|
||||||
|
const now = db.prepare("SELECT datetime('now','localtime') as t").get().t;
|
||||||
const due = db.prepare(`
|
const due = db.prepare(`
|
||||||
SELECT s.*, p.user_key, p.app_token
|
SELECT s.*, p.user_key, p.app_token
|
||||||
FROM push_schedules s
|
FROM push_schedules s
|
||||||
JOIN pushover_settings p ON p.user_id = s.user_id
|
JOIN pushover_settings p ON p.user_id = s.user_id
|
||||||
WHERE s.sent = 0 AND s.scheduled_at <= datetime('now','localtime')
|
WHERE s.sent = 0 AND s.scheduled_at <= ?
|
||||||
`).all();
|
`).all(now);
|
||||||
|
|
||||||
for (const row of due) {
|
for (const row of due) {
|
||||||
await sendPushoverMsg(row.user_key, row.app_token, row.message);
|
await sendPushoverMsg(row.user_key, row.app_token, row.message);
|
||||||
db.prepare('UPDATE push_schedules SET sent=1 WHERE id=?').run(row.id);
|
db.prepare('UPDATE push_schedules SET sent=1 WHERE id=?').run(row.id);
|
||||||
console.log(`✓ Push gesendet an user ${row.user_id}: ${row.message}`);
|
console.log(`✓ Push gesendet an user ${row.user_id}: "${row.message}" (fällig: ${row.scheduled_at})`);
|
||||||
}
|
}
|
||||||
} catch(e) { console.error('Push-Job Fehler:', e.message); }
|
} catch(e) { console.error('Push-Job Fehler:', e.message); }
|
||||||
}, 60 * 1000); // jede Minute
|
}, 60 * 1000);
|
||||||
|
|
||||||
|
console.log('⏰ Push-Scheduler aktiv (jede Minute)');
|
||||||
|
|||||||
@@ -219,10 +219,12 @@ router.get('/push-schedules', authenticate, (req, res) => {
|
|||||||
router.post('/push-schedules', authenticate, (req, res) => {
|
router.post('/push-schedules', authenticate, (req, res) => {
|
||||||
const { message, scheduled_at } = req.body;
|
const { message, scheduled_at } = req.body;
|
||||||
if (!message?.trim() || !scheduled_at) return res.status(400).json({ error: 'Nachricht und Zeitpunkt erforderlich' });
|
if (!message?.trim() || !scheduled_at) return res.status(400).json({ error: 'Nachricht und Zeitpunkt erforderlich' });
|
||||||
|
// Normalisieren: T→Leerzeichen, Sekunden ergänzen
|
||||||
|
const normalized = scheduled_at.replace('T',' ') + (scheduled_at.length <= 16 ? ':00' : '');
|
||||||
const r = db.prepare(`
|
const r = db.prepare(`
|
||||||
INSERT INTO push_schedules (user_id, message, scheduled_at, created_at)
|
INSERT INTO push_schedules (user_id, message, scheduled_at, created_at)
|
||||||
VALUES (?, ?, ?, datetime('now','localtime'))
|
VALUES (?, ?, ?, datetime('now','localtime'))
|
||||||
`).run(uid(req), message.trim(), scheduled_at);
|
`).run(uid(req), message.trim(), normalized);
|
||||||
res.json(db.prepare('SELECT * FROM push_schedules WHERE id=?').get(r.lastInsertRowid));
|
res.json(db.prepare('SELECT * FROM push_schedules WHERE id=?').get(r.lastInsertRowid));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -230,8 +232,9 @@ router.put('/push-schedules/:id', authenticate, (req, res) => {
|
|||||||
const row = db.prepare('SELECT * FROM push_schedules WHERE id=? AND user_id=?').get(req.params.id, uid(req));
|
const row = db.prepare('SELECT * FROM push_schedules WHERE id=? AND user_id=?').get(req.params.id, uid(req));
|
||||||
if (!row) return res.status(404).json({ error: 'Nicht gefunden' });
|
if (!row) return res.status(404).json({ error: 'Nicht gefunden' });
|
||||||
const { message, scheduled_at } = req.body;
|
const { message, scheduled_at } = req.body;
|
||||||
|
const normalized = scheduled_at ? scheduled_at.replace('T',' ') + (scheduled_at.length <= 16 ? ':00' : '') : row.scheduled_at;
|
||||||
db.prepare('UPDATE push_schedules SET message=?, scheduled_at=?, sent=0 WHERE id=?')
|
db.prepare('UPDATE push_schedules SET message=?, scheduled_at=?, sent=0 WHERE id=?')
|
||||||
.run(message ?? row.message, scheduled_at ?? row.scheduled_at, row.id);
|
.run(message ?? row.message, normalized, row.id);
|
||||||
res.json(db.prepare('SELECT * FROM push_schedules WHERE id=?').get(row.id));
|
res.json(db.prepare('SELECT * FROM push_schedules WHERE id=?').get(row.id));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1008,10 +1008,11 @@ function PushScheduler({ toast }) {
|
|||||||
api('/tools/nachrichten/pushover').then(d=>setHasPushover(!!(d.user_key&&d.app_token))).catch(()=>{});
|
api('/tools/nachrichten/pushover').then(d=>setHasPushover(!!(d.user_key&&d.app_token))).catch(()=>{});
|
||||||
}, [isOpen]);
|
}, [isOpen]);
|
||||||
|
|
||||||
// Vorauswahl: jetzt + 1 Stunde
|
// Vorauswahl: jetzt + 1 Stunde in Lokalzeit
|
||||||
const defaultDt = () => {
|
const defaultDt = () => {
|
||||||
const d = new Date(Date.now() + 60*60*1000);
|
const d = new Date(Date.now() + 60*60*1000);
|
||||||
return d.toISOString().slice(0,16);
|
const p = n => String(n).padStart(2,'0');
|
||||||
|
return `${d.getFullYear()}-${p(d.getMonth()+1)}-${p(d.getDate())}T${p(d.getHours())}:${p(d.getMinutes())}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const fmtDt = s => { if (!s) return ''; const d = new Date(s.replace(' ','T')); return isNaN(d)?s:d.toLocaleString('de-DE',{day:'2-digit',month:'2-digit',hour:'2-digit',minute:'2-digit'}); };
|
const fmtDt = s => { if (!s) return ''; const d = new Date(s.replace(' ','T')); return isNaN(d)?s:d.toLocaleString('de-DE',{day:'2-digit',month:'2-digit',hour:'2-digit',minute:'2-digit'}); };
|
||||||
|
|||||||
Reference in New Issue
Block a user