UNPKG

node-red-contrib-motechat

Version:

ultranet topic and payload communication

477 lines (419 loc) 12.8 kB
var when = require('when'); var nodeFn = require('when/node/function'); var keys = require('when/keys'); var fs = require('fs-extra'); var fspath = require("path"); var mkdirp = fs.mkdirs; var crypto = require('crypto'); var mc = require('./lib/mcClient.js'); var caller = { SetConfig: mc.set, GetConfig: mc.get, call: mc.call, reged: mc.reged } var initialFlowLoadComplete = false; var settings; var runtime; var flowsFile; var projectFile; var flowsFullPath; var flowsFileBackup; var credentialsFile; var credentialsFileBackup; var oldCredentialsFile; var sessionsFile; var libDir; var libFlowsDir; var globalSettingsFile; var qName; var qCode; var qType; var oid; var uid; var eiName; var promiseDir = nodeFn.lift(mkdirp); function escapeRegExp(str) { return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); } function log(){ var str = ""; if(oid) str+= " OID = " + oid; if(qName) str+= " QNAME = " + qName; if(qCode) str+= " QCODE = " + qCode; if(qType) str+= " QTYPE = " + qType; if(uid) str+= " UID = " + uid; return str; } function log2(){ var str = ""; if(oid) str+= " OID = " + oid; if(qName) str+= " QNAME = " + qName; if(qCode) str+= " QCODE = " + qCode; if(eiName) str+= " EINAME = " + eiName; return str; } function loadObjMMS(){ return when.promise(async function(resolve, reject){ let payload = { type: "flow" }; if(qType) payload.type = qType; if(oid && oid != null) payload._id = oid; else if(qName){ payload.qname = qName; if(qCode) payload.qcode = qCode; if(uid) payload.uid = uid; } if(!qCode && !qName && !oid) reject('QCODE or QNAME or OID is required.'); while(1){ if(caller.reged() != ""){ break; } await new Promise(resolve => setTimeout(resolve, 500)); } caller.call('', process.env.OBJMMS_DDN || '>svc/objc', 'obj://get', {}, payload).then(reply => { if (reply) { let result; if (typeof reply == 'object') result = reply; else result = reply[0]; if (Array.isArray(result)) result = result[0]; //console.log("ObjMMS Call Result = %s", JSON.stringify(result)); if(!result.Reply || result.Reply == ''){ reject(result.IN.State.ErrMsg); }else{ result = result.Reply; } if (result.ErrMsg != 'OK') { reject(result.ErrMsg); } else if (result.ErrMsg == 'OK') { result = result.Data; if(result && result.data){ if(qType == 'project') resolve(result.data.flows); else resolve(result.data.flow); } else{ reject(`Flow not found: QNAME = ${qName} QCODE = ${qCode}`); } } } else { reject("Call objmms not response") } }).catch(err => { console.log(err); reject(err); }); }) } function objLoad(type, path) { if (!initialFlowLoadComplete) { initialFlowLoadComplete = true; } return when.promise(async function(resolve, reject) { if(type == 'flows'){ console.log("Flow params: " + log()); loadObjMMS().then((reply)=>{ if(reply && reply.length > 0){ console.log("Flow loaded from objstore: OK"); objSave('flows', '/', reply).then((result)=>{ console.log("Flow stored at xstorage: OK"); resolve(reply); }).catch((err)=>{ console.log("Flow can't store at xstorage: " + log2()); console.log(err); loadFromXstore(type, resolve, reject); //reject(err.message); }); }else{ console.log("Flow not found in objstore"); loadFromXstore(type, resolve, reject); } }).catch((err) => { console.log("Flow can't load from objstore"); console.log(err); loadFromXstore(type, resolve, reject); }); }else{ let idname = `${eiName}_${type}`; if(path) idname += `_${path}`; let payload = { catalog: type == 'flows' ? 'flow' : type, idname: idname }; caller.GetConfig(payload).then((reply) => { if (reply) { let result; if (typeof reply == 'object') result = reply; else result = reply[0]; if (Array.isArray(result)) result = result[0]; if (result.ErrMsg != 'OK') { reject(result.ErrMsg); } else if (result.ErrMsg == 'OK') { if(result.result) resolve(result.result); else if(type == 'flows'){ resolve([]); } else{ resolve([]); } } } else { reject("Call xstorage not response") } }); } }); } function loadFromXstore(type, resolve, reject){ let payload = { catalog: 'flow', idname: eiName }; console.log("Flow xstorage params: " + log2()); caller.GetConfig(payload).then((reply) => { if (reply) { let result; if (typeof reply == 'object') result = reply; else result = reply[0]; if (Array.isArray(result)) result = result[0]; if (result.ErrMsg != 'OK') { reject(result.ErrMsg); } else if (result.ErrMsg == 'OK') { console.log("Flow loaded from xstorage"); if(result.result) resolve(result.result); else if(type == 'flows'){ resolve([]); } else{ resolve([]); } } } else { console.log("Flow can't load from xstorage"); reject("Call xstorage not response") } }); } function objSave(type, path, blob) { //need to check return when.promise(function(resolve, reject) { let idname = `${eiName}_${type}`; if(path) idname += `_${path}`; if(type == 'flows'){ idname = eiName; } let payload = { catalog: type == 'flows' ? 'flow' : type, idname: idname, data: blob }; caller.SetConfig(payload).then((reply) => { if (reply) { let result; if (typeof reply == 'object') result = reply; else result = reply[0]; if (Array.isArray(result)) result = result[0]; if (result.ErrMsg != 'OK') { reject(result.ErrMsg); } else if (result.ErrMsg == 'OK') { resolve('OK') } } else { reject('Call xstorage not response'); } }); }); } var storage = process.env.FBOT_MODE || ""; if(storage === "xstorage"){ var xStorage = { init: function(_settings, _runtime) { var promises = []; settings = _settings; runtime = _runtime; if (!settings.userDir) { try { fs.statSync(fspath.join(process.env.NODE_RED_HOME,".config.json")); settings.userDir = process.env.NODE_RED_HOME; } catch(err) { settings.userDir = fspath.join(process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE || process.env.NODE_RED_HOME,".node-red"); if (!settings.readOnly) { promises.push(promiseDir(fspath.join(settings.userDir,"node_modules"))); } } } if (process.env.FLOW_FILE || settings.flowFile) { flowsFile = process.env.FBOT_FLOWFILE || settings.flowFile; // handle Unix and Windows "C:\" if ((flowsFile[0] == "/") || (flowsFile[1] == ":")) { // Absolute path flowsFullPath = flowsFile; } else if (flowsFile.substring(0,2) === "./") { // Relative to cwd flowsFullPath = fspath.join(process.cwd(),flowsFile); } else { try { fs.statSync(fspath.join(process.cwd(),flowsFile)); // Found in cwd flowsFullPath = fspath.join(process.cwd(),flowsFile); } catch(err) { // Use userDir flowsFullPath = fspath.join(settings.userDir,flowsFile); } } } else { flowsFile = 'flows_'+require('os').hostname()+'.json'; flowsFullPath = fspath.join(settings.userDir,flowsFile); } var ffExt = fspath.extname(flowsFullPath); var ffName = fspath.basename(flowsFullPath); var ffBase = fspath.basename(flowsFullPath,ffExt); var ffDir = fspath.dirname(flowsFullPath); credentialsFile = fspath.join(settings.userDir,ffBase+"_cred"+ffExt); credentialsFileBackup = fspath.join(settings.userDir,"."+ffBase+"_cred"+ffExt+".backup"); oldCredentialsFile = fspath.join(settings.userDir,"credentials.json"); //flowsFileBackup = fspath.join(ffDir,"."+ffName+".backup"); sessionsFile = fspath.join(settings.userDir,".sessions.json"); //projectFile = fspath.join(settings.userDir,"projects.json"); libDir = fspath.join(settings.userDir,"lib"); libFlowsDir = fspath.join(libDir,"flows"); globalSettingsFile = fspath.join(settings.userDir,".config.json"); if (!settings.readOnly) { promises.push(promiseDir(libFlowsDir)); } qName = process.env.FBOT_QNAME; qCode = process.env.FBOT_QCODE; qType = process.env.FBOT_QTYPE; oid = process.env.FBOT_OID || null; uid = process.env.FBOT_UID || null; eiName = process.env.MCHAT_EINAME; promises.push(mc.setup()); return when.all(promises); }, getFlows: function() { return objLoad('flows', '/'); }, saveFlows: function(flows) { return objSave('flows', '/', flows); }, getCredentials: function() { return objLoad('credentials', '/'); }, saveCredentials: function(credentials) { return objSave('credentials', '/', credentials); }, getSettings: function() { return objLoad('settings', '/'); }, saveSettings: function(settings) { return objSave('settings', '/', settings); }, getSessions: function() { return objLoad('sessions', '/'); }, saveSessions: function(sessions) { return objSave('sessions', '/', sessions); }, getLibraryEntry: function(type, path) { return when.promise(function(resolve, reject) { let idname = `${eiName}_library`; if(type) idname += `_${type}`; if(path) idname += `_${path}`; let payload = { catalog: type, idname: idname } caller.GetConfig(payload).then((reply) => { if (reply) { let result; if (typeof reply == 'object') result = reply; else result = reply[0]; if (Array.isArray(result)) result = result[0]; if (result.ErrMsg != 'OK') { reject(result.ErrMsg); } else if (result.ErrMsg == 'OK') { resolve(result.result || {}); } } else { reject("Call xstorage not response") } }); }); }, saveLibraryEntry: function(type, path, meta, body) { return when.promise(function(resolve, reject) { let idname = `${eiName}_library`; if(type) idname += `_${type}`; if(path) idname += `_${path}`; let payload = { catalog: type, idname: idname, data: {meta : meta, body: body} }; caller.SetConfig(payload).then((reply) => { if (reply) { let result; if (typeof reply == 'object') result = reply; else result = reply[0]; if (Array.isArray(result)) result = result[0]; if (result.ErrMsg != 'OK') { reject(result.ErrMsg); } else if (result.ErrMsg == 'OK') { resolve('OK') } } else { reject('Call xstorage not response'); } }); }); } }; module.exports = xStorage; }