UNPKG

node-red-contrib-smartnora

Version:

Google Smart Home integration via Smart Nora https://smart-nora.eu/

122 lines (121 loc) 6.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const nora_firebase_common_1 = require("@andrei-tatar/nora-firebase-common"); const rxjs_1 = require("rxjs"); const operators_1 = require("rxjs/operators"); const __1 = require(".."); const connection_1 = require("../nora/connection"); const device_context_1 = require("../nora/device-context"); const safe_update_1 = require("../nora/safe-update"); const sync_1 = require("../nora/sync"); const util_1 = require("./util"); const JSON_ACTION_PREFIX = 'json:'; const LINK_ACTION_PREFIX = 'https://'; module.exports = function (RED) { RED.nodes.registerType('noraf-notify', function (config) { var _a, _b, _c; RED.nodes.createNode(this, config); const noraConfig = RED.nodes.getNode(config.nora); if (!(noraConfig === null || noraConfig === void 0 ? void 0 : noraConfig.valid)) { return; } const identifier = `${(0, util_1.getId)(config)}|${noraConfig.group}`; const configActions = config.actions; const actions = (_a = configActions === null || configActions === void 0 ? void 0 : configActions.map(({ p: title, v: value, vt: type }, index) => ({ title, action: type === 'link' ? value : `${index}`, }))) === null || _a === void 0 ? void 0 : _a.splice(0, 3); const defaultAction = (_c = actions === null || actions === void 0 ? void 0 : actions[(_b = configActions === null || configActions === void 0 ? void 0 : configActions.findIndex(c => !!c.d)) !== null && _b !== void 0 ? _b : -1]) === null || _c === void 0 ? void 0 : _c.action; const close$ = (0, util_1.getClose)(this); const notificationSent$ = new rxjs_1.Subject(); const ctx = new device_context_1.DeviceContext(this); ctx.startUpdating(close$); const connection$ = connection_1.FirebaseConnection .withLogger(RED.log) .fromConfig(noraConfig, ctx) .pipe((0, __1.singleton)(), (0, operators_1.takeUntil)(close$)); connection$.pipe((0, operators_1.switchMap)(c => c.watchForActions(identifier)), (0, operators_1.takeUntil)(close$)).subscribe(action => { if (action.startsWith(JSON_ACTION_PREFIX)) { const actionJson = action.substring(JSON_ACTION_PREFIX.length); this.send({ payload: JSON.parse(actionJson), topic: config.topic, }); } else { const actionIndex = parseInt(action, 10); if ((configActions === null || configActions === void 0 ? void 0 : configActions.length) && actionIndex >= 0 && actionIndex < configActions.length) { const { v: value, vt: valuetype } = configActions[actionIndex]; const payload = (0, util_1.getValue)(RED, this, value, valuetype); this.send({ payload, topic: config.topic, }); } } }); notificationSent$.pipe((0, operators_1.switchMap)(_ => { ctx.status$.next('sent'); ctx.local$.next(true); return (0, rxjs_1.concat)((0, rxjs_1.timer)(1000), (0, rxjs_1.defer)(() => { ctx.status$.next(null); ctx.local$.next(false); return rxjs_1.EMPTY; })); }), (0, operators_1.takeUntil)(close$)).subscribe(); (0, util_1.handleNodeInput)({ node: this, handler: async (msg) => { var _a, _b, _c, _d, _e, _f; const notification = { title: config.title, body: config.body, icon: config.icon, tag: config.tag || undefined, actions: [], data: { close: (_b = (config.closeNotification || ((_a = msg.payload) === null || _a === void 0 ? void 0 : _a.close))) !== null && _b !== void 0 ? _b : undefined, }, }; (_c = msg === null || msg === void 0 ? void 0 : msg.payload) === null || _c === void 0 ? true : delete _c.close; if (typeof msg.payload === 'object' && Array.isArray(msg.payload.actions) && msg.payload.actions.length) { msg.payload.actions = msg.payload.actions.map((v) => (Object.assign(Object.assign({}, v), { action: typeof v.action === 'string' && v.action.startsWith(LINK_ACTION_PREFIX) ? v.action : JSON_ACTION_PREFIX + JSON.stringify(v.action) }))); msg.payload.data = Object.assign(Object.assign({}, msg.payload.data), { defaultAction: msg.payload.actions[0].action }); } (0, safe_update_1.getSafeUpdate)({ update: (_d = msg.payload) !== null && _d !== void 0 ? _d : {}, safeUpdateObject: notification, currentState: notification, isValid: () => (0, nora_firebase_common_1.validateIndividual)('notification', notification).valid, warn: (propName) => this.warn(`ignoring property ${propName}`), }); if ((actions === null || actions === void 0 ? void 0 : actions.length) && !((_e = notification.actions) === null || _e === void 0 ? void 0 : _e.length)) { notification.actions = actions; notification.data = Object.assign(Object.assign({}, notification.data), { defaultAction }); } if ((_f = notification.actions) === null || _f === void 0 ? void 0 : _f.length) { notification.data = Object.assign(Object.assign({}, notification.data), { sender: identifier }); } else { delete notification.actions; } const connection = await (0, rxjs_1.firstValueFrom)(connection$); try { ctx.error$.next(null); await connection.sendNotification(notification); notificationSent$.next(null); } catch (err) { if (err instanceof sync_1.RateLimitingError) { ctx.error$.next('Too many notifications'); } else { throw err; } } }, }); }); };