chore: integrate new admin with l-s
This commit is contained in:
parent
6b3db134e7
commit
bf8f1d991c
72 changed files with 1493 additions and 1611 deletions
145
lib/notifier.js
145
lib/notifier.js
|
|
@ -15,6 +15,7 @@ const ALERT_SEND_INTERVAL = T.hour
|
|||
const PING = 'PING'
|
||||
const STALE = 'STALE'
|
||||
const LOW_CRYPTO_BALANCE = 'LOW_CRYPTO_BALANCE'
|
||||
const HIGH_CRYPTO_BALANCE = 'HIGH_CRYPTO_BALANCE'
|
||||
const CASH_BOX_FULL = 'CASH_BOX_FULL'
|
||||
const LOW_CASH_OUT = 'LOW_CASH_OUT'
|
||||
|
||||
|
|
@ -22,6 +23,7 @@ const CODES_DISPLAY = {
|
|||
PING: 'Machine Down',
|
||||
STALE: 'Machine Stuck',
|
||||
LOW_CRYPTO_BALANCE: 'Low Crypto Balance',
|
||||
HIGH_CRYPTO_BALANCE: 'High Crypto Balance',
|
||||
CASH_BOX_FULL: 'Cash box full',
|
||||
LOW_CASH_OUT: 'Low Cash-out'
|
||||
}
|
||||
|
|
@ -41,47 +43,54 @@ function sameState (a, b) {
|
|||
return a.note.txId === b.note.txId && a.note.state === b.note.state
|
||||
}
|
||||
|
||||
function sendNoAlerts (plugins) {
|
||||
function sendNoAlerts (plugins, smsEnabled, emailEnabled) {
|
||||
const subject = '[Lamassu] All clear'
|
||||
const rec = {
|
||||
sms: {
|
||||
body: subject
|
||||
},
|
||||
email: {
|
||||
subject,
|
||||
body: 'No errors are reported for your machines.'
|
||||
}
|
||||
|
||||
let rec = {}
|
||||
if (smsEnabled) {
|
||||
rec = _.set(['sms', 'body'])(subject)(rec)
|
||||
}
|
||||
|
||||
if (emailEnabled) {
|
||||
rec = _.set(['email', 'subject'])(subject)(rec)
|
||||
rec = _.set(['email', 'body'])('No errors are reported for your machines.')(rec)
|
||||
}
|
||||
|
||||
return plugins.sendMessage(rec)
|
||||
}
|
||||
|
||||
function checkNotification (plugins) {
|
||||
if (!plugins.notificationsEnabled()) return Promise.resolve()
|
||||
const notifications = plugins.getNotificationConfig()
|
||||
const isActive = it => it.active && (it.balance || it.errors)
|
||||
const smsEnabled = isActive(notifications.sms)
|
||||
const emailEnabled = isActive(notifications.email)
|
||||
|
||||
if (!smsEnabled && !emailEnabled) return Promise.resolve()
|
||||
|
||||
return checkStatus(plugins)
|
||||
.then(alertRec => {
|
||||
const currentAlertFingerprint = buildAlertFingerprint(alertRec)
|
||||
const currentAlertFingerprint = buildAlertFingerprint(alertRec, notifications)
|
||||
if (!currentAlertFingerprint) {
|
||||
const inAlert = !!alertFingerprint
|
||||
alertFingerprint = null
|
||||
lastAlertTime = null
|
||||
if (inAlert) return sendNoAlerts(plugins)
|
||||
if (inAlert) return sendNoAlerts(plugins, smsEnabled, emailEnabled)
|
||||
}
|
||||
|
||||
const alertChanged = currentAlertFingerprint === alertFingerprint &&
|
||||
lastAlertTime - Date.now() < ALERT_SEND_INTERVAL
|
||||
if (alertChanged) return
|
||||
|
||||
const rec = {
|
||||
sms: {
|
||||
body: printSmsAlerts(alertRec)
|
||||
},
|
||||
email: {
|
||||
subject: alertSubject(alertRec),
|
||||
body: printEmailAlerts(alertRec)
|
||||
}
|
||||
let rec = {}
|
||||
if (smsEnabled) {
|
||||
rec = _.set(['sms', 'body'])(printSmsAlerts(alertRec, notifications.sms))(rec)
|
||||
}
|
||||
|
||||
if (emailEnabled) {
|
||||
rec = _.set(['email', 'subject'])(alertSubject(alertRec, notifications.email))(rec)
|
||||
rec = _.set(['email', 'body'])(printEmailAlerts(alertRec, notifications.email))(rec)
|
||||
}
|
||||
|
||||
alertFingerprint = currentAlertFingerprint
|
||||
lastAlertTime = Date.now()
|
||||
|
||||
|
|
@ -162,12 +171,13 @@ function checkStatus (plugins) {
|
|||
return eventRow.device_id === deviceId
|
||||
})
|
||||
|
||||
const balanceAlerts = _.filter(['deviceId', deviceId], balances)
|
||||
const ping = pings[deviceId] || []
|
||||
const stuckScreen = checkStuckScreen(deviceEvents, deviceName)
|
||||
const deviceAlerts = _.isEmpty(ping) ? stuckScreen : ping
|
||||
|
||||
alerts.devices[deviceId] = _.concat(deviceAlerts, balanceAlerts)
|
||||
if (!alerts.devices[deviceId]) alerts.devices[deviceId] = {}
|
||||
alerts.devices[deviceId].balanceAlerts = _.filter(['deviceId', deviceId], balances)
|
||||
alerts.devices[deviceId].deviceAlerts = _.isEmpty(ping) ? stuckScreen : ping
|
||||
|
||||
alerts.deviceNames[deviceId] = deviceName
|
||||
})
|
||||
|
||||
|
|
@ -194,6 +204,9 @@ function emailAlert (alert) {
|
|||
case LOW_CRYPTO_BALANCE:
|
||||
const balance = formatCurrency(alert.fiatBalance.balance, alert.fiatCode)
|
||||
return `Low balance in ${alert.cryptoCode} [${balance}]`
|
||||
case HIGH_CRYPTO_BALANCE:
|
||||
const highBalance = formatCurrency(alert.fiatBalance.balance, alert.fiatCode)
|
||||
return `High balance in ${alert.cryptoCode} [${highBalance}]`
|
||||
case CASH_BOX_FULL:
|
||||
return `Cash box full on ${alert.machineName} [${alert.notes} banknotes]`
|
||||
case LOW_CASH_OUT:
|
||||
|
|
@ -205,28 +218,48 @@ function emailAlerts (alerts) {
|
|||
return alerts.map(emailAlert).join('\n') + '\n'
|
||||
}
|
||||
|
||||
function printEmailAlerts (alertRec) {
|
||||
function printEmailAlerts (alertRec, config) {
|
||||
let body = 'Errors were reported by your Lamassu Machines.\n'
|
||||
|
||||
if (alertRec.general.length !== 0) {
|
||||
if (config.balance && alertRec.general.length !== 0) {
|
||||
body = body + '\nGeneral errors:\n'
|
||||
body = body + emailAlerts(alertRec.general)
|
||||
body = body + emailAlerts(alertRec.general) + '\n'
|
||||
}
|
||||
|
||||
_.keys(alertRec.devices).forEach(function (device) {
|
||||
const deviceName = alertRec.deviceNames[device]
|
||||
body = body + '\nErrors for ' + deviceName + ':\n'
|
||||
body = body + emailAlerts(alertRec.devices[device])
|
||||
|
||||
let alerts = []
|
||||
if (config.balance) {
|
||||
alerts = _.concat(alerts, alertRec.devices[device].balanceAlerts)
|
||||
}
|
||||
|
||||
if (config.errors) {
|
||||
alerts = _.concat(alerts, alertRec.devices[device].deviceAlerts)
|
||||
}
|
||||
|
||||
body = body + emailAlerts(alerts)
|
||||
})
|
||||
|
||||
return body
|
||||
}
|
||||
|
||||
function alertSubject (alertRec) {
|
||||
let alerts = alertRec.general
|
||||
function alertSubject (alertRec, config) {
|
||||
let alerts = []
|
||||
|
||||
if (config.balance) {
|
||||
alerts = _.concat(alerts, alertRec.general)
|
||||
}
|
||||
|
||||
_.keys(alertRec.devices).forEach(function (device) {
|
||||
alerts = _.concat(alerts, alertRec.devices[device])
|
||||
if (config.balance) {
|
||||
alerts = _.concat(alerts, alertRec.devices[device].balanceAlerts)
|
||||
}
|
||||
|
||||
if (config.errors) {
|
||||
alerts = _.concat(alerts, alertRec.devices[device].deviceAlerts)
|
||||
}
|
||||
})
|
||||
|
||||
if (alerts.length === 0) return null
|
||||
|
|
@ -235,11 +268,21 @@ function alertSubject (alertRec) {
|
|||
return '[Lamassu] Errors reported: ' + alertTypes.join(', ')
|
||||
}
|
||||
|
||||
function printSmsAlerts (alertRec) {
|
||||
let alerts = alertRec.general
|
||||
function printSmsAlerts (alertRec, config) {
|
||||
let alerts = []
|
||||
|
||||
if (config.balance) {
|
||||
alerts = _.concat(alerts, alertRec.general)
|
||||
}
|
||||
|
||||
_.keys(alertRec.devices).forEach(function (device) {
|
||||
alerts = _.concat(alerts, alertRec.devices[device])
|
||||
if (config.balance) {
|
||||
alerts = _.concat(alerts, alertRec.devices[device].balanceAlerts)
|
||||
}
|
||||
|
||||
if (config.errors) {
|
||||
alerts = _.concat(alerts, alertRec.devices[device].deviceAlerts)
|
||||
}
|
||||
})
|
||||
|
||||
if (alerts.length === 0) return null
|
||||
|
|
@ -265,9 +308,39 @@ function printSmsAlerts (alertRec) {
|
|||
return '[Lamassu] Errors reported: ' + displayAlertTypes.join(', ')
|
||||
}
|
||||
|
||||
function buildAlertFingerprint (alertRec) {
|
||||
const subject = alertSubject(alertRec)
|
||||
if (!subject) return null
|
||||
function getAlertTypes (alertRec, config) {
|
||||
let alerts = []
|
||||
|
||||
if (!config.active || (!config.balance && !config.errors)) return alerts
|
||||
|
||||
if (config.balance) {
|
||||
alerts = _.concat(alerts, alertRec.general)
|
||||
}
|
||||
|
||||
_.keys(alertRec.devices).forEach(function (device) {
|
||||
if (config.balance) {
|
||||
alerts = _.concat(alerts, alertRec.devices[device].balanceAlerts)
|
||||
}
|
||||
|
||||
if (config.errors) {
|
||||
alerts = _.concat(alerts, alertRec.devices[device].deviceAlerts)
|
||||
}
|
||||
})
|
||||
|
||||
return alerts
|
||||
}
|
||||
|
||||
function buildAlertFingerprint (alertRec, notifications) {
|
||||
const sms = getAlertTypes(alertRec, notifications.sms)
|
||||
const email = getAlertTypes(alertRec, notifications.email)
|
||||
|
||||
if (sms.length === 0 && email.length === 0) return null
|
||||
|
||||
const smsTypes = _.map(codeDisplay, _.uniq(_.map('code', sms))).sort()
|
||||
const emailTypes = _.map(codeDisplay, _.uniq(_.map('code', email))).sort()
|
||||
|
||||
const subject = _.concat(smsTypes, emailTypes).join(', ')
|
||||
|
||||
return crypto.createHash('sha256').update(subject).digest('hex')
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue