diff --git a/host-stacks/vds-kzntsv/sched-custom/custom-entry.mjs b/host-stacks/vds-kzntsv/sched-custom/custom-entry.mjs index 130be4d..9ae253e 100644 --- a/host-stacks/vds-kzntsv/sched-custom/custom-entry.mjs +++ b/host-stacks/vds-kzntsv/sched-custom/custom-entry.mjs @@ -32,9 +32,25 @@ const storage = await createMysqlStorage(pool); // self-migrates on open const dbName = dbNameFromUrl(MYSQL_URL); // --- daemon: engine only (we own the http server) --- +// Programmatic alerts (from env), NOT the tasks.json block: the published @schedjs/daemon 0.12.1 +// does not wire onRunFinal from the file alerts block reliably (books-vds uses a books-built +// daemon where it does). Passing `alerts` explicitly guarantees the onRunFinal hook is set. +const ALERT_WEBHOOK = process.env.SCHED_ALERTS_WEBHOOK_URL; +const ALERT_BASIC = process.env.SCHED_ALERTS_BASIC_AUTH; // base64 `user:pass`, optional const daemon = createDaemon({ storage, tasksPath: TASKS, + ...(ALERT_WEBHOOK + ? { alerts: { + on: ['failed'], + onMissed: true, + onSyncFailed: true, + webhook: { + url: ALERT_WEBHOOK, + ...(ALERT_BASIC ? { headers: { Authorization: `Basic ${ALERT_BASIC}` } } : {}), + }, + } } + : {}), // no `admin` here — createDaemon would bind its own /api-only server; we route ourselves }); await daemon.start(); diff --git a/host-stacks/vds-kzntsv/sched.compose.yml b/host-stacks/vds-kzntsv/sched.compose.yml index c35de45..046fb6e 100644 --- a/host-stacks/vds-kzntsv/sched.compose.yml +++ b/host-stacks/vds-kzntsv/sched.compose.yml @@ -20,6 +20,8 @@ services: SCHED_TASKS: /app/config/tasks.json MYSQL_URL: mysql://sched:${SCHED_DB_PASS}@mariadb:3306/sched?ssl={"rejectUnauthorized":false} SCHED_ADMIN_KEY: ${SCHED_ADMIN_KEY} + SCHED_ALERTS_WEBHOOK_URL: ${SCHED_ALERTS_WEBHOOK_URL} + SCHED_ALERTS_BASIC_AUTH: ${SCHED_ALERTS_BASIC_AUTH} volumes: - /opt/stacks/sched/tasks.json:/app/config/tasks.json:ro healthcheck: