uci-utils-notify/src/notify.js

104 lines
3.1 KiB
JavaScript

// import RxClass from '@uci-utils/rx-class'
import path from 'path'
import { path as root } from 'app-root-path'
import json from 'jsonfile'
import to from 'await-to-js'
const internal = Symbol('token for Notifier Instance')
let inst
class Notifier {
constructor(token,opts={}){
if(token !== internal) {
throw new Error('\'new Notifer\' not supported. Use the \'await Notifier.create()\' async static method')
}
// super(opts)
this._services = {}
this._disabled = []
this.services = opts.services || {}
} // end constructor
static async create(opts){
inst = new Notifier(internal,opts)
console.log('notifcation service registrations:',
await Promise.all(
Object.entries(inst.services).map(async service => {
return await inst.registerService.call(inst,service[0],service[1])
}
)
)
)
return inst
}
async registerService(name,opts) {
let mod; let file
let dir = `${root}/node_modules/${opts.module || name}`
let [err,pkg] = await to(json.readFile(dir+'/package.json'))
if (!err) {
file = (dir + '/' + (pkg.main ? pkg.main : 'index.js'))
// eslint-disable-next-line
let [err,res] = await to(import(file))
if (err) return `${name} failed - no file at ${file}`
mod = res
} else {
// try in service directory for baked in plugins
console.log(opts.module||name, ': no plugin found in node_modules, looking for internal module')
let file = (`${path.dirname(__dirname)}/services/${name}.js`)
// eslint-disable-next-line
let [err,res] = await to(import(file))
if (err) return `${name} failed - no file at ${file}`
mod = res
}
// delete opts.module
const Service = mod.Service || mod.default
if (!Service.prototype.constructor) {
console.log('no default or "Service" class was exported from plugin')
return `${name} failed`
}
else this._services[name] = new Service(opts)
return `${name} registered`
}
disableService(name) {
this._disabled.push(name)
}
enableService(name) {
this._disabled= this._disabled.filter(service=>service!==name)
}
async send (msg,service,opts={}) {
if (service!==null || service==='!email') {
if (this._services[service]) return await this._services[service].send(msg,opts)
}
let response = {}
let services = Object.entries(this._services)
if (service==='!email') services = services.filter(service => service[0]!=='email')
// console.log('services for message send', services.map(service=>service[0]))
await Promise.all(
services.map(async service => {
let res = this._disabled.includes(service[0]) ? 'disabled' : await service[1].send(msg,opts[service[0]])
if (res.error) response.error ? response.error[service[0]] = res.error : response = { error:{[service[0]]:res.error}}
response[service[0]]=res
}
)
)
return response
}
getServicesList() { return Object.keys(this._services) }
getService(name) {
if (name==null) return this._services
return this._services[name]
}
} // end Notifier class
export default Notifier
export { Notifier }