sync: auto-sync from DESKTOP-0O8A1RL at 2026-04-21 18:46:45

Author: Mike Swanson
Machine: DESKTOP-0O8A1RL
Timestamp: 2026-04-21 18:46:45
This commit is contained in:
2026-04-21 18:46:49 -07:00
parent a9bcbc2580
commit 63089c45c9
6 changed files with 1504 additions and 1324 deletions

View File

@@ -0,0 +1,63 @@
/**
* Failure notification via email.
*
* Reads SMTP config from config/notify.json (gitignored, written by deploy-to-ad2.py).
* Silently swallows send errors so a notification failure never masks the real error.
*/
const fs = require('fs');
const path = require('path');
const CONFIG_PATH = path.join(__dirname, '..', 'config', 'notify.json');
function loadConfig() {
try {
return JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf8'));
} catch (err) {
console.error(`[NOTIFY] Could not read ${CONFIG_PATH}: ${err.message}`);
return null;
}
}
/**
* Send a failure notification email.
* @param {string} subject
* @param {string} body - plain text
*/
async function sendFailureEmail(subject, body) {
const cfg = loadConfig();
if (!cfg) return;
let nodemailer;
try {
nodemailer = require('nodemailer');
} catch (err) {
console.error('[NOTIFY] nodemailer not installed — skipping email');
return;
}
const transporter = nodemailer.createTransport({
host: cfg.smtp.host,
port: cfg.smtp.port,
secure: false,
requireTLS: true,
auth: {
user: cfg.smtp.user,
pass: cfg.smtp.pass,
},
});
try {
await transporter.sendMail({
from: cfg.from,
to: cfg.to,
subject,
text: body,
});
console.log(`[NOTIFY] Failure email sent: ${subject}`);
} catch (err) {
console.error(`[NOTIFY] Failed to send email: ${err.message}`);
}
}
module.exports = { sendFailureEmail };