Feat: crypto balance notifications saving in DB
Chore: add new column "detail" to transactions table migration Feat: check if older notification is valid before sending new one Feat: error saving to database Fix: fix error when invalidating notification on clearCryptoBalanceNotifications Chre: code refactor in new-settings-loader for simplicity Chore: refactor code on notifier and merge similar functions
This commit is contained in:
parent
d73520c0c0
commit
1ec56cd1ab
6 changed files with 138 additions and 22 deletions
|
|
@ -84,8 +84,4 @@ function emailAlert (alert) {
|
||||||
|
|
||||||
const sendMessage = email.sendMessage
|
const sendMessage = email.sendMessage
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
|
|
||||||
>>>>>>> 1706b2c... Feat: save highVolumeTxs on DB and plugins code refactor
|
|
||||||
module.exports = { alertSubject, printEmailAlerts, sendMessage }
|
module.exports = { alertSubject, printEmailAlerts, sendMessage }
|
||||||
|
|
|
||||||
|
|
@ -371,7 +371,7 @@ const cashCassettesNotify = (cassettes, deviceId) => {
|
||||||
|
|
||||||
if(cashOutEnabled) {
|
if(cashOutEnabled) {
|
||||||
// we only want to add this notification if there isn't one already set and unread in the database
|
// we only want to add this notification if there isn't one already set and unread in the database
|
||||||
Promise.all([queries.getUnreadCassetteNotifications(1), queries.getUnreadCassetteNotifications(2)]).then(res => {
|
Promise.all([queries.getUnreadCassetteNotifications(1, deviceId), queries.getUnreadCassetteNotifications(2, deviceId)]).then(res => {
|
||||||
if(res[0].length === 0 && cassette1Count < cassette1Threshold) {
|
if(res[0].length === 0 && cassette1Count < cassette1Threshold) {
|
||||||
console.log("Adding fiatBalance alert for cashbox 1 in database - count & threshold: ", cassette1Count, cassette1Threshold )
|
console.log("Adding fiatBalance alert for cashbox 1 in database - count & threshold: ", cassette1Count, cassette1Threshold )
|
||||||
queries.addCashCassetteWarning(1, deviceId)
|
queries.addCashCassetteWarning(1, deviceId)
|
||||||
|
|
@ -385,6 +385,133 @@ const cashCassettesNotify = (cassettes, deviceId) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Notes for new "valid" column on notifications table:
|
||||||
|
|
||||||
|
- We only want to add a new notification if it is present in the high or low warning consts.
|
||||||
|
- Before we add the notification we need to see if there is no "valid" notification in the database.
|
||||||
|
- Since the poller runs every few seconds, if the user marks it as read, this code would add a new notification
|
||||||
|
immediately. This new column helps us decide if a new notification should be added.
|
||||||
|
- "Valid" is defaulted to "true". When the cryptobalance goes over the low threshold or under the high threshold,
|
||||||
|
the notification will be marked as invalid. This will allow a new one to be sent. If the cryptobalance never goes
|
||||||
|
into the middle of the high and low thresholds, the old, "read" notification will still be relevant so we won't add
|
||||||
|
a new one.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const clearOldCryptoNotifications = (balances) => {
|
||||||
|
// get valid crypto notifications from DB
|
||||||
|
// if that notification doesn't exist in balances, then make it invalid on the DB
|
||||||
|
queries.getAllValidNotifications('cryptoBalance').then(res => {
|
||||||
|
const notifications = _.map(it => {
|
||||||
|
return {
|
||||||
|
cryptoCode: it.detail.split('_')[0],
|
||||||
|
code: it.detail.split('_').splice(1).join('_')
|
||||||
|
}
|
||||||
|
}, res)
|
||||||
|
_.forEach(notification => {
|
||||||
|
const idx = _.findIndex(balance => {
|
||||||
|
return balance.code === notification.code && balance.cryptoCode === notification.cryptoCode
|
||||||
|
}, balances)
|
||||||
|
|
||||||
|
if(idx !== -1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// if the notification doesn't exist in the new balances object, then it is outdated and is not valid anymore
|
||||||
|
queries.invalidateNotification(notification.id)
|
||||||
|
}, notifications)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const balancesNotify = (balances) => {
|
||||||
|
const highFilter = o => o.code === 'HIGH_CRYPTO_BALANCE'
|
||||||
|
const lowFilter = o => o.code === 'LOW_CRYPTO_BALANCE'
|
||||||
|
const highWarnings = _.filter(highFilter, balances)
|
||||||
|
const lowWarnings = _.filter(lowFilter, balances)
|
||||||
|
|
||||||
|
clearOldCryptoNotifications(balances)
|
||||||
|
|
||||||
|
highWarnings.forEach(warning => {
|
||||||
|
queries.getValidNotifications('cryptoBalance', `${warning.cryptoCode}_${warning.code}`).then(res => {
|
||||||
|
if (res.length > 0) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
console.log("Adding high balance alert for " + warning.cryptoCode + " - " + warning.fiatBalance.balance)
|
||||||
|
const balance = utils.formatCurrency(warning.fiatBalance.balance, warning.fiatCode)
|
||||||
|
queries.addCryptoBalanceWarning(`${warning.cryptoCode}_${warning.code}`, `High balance in ${warning.cryptoCode} [${balance}]`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
lowWarnings.forEach(warning => {
|
||||||
|
queries.getValidNotifications('cryptoBalance', `${warning.cryptoCode}_${warning.code}`).then(res => {
|
||||||
|
if (res.length > 0) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
console.log("Adding low balance alert for " + warning.cryptoCode + " - " + warning.fiatBalance.balance)
|
||||||
|
const balance = utils.formatCurrency(warning.fiatBalance.balance, warning.fiatCode)
|
||||||
|
queries.addCryptoBalanceWarning(`${warning.cryptoCode}_${warning.code}`, `Low balance in ${warning.cryptoCode} [${balance}]`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const clearOldErrorNotifications = (alerts) => {
|
||||||
|
queries.getAllValidNotifications('error').then(res => {
|
||||||
|
_.forEach(notification => {
|
||||||
|
const idx = _.findIndex(alert => {
|
||||||
|
return alert.code === notification.detail.split('_')[0] && alert.deviceId === notification.device_id
|
||||||
|
}, alerts)
|
||||||
|
if(idx !== -1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// if the notification doesn't exist, then it is outdated and is not valid anymore
|
||||||
|
queries.invalidateNotification(notification.id)
|
||||||
|
}, res)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const errorAlertsNotify = (alertRec) => {
|
||||||
|
let alerts = []
|
||||||
|
_.keys(alertRec.devices).forEach(function (device) {
|
||||||
|
// embed device ID in each alert object inside the deviceAlerts array
|
||||||
|
alertRec.devices[device].deviceAlerts = _.map(alert => {
|
||||||
|
return {...alert, deviceId: device}
|
||||||
|
}, alertRec.devices[device].deviceAlerts)
|
||||||
|
// concat every array into one
|
||||||
|
alerts = _.concat(alerts, alertRec.devices[device].deviceAlerts)
|
||||||
|
})
|
||||||
|
|
||||||
|
// now that we have all the alerts, we want to add PING and STALE alerts to the DB
|
||||||
|
// if there is a valid alert on the DB that doesn't exist on the new alerts array,
|
||||||
|
// that alert should be considered invalid
|
||||||
|
// after that, for the alerts array, we have to see if there is a valid alert of
|
||||||
|
// the sorts already on the DB
|
||||||
|
clearOldErrorNotifications(alerts)
|
||||||
|
|
||||||
|
_.forEach(alert => {
|
||||||
|
switch(alert.code) {
|
||||||
|
case PING:
|
||||||
|
return queries.getValidNotifications('error', PING, alert.deviceId).then(res => {
|
||||||
|
if(res.length > 0) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
console.log("Adding PING alert on database for " + alert.machineName)
|
||||||
|
const message = `Machine down`
|
||||||
|
queries.addErrorNotification(`${PING}_${alert.age ? alert.age : '-1'}`, message, alert.deviceId)
|
||||||
|
})
|
||||||
|
case STALE:
|
||||||
|
return queries.getValidNotifications('error', STALE, alert.deviceId).then(res => {
|
||||||
|
if(res.length > 0) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
console.log("Adding STALE alert on database for " + alert.machineName)
|
||||||
|
const message = `Machine is stuck on ${alert.state} screen`
|
||||||
|
queries.addErrorNotification(STALE, message, alert.deviceId)
|
||||||
|
})
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}, alerts)
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
transactionNotify,
|
transactionNotify,
|
||||||
checkNotification,
|
checkNotification,
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,12 @@ function printSmsAlerts (alertRec, config) {
|
||||||
const code = entry[0]
|
const code = entry[0]
|
||||||
const machineNames = _.filter(
|
const machineNames = _.filter(
|
||||||
_.negate(_.isEmpty),
|
_.negate(_.isEmpty),
|
||||||
_.map('machineName', entry[1])
|
_.map('machineName', entry[1]),
|
||||||
|
)
|
||||||
|
|
||||||
|
const cryptoCodes = _.filter(
|
||||||
|
_.negate(_.isEmpty),
|
||||||
|
_.map('cryptoCode', entry[1]),
|
||||||
)
|
)
|
||||||
|
|
||||||
const cryptoCodes = _.filter(
|
const cryptoCodes = _.filter(
|
||||||
|
|
|
||||||
|
|
@ -108,13 +108,8 @@ const buildTransactionMessage = (tx, rec, highValueTx, machineName, customer) =>
|
||||||
status = !isCashOut
|
status = !isCashOut
|
||||||
? 'Successful'
|
? 'Successful'
|
||||||
: !rec.isRedemption
|
: !rec.isRedemption
|
||||||
<<<<<<< HEAD
|
|
||||||
? 'Successful & awaiting redemption'
|
? 'Successful & awaiting redemption'
|
||||||
: 'Successful & dispensed'
|
: 'Successful & dispensed'
|
||||||
=======
|
|
||||||
? 'Successful & awaiting redemption'
|
|
||||||
: 'Successful & dispensed'
|
|
||||||
>>>>>>> 1706b2c... Feat: save highVolumeTxs on DB and plugins code refactor
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const body = `
|
const body = `
|
||||||
|
|
@ -141,7 +136,6 @@ const buildTransactionMessage = (tx, rec, highValueTx, machineName, customer) =>
|
||||||
}, highValueTx]
|
}, highValueTx]
|
||||||
}
|
}
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
function formatCurrency (num, code) {
|
function formatCurrency (num, code) {
|
||||||
return numeral(num).format('0,0.00') + ' ' + code
|
return numeral(num).format('0,0.00') + ' ' + code
|
||||||
}
|
}
|
||||||
|
|
@ -186,8 +180,6 @@ function getAlertTypes (alertRec, config) {
|
||||||
return alerts
|
return alerts
|
||||||
}
|
}
|
||||||
|
|
||||||
=======
|
|
||||||
>>>>>>> 1706b2c... Feat: save highVolumeTxs on DB and plugins code refactor
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
codeDisplay,
|
codeDisplay,
|
||||||
parseEventNote,
|
parseEventNote,
|
||||||
|
|
@ -200,13 +192,9 @@ module.exports = {
|
||||||
shouldNotAlert,
|
shouldNotAlert,
|
||||||
buildAlertFingerprint,
|
buildAlertFingerprint,
|
||||||
sendNoAlerts,
|
sendNoAlerts,
|
||||||
<<<<<<< HEAD
|
|
||||||
buildTransactionMessage,
|
buildTransactionMessage,
|
||||||
formatCurrency,
|
formatCurrency,
|
||||||
formatAge,
|
formatAge,
|
||||||
buildDetail,
|
buildDetail,
|
||||||
deviceAlerts
|
deviceAlerts,
|
||||||
=======
|
|
||||||
buildTransactionMessage
|
|
||||||
>>>>>>> 1706b2c... Feat: save highVolumeTxs on DB and plugins code refactor
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
const _ = require('lodash/fp')
|
const _ = require('lodash/fp')
|
||||||
|
|
||||||
const plugins = require('./plugins')
|
const plugins = require('./plugins')
|
||||||
const notifier = require('./notifier')
|
const notifier = require('./notifier/index')
|
||||||
const T = require('./time')
|
const T = require('./time')
|
||||||
const logger = require('./logger')
|
const logger = require('./logger')
|
||||||
const cashOutTx = require('./cash-out/cash-out-tx')
|
const cashOutTx = require('./cash-out/cash-out-tx')
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ import { transformNumber } from 'src/utils/number'
|
||||||
|
|
||||||
import NotificationsCtx from '../NotificationsContext'
|
import NotificationsCtx from '../NotificationsContext'
|
||||||
|
|
||||||
const HIGH_BALANCE_KEY = 'highBalance'
|
const HIGH_BALANCE_KEY = 'cryptoHighBalance'
|
||||||
const LOW_BALANCE_KEY = 'lowBalance'
|
const LOW_BALANCE_KEY = 'cryptoLowBalance'
|
||||||
const CRYPTOCURRENCY_KEY = 'cryptoCurrency'
|
const CRYPTOCURRENCY_KEY = 'cryptoCurrency'
|
||||||
const NAME = 'cryptoBalanceOverrides'
|
const NAME = 'cryptoBalanceOverrides'
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue