lots of notifier improvements
This commit is contained in:
parent
8a87c7579d
commit
8a4b447db3
7 changed files with 172 additions and 26 deletions
30
dev/notify.js
Normal file
30
dev/notify.js
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
require('es6-promise').polyfill()
|
||||
|
||||
var notifier = require('../lib/notifier')
|
||||
var db = require('../lib/postgresql_interface')
|
||||
|
||||
function getBalances () {
|
||||
return [
|
||||
{fiatBalance: 23.2345, fiatCode: 'USD', cryptoCode: 'BTC'},
|
||||
{fiatBalance: 22, fiatCode: 'USD', cryptoCode: 'ETH'}
|
||||
]
|
||||
}
|
||||
|
||||
db.init('psql://lamassu:lamassu@localhost/lamassu')
|
||||
notifier.init(db, getBalances)
|
||||
console.log('DEBUG0')
|
||||
notifier.checkStatus()
|
||||
.then(function (alertRec) {
|
||||
console.log('DEBUG1')
|
||||
console.log('%j', alertRec)
|
||||
var subject = notifier.alertSubject(alertRec)
|
||||
console.log(subject)
|
||||
var body = notifier.printEmailAlerts(alertRec)
|
||||
console.log(body)
|
||||
console.log(notifier.alertFingerprint(alertRec))
|
||||
process.exit(0)
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.log(err.stack)
|
||||
process.exit(1)
|
||||
})
|
||||
|
|
@ -7,12 +7,10 @@ var rand = Math.floor(Math.random() * 1e6)
|
|||
|
||||
var rec = {
|
||||
email: {
|
||||
toEmail: 'joshmh@gmail.com',
|
||||
subject: 'Test email ' + rand,
|
||||
body: 'This is a test email from lamassu-server'
|
||||
},
|
||||
sms: {
|
||||
toNumber: process.argv[2],
|
||||
body: '[Lamassu] This is a test sms ' + rand
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
'use strict'
|
||||
|
||||
require('es6-promise').polyfill()
|
||||
|
||||
var http = require('http')
|
||||
var https = require('https')
|
||||
var express = require('express')
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ function connect () {
|
|||
}
|
||||
return pgp(psqlUrl)
|
||||
}
|
||||
exports.connect = connect
|
||||
|
||||
function loadConfig () {
|
||||
var db = connect()
|
||||
|
|
@ -19,5 +20,4 @@ function loadConfig () {
|
|||
return data.data
|
||||
})
|
||||
}
|
||||
|
||||
exports.loadConfig = loadConfig
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
var crypto = require('crypto')
|
||||
var R = require('ramda')
|
||||
var prettyMs = require('pretty-ms')
|
||||
var numeral = require('numeral')
|
||||
var db = null
|
||||
var getBalances = null
|
||||
|
||||
|
|
@ -21,7 +24,7 @@ function sameState (a, b) {
|
|||
function checkBalance (rec) {
|
||||
var LOW_BALANCE_THRESHOLD = 10
|
||||
return rec.fiatBalance < LOW_BALANCE_THRESHOLD
|
||||
? {code: 'lowBalance', cryptoCode: rec.cryptoCode, fiatBalance: rec.fiatBalance}
|
||||
? {code: 'lowBalance', cryptoCode: rec.cryptoCode, fiatBalance: rec.fiatBalance, fiatCode: rec.fiatCode}
|
||||
: null
|
||||
}
|
||||
|
||||
|
|
@ -110,5 +113,65 @@ function checkStatus () {
|
|||
|
||||
return alerts
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.log(err.stack)
|
||||
})
|
||||
}
|
||||
exports.checkStatus = checkStatus
|
||||
|
||||
function formatCurrency (num, code) {
|
||||
return numeral(num).format('0,0.00') + ' ' + code
|
||||
}
|
||||
|
||||
function emailAlert (alert) {
|
||||
switch (alert.code) {
|
||||
case 'ping':
|
||||
var pingAge = prettyMs(alert.age, {compact: true, verbose: true})
|
||||
return 'Connection to machine down for ' + pingAge
|
||||
case 'stale':
|
||||
var stuckAge = prettyMs(alert.age, {compact: true, verbose: true})
|
||||
return 'Machine is stuck on ' + alert.state + 'screen for ' + stuckAge
|
||||
case 'lowBalance':
|
||||
var balance = formatCurrency(alert.fiatBalance, alert.fiatCode)
|
||||
return 'Low balance of ' + balance + ' in ' + alert.cryptoCode + ' wallet'
|
||||
}
|
||||
}
|
||||
|
||||
function emailAlerts (alerts) {
|
||||
return alerts.map(emailAlert).join('\n') + '\n'
|
||||
}
|
||||
|
||||
function printEmailAlerts (alertRec) {
|
||||
var body = 'Errors were reported by your Lamassu Machines.\n'
|
||||
|
||||
if (alertRec.general.length !== 0) {
|
||||
body = body + '\nGeneral errors:\n'
|
||||
body = body + emailAlerts(alertRec.general)
|
||||
}
|
||||
|
||||
R.keys(alertRec.devices).forEach(function (device) {
|
||||
body = body + '\nErrors for ' + device + ':\n'
|
||||
body = body + emailAlerts(alertRec.devices[device])
|
||||
})
|
||||
|
||||
return body
|
||||
}
|
||||
exports.printEmailAlerts = printEmailAlerts
|
||||
|
||||
function alertSubject (alertRec) {
|
||||
var alerts = alertRec.general
|
||||
R.keys(alertRec.devices).forEach(function (device) {
|
||||
alerts = R.concat(alerts, alertRec.devices[device])
|
||||
})
|
||||
if (alerts.length === 0) return null
|
||||
var alertTypes = R.uniq(R.pluck('code', alerts)).sort()
|
||||
return '[Lamassu] Errors reported: ' + alertTypes.join(', ')
|
||||
}
|
||||
exports.alertSubject = alertSubject
|
||||
|
||||
function alertFingerprint (alertRec) {
|
||||
var subject = alertSubject(alertRec)
|
||||
if (!subject) return null
|
||||
return crypto.createHash('sha256').update(subject).digest('hex')
|
||||
}
|
||||
exports.alertFingerprint = alertFingerprint
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
var _ = require('lodash')
|
||||
var async = require('async')
|
||||
var R = require('ramda')
|
||||
|
||||
var BigNumber = require('bignumber.js')
|
||||
|
||||
|
|
@ -15,6 +14,7 @@ var uuid = require('node-uuid')
|
|||
var tradeIntervals = {}
|
||||
|
||||
var CHECK_NOTIFICATION_INTERVAL = 60 * 1000
|
||||
var ALERT_SEND_INTERVAL = 60 * 60 * 1000
|
||||
var POLLING_RATE = 60 * 1000 // poll each minute
|
||||
var REAP_RATE = 2 * 1000
|
||||
var PENDING_TIMEOUT = 70 * 1000
|
||||
|
|
@ -51,6 +51,9 @@ var coins = {
|
|||
ETH: {unitScale: 18}
|
||||
}
|
||||
|
||||
var alertFingerprint = null
|
||||
var lastAlertTime = null
|
||||
|
||||
// that's basically a constructor
|
||||
exports.init = function init (databaseHandle) {
|
||||
if (!databaseHandle) {
|
||||
|
|
@ -428,7 +431,9 @@ exports.dispenseAck = function dispenseAck (session, rec) {
|
|||
}
|
||||
|
||||
exports.fiatBalance = function fiatBalance (cryptoCode) {
|
||||
var rawRate = exports.getDeviceRate(cryptoCode).rates.ask
|
||||
var deviceRate = exports.getDeviceRate(cryptoCode)
|
||||
if (!deviceRate) return null
|
||||
var rawRate = deviceRate.rates.ask
|
||||
var commission = cachedConfig.exchanges.settings.commission
|
||||
var lastBalance = lastBalances[cryptoCode]
|
||||
|
||||
|
|
@ -634,49 +639,95 @@ exports.getcryptoCodes = function getcryptoCodes () {
|
|||
return cryptoCodes
|
||||
}
|
||||
|
||||
function sendMessage (rec, cb) {
|
||||
console.log('DEBUG5')
|
||||
cb = cb || function () {}
|
||||
function sendMessage (rec) {
|
||||
console.log('DEBUG50')
|
||||
console.log('%j', rec)
|
||||
console.log(cachedConfig.exchanges.plugins.current.notify)
|
||||
var pluginTypes = JSON.parse(cachedConfig.exchanges.plugins.current.notify)
|
||||
console.log('DEBUG7')
|
||||
console.log(pluginTypes)
|
||||
var pluginPromises = pluginTypes.map(function (pluginType) {
|
||||
if (pluginType === 'email') return emailPlugin.sendMessage(rec, cb)
|
||||
if (pluginType === 'sms') return smsPlugin.sendMessage(rec, cb)
|
||||
if (pluginType === 'email') return emailPlugin.sendMessage(rec)
|
||||
if (pluginType === 'sms') return smsPlugin.sendMessage(rec)
|
||||
throw new Error('No such plugin type: ' + pluginType)
|
||||
})
|
||||
return Promise.all(pluginPromises)
|
||||
}
|
||||
exports.sendMessage = sendMessage
|
||||
|
||||
function sendNoAlerts () {
|
||||
var subject = '[Lamassu] All clear'
|
||||
var rec = {
|
||||
sms: {
|
||||
body: subject
|
||||
},
|
||||
email: {
|
||||
subject: subject,
|
||||
body: 'No errors are reported for your machines.'
|
||||
}
|
||||
}
|
||||
return sendMessage(rec)
|
||||
}
|
||||
|
||||
function checkNotification () {
|
||||
notifier.checkStatus()
|
||||
.then(function (alerts) {
|
||||
if (alerts.length === 0) return
|
||||
console.log('DEBUG39 ******************************')
|
||||
return notifier.checkStatus()
|
||||
.then(function (alertRec) {
|
||||
console.log('DEBUG41 ******************************')
|
||||
var fingerprint = notifier.alertFingerprint(alertRec)
|
||||
if (!fingerprint) {
|
||||
console.log('DEBUG40 ******************************')
|
||||
var inAlert = !!alertFingerprint
|
||||
alertFingerprint = null
|
||||
lastAlertTime = null
|
||||
if (inAlert) return sendNoAlerts()
|
||||
}
|
||||
|
||||
// var devices = R.keys(alerts.devices)
|
||||
var alertRecs = alerts.general
|
||||
R.keys(alerts.devices).forEach(function (device) {
|
||||
alertRecs = R.append(alerts.devices[device], alertRecs)
|
||||
})
|
||||
var alertTypes = alertRecs.pluck('code', alerts)
|
||||
var body = ''
|
||||
console.log('DEBUG42 ******************************')
|
||||
|
||||
var alertChanged = fingerprint === alertFingerprint &&
|
||||
lastAlertTime - Date.now() < ALERT_SEND_INTERVAL
|
||||
if (alertChanged) return
|
||||
|
||||
console.log('DEBUG43 ******************************')
|
||||
|
||||
var subject = notifier.alertSubject(alertRec)
|
||||
var rec = {
|
||||
sms: {
|
||||
body: '[Lamassu] Errors reported: ' + alertTypes.join(', ')
|
||||
body: subject
|
||||
},
|
||||
email: {
|
||||
subject: '[Lamassu] Errors reported: ' + alertTypes.join(', '),
|
||||
body: body
|
||||
subject: subject,
|
||||
body: notifier.printEmailAlerts(alertRec)
|
||||
}
|
||||
}
|
||||
sendMessage(rec)
|
||||
alertFingerprint = fingerprint
|
||||
lastAlertTime = Date.now()
|
||||
return sendMessage(rec)
|
||||
})
|
||||
.then(function () {
|
||||
logger.debug('Successfully sent alerts')
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error(err)
|
||||
})
|
||||
}
|
||||
|
||||
function checkBalances () {
|
||||
var cryptoCodes = exports.getcryptoCodes()
|
||||
|
||||
var balances = []
|
||||
cryptoCodes.forEach(function (cryptoCode) {
|
||||
var balance = exports.fiatBalance(cryptoCode)
|
||||
if (!balance) return
|
||||
var rec = {fiatBalance: balance, cryptoCode: cryptoCode, fiatCode: deviceCurrency}
|
||||
balances.push(rec)
|
||||
})
|
||||
|
||||
return balances
|
||||
}
|
||||
|
||||
exports.startCheckingNotification = function startCheckingNotification () {
|
||||
notifier.init(db, checkBalances)
|
||||
checkNotification()
|
||||
setInterval(checkNotification, CHECK_NOTIFICATION_INTERVAL)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,8 +36,10 @@
|
|||
"lodash": "^2.4.1",
|
||||
"minimist": "0.0.8",
|
||||
"node-uuid": "^1.4.2",
|
||||
"numeral": "^1.5.3",
|
||||
"pg": "^4.5.1",
|
||||
"pg-promise": "^3.4.3",
|
||||
"pretty-ms": "^2.1.0",
|
||||
"prompt": "^1.0.0",
|
||||
"promptly": "^1.1.0",
|
||||
"ramda": "^0.19.1",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue