node-red-contrib-motechat
Version:
ultranet topic and payload communication
273 lines (256 loc) • 8.47 kB
JavaScript
const mchat = require('motechat')
const os = require('os')
const { name, version } = require('../package.json')
const { EventEmitter } = require('events')
const debug = require('debug')('nr-motechat')
//let config = require('./config.js')
let mcState = false
let mcEvent = new EventEmitter()
mcEvent.setMaxListeners(0)
let settings = {}
debug(`${name} version:${version}`)
let conf = {
"AppName": process.env.MCHAT_APPNAME || os.hostname(),
"AppKey": process.env.APP_KEY || "1u6WauSf",
"DCenter": process.env.MCHAT_DC || "dc",
"IOC": process.env.MCHAT_IOC || "ioc",
"MotebusGW": process.env.MCHAT_MBGWIP || "127.0.0.1",
"MotebusPort": process.env.MCHAT_PORT || "6262",
"WatchLevel": process.env.MCHAT_WATCHLEVEL || "1"
}
let eiInfo = {
"EiOwner": process.env.MCHAT_EIOWNER || "",
"EiName": process.env.MCHAT_EINAME || os.hostname(),
"EiType": process.env.MCHAT_EITYPE || ".flow",
"EiTag": process.env.MCHAT_EITAG || "",
"EiLoc": process.env.MCHAT_EILOC || ""
}
let reginfo = {
"SToken":process.env.STOKEN || "",
"EiToken":process.env.EITOKEN || "",
"WIP":"",
"LIP":"",
"EdgeInfo":eiInfo,
"Option":{"SaveDSIM":false}
}
let isReg = false;
let WIP;
let EiUDID;
let LIP;
let DDN;
let checkUDID = process.env.MCHAT_UDID || "0";
let checkMOTE = process.env.MCHAT_MOTE || "0";
let flowOnevent = false;
class MCClient {
static getMessage({ Topic = '', DDN = '', Data , t1 = 6, t2 = 12 } = {}) {
return {
SToken: reginfo.SToken,
Topic, DDN, Data,
SendTimeout: process.env.SENDTIMEOUT || t1,
WaitReply: process.env.WAITREPLY || t2
}
}
static getRPC({ Topic = '', DDN = '', Func, Data, t1 = 6, t2 = 12 } = {}) {
return {
SToken: reginfo.SToken,
Topic, DDN, Func, Data,
SendTimeout: process.env.SENDTIMEOUT || t1,
WaitReply: process.env.WAITREPLY || t2
}
}
static async setEi({ name, tag, location}){
function isDiffEi({ name, tag, location }) {
const { EiName, EiTag, EiLoc } = reginfo.EdgeInfo;
if (name !== EiName) return true
if (tag !== EiTag) return true
if (location !== EiLoc) return true
return false
}
if (!isDiffEi({ name, tag, location })) {
return new Promise(resolve => resolve({}))
}
reginfo.EdgeInfo = {"EiName":name,"EiType":reginfo.EdgeInfo.EiType,"EiTag":tag,"EiLoc":location}
return new Promise(resolve => {
mchat.Set(reginfo, result => resolve(result))
})
}
static async setup() {
debug("DC env: ", process.env.DC)
mcEvent.on('checkEvent', (status) => {
flowOnevent = status;
});
await mchat.Open(conf, async (openret) => { //open motechat
if(openret.Info.udid) EiUDID = openret.Info.udid; //*
WIP = openret.Info.wanIP; //*
LIP = openret.Info.localIP; //*
console.log('motechat open result=', openret)
if (checkUDID === '1' && checkMOTE === '1') reginfo.EdgeInfo.EiName = 'mm-' + EiUDID + '-' + eiInfo.EiName;
else if (checkUDID === '1') reginfo.EdgeInfo.EiName = EiUDID + '-' + eiInfo.EiName;
reginfo.WIP = WIP;
reginfo.LIP = LIP;
let regret = await mchat.Reg(reginfo);
DDN = regret.result.DDN;
reginfo.SToken = regret.result.SToken;
reginfo.EiToken = regret.result.EiToken;
console.log("motechat reg result= ", regret);
isReg = true;
let setret = await mchat.Set(reginfo);
mchat.OnEvent('message', (ch, inctl, data, cb) => {
if(flowOnevent) mcEvent.emit('message', { ch, inctl, data, mcBack: cb })
else cb({ ErrCode: -20001, ErrMsg: 'Flow not listen' })
}, '')
mchat.OnEvent('state', state => {
mcEvent.emit('state', { state })
}, '')
})
}
}
function isRegist(){
return isReg;
}
const checkNormal = (reply) => {
if (!Array.isArray(reply)) {
const { ErrCode } = reply
return ErrCode == 0
}
const [result] = reply
if (result.State) {
const { ErrCode } = result.State
return ErrCode == 0
}
if (result.IN.State) {
const { ErrCode } = result.IN.State
return ErrCode == 0
}
}
var storage = process.env.FBOT_MODE || "";
if(storage != "xstorage"){
MCClient.setup();
}
module.exports = {
async setup() {
await MCClient.setup();
},
/**
* @summary Send the message to the DDN, and return the promise of the reply
* @function send
* @public
*
* @param {string} topic the topic
* @param {string} DDN the DDN
* @param {*} payload the data that send to the DDN
*
* @returns {Promise<object>} return the send reply
*/
send(topic, DDN, timers = {}, payload) {
let { t1, t2 } = timers
return new Promise((resolve, reject) => {
const message = MCClient.getMessage({
Topic: topic, DDN, Data: payload,
t1, t2
})
mchat.Send(message, reply => {
//const isNormal = checkNormal(reply)
//if (!isNormal) reject(reply)
resolve(reply)
})
})
},
/**
* @summary Call the function of the DDN, and then return the reply
* @function call
* @public
*
* @param {stirng} topic the topic
* @param {string} DDN the DDN
* @param {string} func the function name
* @param {*} payload the data that send to the called topic
*
* @returns {Promise<object>} return the call reply
*/
call(topic, DDN, func, timers = {}, payload = {}) {
let { t1, t2 } = timers
return new Promise((resolve, reject) => {
let xrpc = MCClient.getRPC({
Topic: topic, DDN, Func: func, Data: payload,
t1, t2
})
mchat.Call(xrpc, reply => {
//const isNormal = checkNormal(reply)
//if (!isNormal) reject(reply)
resolve(reply)
})
})
},
/**
* @summary set the triggerID signal to the event emitter
* @function setEvent
* @public
*
* @param {string} event the event signal
* @param {function} callback the event callback fucntion
*/
setEvent(event, callback) {
if (event !== "message" && event !== "status") return
debug("setting event")
mcEvent.on(event, callback)
debug(mcEvent)
},
set(payload = {}) {
return new Promise((resolve, reject) => {
mchat.mbSetConfig(payload).then(reply => {
const isNormal = checkNormal(reply)
if (!isNormal) reject(reply)
resolve(reply)
}).catch(err => {
reject(err)
})
})
},
/**
* @summary Call the function mbGetConfig
* @function get
* @public
*
* @param {*} payload the data that send to the called topic
*
* @returns {Promise<object>} return the call reply
*/
get(payload = {}) {
return new Promise((resolve, reject) => {
mchat.mbGetConfig(payload).then(reply => {
const isNormal = checkNormal(reply)
if (!isNormal) reject(reply)
resolve(reply)
}).catch(err => {
reject(err)
})
})
},
/**
* @summary remove the event listener from the event emitter
* @function removeEvent
* @public
*
* @param {string} event the event signal that removed from the event emitter
* @param {function} callback the event callback that removed
*/
removeEvent(event, callback) {
mcEvent.removeListener(event, callback)
},
sendEvent(event, payload){
mcEvent.emit(event, payload)
},
getDDN() {
return DDN;
},
setEi: MCClient.setEi,
debug: debug,
isRegist() {
return isRegist();
},
reged(){
return reginfo.SToken
},
}